From b2d613f53625f0dba101fa27a8a3cbdd5183740f Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 3 Jul 2014 08:41:47 +0200 Subject: [PATCH 001/819] CLOUDSTACK-6242: catching all to allow continuation on configuration error (CLOUDSTACK-7039 through CLOUDSTACK-7042) --- server/src/com/cloud/server/ConfigurationServerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 1469048026..b66e52dcb0 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -512,9 +512,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) { PreparedStatement stmt = txn.prepareAutoCloseStatement(checkSql); stmt.executeQuery(); tableName = "network_group"; - } catch (SQLException ex) { + } catch (Exception ex) { // if network_groups table exists, create the default security group there - s_logger.debug("Caught SQLException: no network_group ", ex); + s_logger.debug("Caught (SQL?)Exception: no network_group " + ex.getLocalizedMessage()); } insertSql = "SELECT * FROM " + tableName + " where account_id=2 and name='default'"; From ce5061e107f743e52b23445fd97fcf60d8160ec6 Mon Sep 17 00:00:00 2001 From: Damodar Reddy Date: Thu, 3 Jul 2014 15:48:34 +0530 Subject: [PATCH 002/819] CLOUDSTACK-6834 : 3. Some description changes words like CloudStack etc 4. Change Default installation location if possible include version number 5. Mysql Connector Installer along with other dependecies 6. Add run Service Checkbox 7. Add ReadMe checkbox Signed-off-by: Koushik Das --- client/pom.xml | 26 +++++++++- pom.xml | 1 + scripts/installer/windows/ExitDialog.wxs | 48 +++++++++++++++++++ .../installer/windows/WixInstallerDialog.wxs | 2 +- scripts/installer/windows/acs.wxs | 39 +++++++++++++-- scripts/installer/windows/dependencies.wxs | 1 + scripts/installer/windows/en-us.wxl | 10 ++-- .../installer/windows/optionstheme_en-us.wxl | 4 +- scripts/installer/windows/readme.txt | 1 + 9 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 scripts/installer/windows/ExitDialog.wxs create mode 100644 scripts/installer/windows/readme.txt diff --git a/client/pom.xml b/client/pom.xml index 29fef4f335..0af1e01fee 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -681,6 +681,7 @@ + @@ -719,6 +720,7 @@ + @@ -746,6 +748,26 @@ + + org.codehaus.mojo + build-helper-maven-plugin + 1.9 + + + regex-property + + regex-property + + + final.version + ${project.version} + -SNAPSHOT + + false + + + + org.apache.cloudstack Wix-cloudstack-maven-plugin @@ -827,10 +849,11 @@ WixUIExtension WixUtilExtension - -dSourceClient=SourceDir\client -dSetupPathDir=SourceDir\setup -dUtilitiesPathDir=SourceDir\scripts -dPythonSitePackagesDir=SourceDir\python-site-packages + -dVersion=${final.version} -dSourceClient=SourceDir\client -dSetupPathDir=SourceDir\setup -dUtilitiesPathDir=SourceDir\scripts -dPythonSitePackagesDir=SourceDir\python-site-packages ../scripts/installer/windows/acs.wxs ../scripts/installer/windows/WixInstallerDialog.wxs + ../scripts/installer/windows/ExitDialog.wxs ../scripts/installer/windows/Setup_Databases.wxs target/client.wxs target/setupdb.wxs @@ -844,6 +867,7 @@ target/setupdb.wixobj target/utilities.wixobj target/WixInstallerDialog.wixobj + target/ExitDialog.wixobj target/Setup_Databases.wixobj target/python-site-packages.wixobj diff --git a/pom.xml b/pom.xml index 0b3b56e7aa..570d2bc585 100644 --- a/pom.xml +++ b/pom.xml @@ -819,6 +819,7 @@ tools/ngui/static/js/lib/* **/.checkstyle scripts/installer/windows/acs_license.rtf + scripts/installer/windows/readme.txt diff --git a/scripts/installer/windows/ExitDialog.wxs b/scripts/installer/windows/ExitDialog.wxs new file mode 100644 index 0000000000..53fa8c5829 --- /dev/null +++ b/scripts/installer/windows/ExitDialog.wxs @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/installer/windows/WixInstallerDialog.wxs b/scripts/installer/windows/WixInstallerDialog.wxs index 0282d8ace7..a2103a9de1 100644 --- a/scripts/installer/windows/WixInstallerDialog.wxs +++ b/scripts/installer/windows/WixInstallerDialog.wxs @@ -28,7 +28,7 @@ - 1 + 1 1 diff --git a/scripts/installer/windows/acs.wxs b/scripts/installer/windows/acs.wxs index bf09afcd6e..db2c8dbb42 100644 --- a/scripts/installer/windows/acs.wxs +++ b/scripts/installer/windows/acs.wxs @@ -11,7 +11,7 @@ + Codepage='1252' Version='!(wix.Version)' Manufacturer='!(loc.ProductManufacturer)'> - - + + @@ -139,6 +139,9 @@ + + + + @@ -278,7 +284,8 @@ NOT Installed NOT Installed - NOT Installed + NOT Installed + NOT Installed (NOT Installed) AND (CREATE_DATABASE = "1") @@ -302,9 +309,31 @@ + - + + + + + + + + + + + + + + WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed + WIXUI_EXITDIALOGOPTIONALRAEDMECHECKBOX = 1 and NOT Installed + \ No newline at end of file diff --git a/scripts/installer/windows/dependencies.wxs b/scripts/installer/windows/dependencies.wxs index 987c561daf..96562db877 100644 --- a/scripts/installer/windows/dependencies.wxs +++ b/scripts/installer/windows/dependencies.wxs @@ -17,6 +17,7 @@ + diff --git a/scripts/installer/windows/en-us.wxl b/scripts/installer/windows/en-us.wxl index 2f34575a05..8b3999cb6d 100644 --- a/scripts/installer/windows/en-us.wxl +++ b/scripts/installer/windows/en-us.wxl @@ -9,9 +9,9 @@ OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - Apache Cloud Stack + Apache CloudStack Apache - Apache Cloud Stack Installer + Apache CloudStack Installer ACS is a registered trademark Apache Apache tomcat6 is not installed please do install tomcat6 and then try @@ -19,7 +19,7 @@ Python 2.7 is not installed Please do install python and then try 7Z is not installed please do install 7z and then try Management Server - The Main Executable of Cloud Stack. + The Main Executable of CloudStack. The complete package. Provide Database Information Please provide the database information that host the cloud schemas @@ -28,7 +28,7 @@ Password Root Password Port - Create Cloud Stack Database + Create CloudStack Database Generating SSL Keys which is needed to talk to Management Server. Creating Database and needed Schemas for management server. Updating db.properties with the given database configuration. @@ -38,6 +38,8 @@ Deleting un-necessary files from installation directory. Updating Tomcat Catalina Base with Management Server Home. Updating Tomcat Classpath with necessary paths. + Launch CloudStack Server + Open Readme Version 4.0.0.0 \ No newline at end of file diff --git a/scripts/installer/windows/optionstheme_en-us.wxl b/scripts/installer/windows/optionstheme_en-us.wxl index c822929d31..876372fe2a 100644 --- a/scripts/installer/windows/optionstheme_en-us.wxl +++ b/scripts/installer/windows/optionstheme_en-us.wxl @@ -10,8 +10,8 @@ governing permissions and limitations under the License. --> - Apache Cloud Stack Setup - Apache Cloud Stack + Apache CloudStack Setup + Apache CloudStack Install MySql Database Server Version 4.0.0.0 diff --git a/scripts/installer/windows/readme.txt b/scripts/installer/windows/readme.txt new file mode 100644 index 0000000000..86fb3e6d8a --- /dev/null +++ b/scripts/installer/windows/readme.txt @@ -0,0 +1 @@ +Need to Add the Readme Content in this file.... \ No newline at end of file From 8c61566d612700f79b26e4e074502274cd676dcb Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Thu, 3 Jul 2014 17:47:07 +0530 Subject: [PATCH 003/819] CLOUDSTACK-7062: Tagging test case with bug Id --- test/integration/smoke/test_primary_storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 0312ad6c8a..2394239765 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -144,7 +144,7 @@ def test_01_primary_storage_nfs(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false", BugId="7062") def test_01_primary_storage_iscsi(self): """Test primary storage pools - XEN, KVM, VMWare """ From 4607c26949b6b925fdc0eb2a5253d536dd333439 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Fri, 4 Jul 2014 10:04:04 +0530 Subject: [PATCH 004/819] Revert "CLOUDSTACK-6834 : 3. Some description changes words like CloudStack etc 4. Change Default installation location if possible include version number 5. Mysql Connector Installer along with other dependecies 6. Add run Service Checkbox 7. Add ReadMe checkbox" This reverts commit ce5061e107f743e52b23445fd97fcf60d8160ec6. --- client/pom.xml | 26 +--------- pom.xml | 1 - scripts/installer/windows/ExitDialog.wxs | 48 ------------------- .../installer/windows/WixInstallerDialog.wxs | 2 +- scripts/installer/windows/acs.wxs | 39 ++------------- scripts/installer/windows/dependencies.wxs | 1 - scripts/installer/windows/en-us.wxl | 10 ++-- .../installer/windows/optionstheme_en-us.wxl | 4 +- scripts/installer/windows/readme.txt | 1 - 9 files changed, 13 insertions(+), 119 deletions(-) delete mode 100644 scripts/installer/windows/ExitDialog.wxs delete mode 100644 scripts/installer/windows/readme.txt diff --git a/client/pom.xml b/client/pom.xml index 0af1e01fee..29fef4f335 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -681,7 +681,6 @@ - @@ -720,7 +719,6 @@ - @@ -748,26 +746,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.9 - - - regex-property - - regex-property - - - final.version - ${project.version} - -SNAPSHOT - - false - - - - org.apache.cloudstack Wix-cloudstack-maven-plugin @@ -849,11 +827,10 @@ WixUIExtension WixUtilExtension - -dVersion=${final.version} -dSourceClient=SourceDir\client -dSetupPathDir=SourceDir\setup -dUtilitiesPathDir=SourceDir\scripts -dPythonSitePackagesDir=SourceDir\python-site-packages + -dSourceClient=SourceDir\client -dSetupPathDir=SourceDir\setup -dUtilitiesPathDir=SourceDir\scripts -dPythonSitePackagesDir=SourceDir\python-site-packages ../scripts/installer/windows/acs.wxs ../scripts/installer/windows/WixInstallerDialog.wxs - ../scripts/installer/windows/ExitDialog.wxs ../scripts/installer/windows/Setup_Databases.wxs target/client.wxs target/setupdb.wxs @@ -867,7 +844,6 @@ target/setupdb.wixobj target/utilities.wixobj target/WixInstallerDialog.wixobj - target/ExitDialog.wixobj target/Setup_Databases.wixobj target/python-site-packages.wixobj diff --git a/pom.xml b/pom.xml index 570d2bc585..0b3b56e7aa 100644 --- a/pom.xml +++ b/pom.xml @@ -819,7 +819,6 @@ tools/ngui/static/js/lib/* **/.checkstyle scripts/installer/windows/acs_license.rtf - scripts/installer/windows/readme.txt diff --git a/scripts/installer/windows/ExitDialog.wxs b/scripts/installer/windows/ExitDialog.wxs deleted file mode 100644 index 53fa8c5829..0000000000 --- a/scripts/installer/windows/ExitDialog.wxs +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/scripts/installer/windows/WixInstallerDialog.wxs b/scripts/installer/windows/WixInstallerDialog.wxs index a2103a9de1..0282d8ace7 100644 --- a/scripts/installer/windows/WixInstallerDialog.wxs +++ b/scripts/installer/windows/WixInstallerDialog.wxs @@ -28,7 +28,7 @@ - 1 + 1 1 diff --git a/scripts/installer/windows/acs.wxs b/scripts/installer/windows/acs.wxs index db2c8dbb42..bf09afcd6e 100644 --- a/scripts/installer/windows/acs.wxs +++ b/scripts/installer/windows/acs.wxs @@ -11,7 +11,7 @@ + Codepage='1252' Version='4.4.0' Manufacturer='!(loc.ProductManufacturer)'> - - + + @@ -139,9 +139,6 @@ - - - - @@ -284,8 +278,7 @@ NOT Installed NOT Installed - NOT Installed - NOT Installed + NOT Installed (NOT Installed) AND (CREATE_DATABASE = "1") @@ -309,31 +302,9 @@ - - - - - - - - - - - - - - - WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed - WIXUI_EXITDIALOGOPTIONALRAEDMECHECKBOX = 1 and NOT Installed - + \ No newline at end of file diff --git a/scripts/installer/windows/dependencies.wxs b/scripts/installer/windows/dependencies.wxs index 96562db877..987c561daf 100644 --- a/scripts/installer/windows/dependencies.wxs +++ b/scripts/installer/windows/dependencies.wxs @@ -17,7 +17,6 @@ - diff --git a/scripts/installer/windows/en-us.wxl b/scripts/installer/windows/en-us.wxl index 8b3999cb6d..2f34575a05 100644 --- a/scripts/installer/windows/en-us.wxl +++ b/scripts/installer/windows/en-us.wxl @@ -9,9 +9,9 @@ OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - Apache CloudStack + Apache Cloud Stack Apache - Apache CloudStack Installer + Apache Cloud Stack Installer ACS is a registered trademark Apache Apache tomcat6 is not installed please do install tomcat6 and then try @@ -19,7 +19,7 @@ Python 2.7 is not installed Please do install python and then try 7Z is not installed please do install 7z and then try Management Server - The Main Executable of CloudStack. + The Main Executable of Cloud Stack. The complete package. Provide Database Information Please provide the database information that host the cloud schemas @@ -28,7 +28,7 @@ Password Root Password Port - Create CloudStack Database + Create Cloud Stack Database Generating SSL Keys which is needed to talk to Management Server. Creating Database and needed Schemas for management server. Updating db.properties with the given database configuration. @@ -38,8 +38,6 @@ Deleting un-necessary files from installation directory. Updating Tomcat Catalina Base with Management Server Home. Updating Tomcat Classpath with necessary paths. - Launch CloudStack Server - Open Readme Version 4.0.0.0 \ No newline at end of file diff --git a/scripts/installer/windows/optionstheme_en-us.wxl b/scripts/installer/windows/optionstheme_en-us.wxl index 876372fe2a..c822929d31 100644 --- a/scripts/installer/windows/optionstheme_en-us.wxl +++ b/scripts/installer/windows/optionstheme_en-us.wxl @@ -10,8 +10,8 @@ governing permissions and limitations under the License. --> - Apache CloudStack Setup - Apache CloudStack + Apache Cloud Stack Setup + Apache Cloud Stack Install MySql Database Server Version 4.0.0.0 diff --git a/scripts/installer/windows/readme.txt b/scripts/installer/windows/readme.txt deleted file mode 100644 index 86fb3e6d8a..0000000000 --- a/scripts/installer/windows/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Need to Add the Readme Content in this file.... \ No newline at end of file From a600d8408ea86782318139c17cf346c8497943d0 Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Wed, 2 Jul 2014 14:08:16 +0530 Subject: [PATCH 005/819] Fixed Resource Leaks, null dereferences, few other issues reported by coverity --- .../src/com/cloud/dc/dao/VlanDaoImpl.java | 30 ++-- .../storage/dao/StoragePoolWorkDaoImpl.java | 26 ++- .../com/cloud/upgrade/DatabaseCreator.java | 4 +- .../usage/dao/UsageIPAddressDaoImpl.java | 21 ++- .../dao/UsageLoadBalancerPolicyDaoImpl.java | 20 ++- .../dao/UsageNetworkOfferingDaoImpl.java | 22 ++- .../dao/UsagePortForwardingRuleDaoImpl.java | 20 ++- .../usage/dao/UsageSecurityGroupDaoImpl.java | 75 ++++---- .../cloud/usage/dao/UsageStorageDaoImpl.java | 102 ++++++----- .../cloud/usage/dao/UsageVPNUserDaoImpl.java | 20 ++- .../cloud/usage/dao/UsageVolumeDaoImpl.java | 19 +- .../datastore/db/PrimaryDataStoreDaoImpl.java | 70 ++++---- .../StorageCacheRandomAllocator.java | 2 +- .../datastore/PrimaryDataStoreHelper.java | 8 +- .../dao/ManagementServerHostDaoImpl.java | 164 ++++++++++-------- .../db/src/com/cloud/utils/db/DbUtil.java | 2 +- .../com/cloud/utils/db/GenericDaoBase.java | 4 +- .../kvm/resource/BridgeVifDriver.java | 4 + .../SamplePrimaryDataStoreLifeCycleImpl.java | 1 - .../cloud/storage/VolumeApiServiceImpl.java | 2 +- .../cloud/tags/TaggedResourceManagerImpl.java | 2 +- .../vm/snapshot/VMSnapshotManagerImpl.java | 2 +- 22 files changed, 340 insertions(+), 280 deletions(-) diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java index a38a96eaa4..1003053f90 100755 --- a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -301,27 +301,25 @@ public Pair assignPodDirectAttachIpAddress(long zoneId, long pod @Override @DB public List searchForZoneWideVlans(long dcId, String vlanType, String vlanId) { - StringBuilder sql = new StringBuilder(FindZoneWideVlans); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, dcId); - pstmt.setString(2, vlanType); - pstmt.setString(3, vlanId); - - ResultSet rs = pstmt.executeQuery(); - List zoneWideVlans = new ArrayList(); - - while (rs.next()) { - zoneWideVlans.add(toEntityBean(rs, false)); + List zoneWideVlans = new ArrayList(); + try(PreparedStatement pstmt = txn.prepareStatement(sql.toString());){ + if(pstmt != null) { + pstmt.setLong(1, dcId); + pstmt.setString(2, vlanType); + pstmt.setString(3, vlanId); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + zoneWideVlans.add(toEntityBean(rs, false)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e); + } } - return zoneWideVlans; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e); } } diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java index c6e1b74f75..99e96a520f 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java @@ -116,25 +116,23 @@ public void removePendingJobsOnMsRestart(long msId, long poolId) { @Override @DB public List searchForPoolIdsForPendingWorkJobs(long msId) { - StringBuilder sql = new StringBuilder(FindPoolIds); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, msId); - - ResultSet rs = pstmt.executeQuery(); - List poolIds = new ArrayList(); - - while (rs.next()) { - poolIds.add(rs.getLong("pool_id")); + List poolIds = new ArrayList(); + try (PreparedStatement pstmt = txn.prepareStatement(sql.toString());){ + if(pstmt != null) { + pstmt.setLong(1, msId); + try (ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + poolIds.add(rs.getLong("pool_id")); + } + } catch (SQLException e) { + throw new CloudRuntimeException("searchForPoolIdsForPendingWorkJobs:Exception:" + e.getMessage(), e); + } } return poolIds; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + throw new CloudRuntimeException("searchForPoolIdsForPendingWorkJobs:Exception:" + e.getMessage(), e); } - } } diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java index b04607decc..2509d6972c 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java @@ -86,8 +86,8 @@ private static void runQuery(String host, String port, String rootPassword, Stri private static void initDB(String dbPropsFile, String rootPassword, String[] databases, boolean dryRun) { Properties dbProperties = new Properties(); - try { - dbProperties.load(new FileInputStream(new File(dbPropsFile))); + try(FileInputStream f_stream = new FileInputStream(new File(dbPropsFile));) { + dbProperties.load(f_stream); } catch (IOException e) { System.out.println("IOError: unable to load/read db properties file: " + e); System.exit(1); diff --git a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java index 17d5dc8e82..358e638b54 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -57,20 +59,25 @@ public UsageIPAddressDaoImpl() { @Override public void update(UsageIPAddressVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getReleased() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_RELEASED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getReleased())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setString(3, usage.getAddress()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_RELEASED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getReleased())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setString(3, usage.getAddress()); + pstmt.executeUpdate(); + } + }catch(SQLException e) + { + throw new CloudException("update:Exception:"+e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating usageIPAddressVO", e); + s_logger.error("Error updating usageIPAddressVO:"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java index c868ac0321..abace04186 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -73,20 +75,24 @@ public void removeBy(long accountId, long lbId) { @Override public void update(UsageLoadBalancerPolicyVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getId()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getId()); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error updating UsageLoadBalancerPolicyVO:" + e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsageLoadBalancerPolicyVO", e); + s_logger.warn("Error updating UsageLoadBalancerPolicyVO"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java index f27fd60f75..2661d4e0ec 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -56,21 +58,25 @@ public UsageNetworkOfferingDaoImpl() { @Override public void update(UsageNetworkOfferingVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getVmInstanceId()); - pstmt.setLong(4, usage.getNetworkOfferingId()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getVmInstanceId()); + pstmt.setLong(4, usage.getNetworkOfferingId()); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error updating UsageNetworkOfferingVO:"+e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsageNetworkOfferingVO", e); + s_logger.warn("Error updating UsageNetworkOfferingVO:"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java index 803288a7a6..d2053e822b 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -73,20 +75,24 @@ public void removeBy(long accountId, long pfId) { @Override public void update(UsagePortForwardingRuleVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getId()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getId()); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error updating UsagePortForwardingRuleVO:"+e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsagePortForwardingRuleVO", e); + s_logger.warn("Error updating UsagePortForwardingRuleVO:"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java index 0fc2ce0fc3..2305018dc6 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -56,21 +58,25 @@ public UsageSecurityGroupDaoImpl() { @Override public void update(UsageSecurityGroupVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getVmInstanceId()); - pstmt.setLong(4, usage.getSecurityGroupId()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getVmInstanceId()); + pstmt.setLong(4, usage.getSecurityGroupId()); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error updating UsageSecurityGroupVO:"+e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsageSecurityGroupVO", e); + s_logger.warn("Error updating UsageSecurityGroupVO:"+e.getMessage(), e); } finally { txn.close(); } @@ -101,11 +107,8 @@ public List getUsageRecords(Long accountId, Long domainId, } TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; - - try { - int i = 1; - pstmt = txn.prepareAutoCloseStatement(sql); + int i = 1; + try (PreparedStatement pstmt = txn.prepareStatement(sql);){ if (param1 != null) { pstmt.setLong(i++, param1); } @@ -115,36 +118,36 @@ public List getUsageRecords(Long accountId, Long domainId, pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - //zoneId, account_id, domain_id, vm_instance_id, security_group_id, created, deleted - Long zoneId = Long.valueOf(rs.getLong(1)); - Long acctId = Long.valueOf(rs.getLong(2)); - Long dId = Long.valueOf(rs.getLong(3)); - long vmId = Long.valueOf(rs.getLong(4)); - long sgId = Long.valueOf(rs.getLong(5)); - Date createdDate = null; - Date deletedDate = null; - String createdTS = rs.getString(6); - String deletedTS = rs.getString(7); - - if (createdTS != null) { - createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); - } - if (deletedTS != null) { - deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + //zoneId, account_id, domain_id, vm_instance_id, security_group_id, created, deleted + Long zoneId = Long.valueOf(rs.getLong(1)); + Long acctId = Long.valueOf(rs.getLong(2)); + Long dId = Long.valueOf(rs.getLong(3)); + long vmId = Long.valueOf(rs.getLong(4)); + long sgId = Long.valueOf(rs.getLong(5)); + Date createdDate = null; + Date deletedDate = null; + String createdTS = rs.getString(6); + String deletedTS = rs.getString(7); + + if (createdTS != null) { + createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); + } + if (deletedTS != null) { + deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); + } + usageRecords.add(new UsageSecurityGroupVO(zoneId, acctId, dId, vmId, sgId, createdDate, deletedDate)); } - - usageRecords.add(new UsageSecurityGroupVO(zoneId, acctId, dId, vmId, sgId, createdDate, deletedDate)); + }catch (SQLException e) { + throw new CloudException("Error getting usage records"+e.getMessage(), e); } } catch (Exception e) { txn.rollback(); - s_logger.warn("Error getting usage records", e); + s_logger.warn("Error getting usage records:"+e.getMessage(), e); } finally { txn.close(); } - return usageRecords; } } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java index 77fc56f9cd..22522751ca 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -91,19 +93,22 @@ public List listByIdAndZone(long accountId, long id, int type, l @Override public void removeBy(long accountId, long volId, int storageType) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); String sql = REMOVE_BY_USERID_STORAGEID; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, accountId); - pstmt.setLong(2, volId); - pstmt.setInt(3, storageType); - pstmt.executeUpdate(); + try( PreparedStatement pstmt = txn.prepareStatement(sql);) { + pstmt.setLong(1, accountId); + pstmt.setLong(2, volId); + pstmt.setInt(3, storageType); + pstmt.executeUpdate(); + }catch(SQLException e) + { + throw new CloudException("removeBy:Exception:"+e.getMessage(),e); + } txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error removing usageStorageVO", e); + s_logger.error("Error removing usageStorageVO", e); } finally { txn.close(); } @@ -112,21 +117,26 @@ public void removeBy(long accountId, long volId, int storageType) { @Override public void update(UsageStorageVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getId()); - pstmt.setInt(4, usage.getStorageType()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getId()); + pstmt.setInt(4, usage.getStorageType()); + pstmt.executeUpdate(); + } + }catch (SQLException e) + { + throw new CloudException("UsageStorageVO update Error:"+e.getMessage(),e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsageStorageVO", e); + s_logger.error("Error updating UsageStorageVO:"+e.getMessage(), e); } finally { txn.close(); } @@ -157,11 +167,8 @@ public List getUsageRecords(Long accountId, Long domainId, Date } TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; - - try { - int i = 1; - pstmt = txn.prepareAutoCloseStatement(sql); + int i = 1; + try (PreparedStatement pstmt = txn.prepareStatement(sql);){ if (param1 != null) { pstmt.setLong(i++, param1); } @@ -172,38 +179,41 @@ public List getUsageRecords(Long accountId, Long domainId, Date pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - //id, zone_id, account_id, domain_id, storage_type, size, created, deleted - Long id = Long.valueOf(rs.getLong(1)); - Long zoneId = Long.valueOf(rs.getLong(2)); - Long acctId = Long.valueOf(rs.getLong(3)); - Long dId = Long.valueOf(rs.getLong(4)); - Integer type = Integer.valueOf(rs.getInt(5)); - Long sourceId = Long.valueOf(rs.getLong(6)); - Long size = Long.valueOf(rs.getLong(7)); - Long virtualSize = Long.valueOf(rs.getLong(10)); - Date createdDate = null; - Date deletedDate = null; - String createdTS = rs.getString(8); - String deletedTS = rs.getString(9); - - if (createdTS != null) { - createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + //id, zone_id, account_id, domain_id, storage_type, size, created, deleted + Long id = Long.valueOf(rs.getLong(1)); + Long zoneId = Long.valueOf(rs.getLong(2)); + Long acctId = Long.valueOf(rs.getLong(3)); + Long dId = Long.valueOf(rs.getLong(4)); + Integer type = Integer.valueOf(rs.getInt(5)); + Long sourceId = Long.valueOf(rs.getLong(6)); + Long size = Long.valueOf(rs.getLong(7)); + Long virtualSize = Long.valueOf(rs.getLong(10)); + Date createdDate = null; + Date deletedDate = null; + String createdTS = rs.getString(8); + String deletedTS = rs.getString(9); + + if (createdTS != null) { + createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); + } + if (deletedTS != null) { + deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); + } + + usageRecords.add(new UsageStorageVO(id, zoneId, acctId, dId, type, sourceId, size, virtualSize, createdDate, deletedDate)); } - if (deletedTS != null) { - deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); - } - - usageRecords.add(new UsageStorageVO(id, zoneId, acctId, dId, type, sourceId, size, virtualSize, createdDate, deletedDate)); + }catch(SQLException e) + { + throw new CloudException("getUsageRecords:"+e.getMessage(),e); } - } catch (Exception e) { + }catch (Exception e) { txn.rollback(); - s_logger.warn("Error getting usage records", e); + s_logger.error("getUsageRecords:Exception:"+e.getMessage(), e); } finally { txn.close(); } - return usageRecords; } } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java index 64d3ecd7fe..e2251dfcd6 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -52,20 +54,24 @@ public UsageVPNUserDaoImpl() { @Override public void update(UsageVPNUserVO usage) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getUserId()); + try(PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) { + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); + pstmt.setLong(2, usage.getAccountId()); + pstmt.setLong(3, usage.getUserId()); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error updating UsageVPNUserVO"+e.getMessage(), e); + } } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error updating UsageVPNUserVO", e); + s_logger.error("Error updating UsageVPNUserVO:"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java index 7bf058c3f4..5beafa6039 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java @@ -18,6 +18,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -25,6 +26,7 @@ import javax.ejb.Local; +import com.cloud.exception.CloudException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -55,18 +57,21 @@ public UsageVolumeDaoImpl() { @Override public void removeBy(long accountId, long volId) { TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; try { txn.start(); - String sql = REMOVE_BY_USERID_VOLID; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, accountId); - pstmt.setLong(2, volId); - pstmt.executeUpdate(); + try(PreparedStatement pstmt = txn.prepareStatement(REMOVE_BY_USERID_VOLID);) { + if (pstmt != null) { + pstmt.setLong(1, accountId); + pstmt.setLong(2, volId); + pstmt.executeUpdate(); + } + }catch (SQLException e) { + throw new CloudException("Error removing usageVolumeVO:"+e.getMessage(), e); + } txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Error removing usageVolumeVO", e); + s_logger.warn("Error removing usageVolumeVO:"+e.getMessage(), e); } finally { txn.close(); } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 92793f1fb1..cb8ec31fdb 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -263,9 +263,8 @@ public List findPoolsByDetails(long dcId, long podId, Long cluste sql.delete(sql.length() - 4, sql.length()); sql.append(DetailsSqlSuffix); TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); + try (PreparedStatement pstmt = txn.prepareStatement(sql.toString());){ + List pools = new ArrayList(); int i = 1; pstmt.setLong(i++, dcId); pstmt.setLong(i++, podId); @@ -274,14 +273,16 @@ public List findPoolsByDetails(long dcId, long podId, Long cluste pstmt.setLong(i++, clusterId); } pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e); } return pools; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); + throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e); } } @@ -378,21 +379,24 @@ public List findZoneWideStoragePoolsByTags(long dcId, String[] ta sql.delete(sql.length() - 4, sql.length()); sql.append(ZoneWideDetailsSqlSuffix); TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setString(i++, ScopeType.ZONE.toString()); - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); + try (PreparedStatement pstmt = txn.prepareStatement(sql.toString());){ List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); + if (pstmt != null) { + int i = 1; + pstmt.setLong(i++, dcId); + pstmt.setString(i++, ScopeType.ZONE.toString()); + pstmt.setInt(i++, details.size()); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("findZoneWideStoragePoolsByTags:Exception:" + e.getMessage(), e); + } } return pools; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); + throw new CloudRuntimeException("findZoneWideStoragePoolsByTags:Exception:" + e.getMessage(), e); } } } @@ -400,27 +404,25 @@ public List findZoneWideStoragePoolsByTags(long dcId, String[] ta @Override @DB public List searchForStoragePoolDetails(long poolId, String value) { - StringBuilder sql = new StringBuilder(FindPoolTagDetails); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, poolId); - pstmt.setString(2, value); - - ResultSet rs = pstmt.executeQuery(); - List tags = new ArrayList(); - - while (rs.next()) { - tags.add(rs.getString("name")); + List tags = new ArrayList(); + try(PreparedStatement pstmt = txn.prepareStatement(sql.toString());) { + if (pstmt != null) { + pstmt.setLong(1, poolId); + pstmt.setString(2, value); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + tags.add(rs.getString("name")); + } + }catch (SQLException e) { + throw new CloudRuntimeException("searchForStoragePoolDetails:Exception:" + e.getMessage(), e); + } } return tags; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + throw new CloudRuntimeException("searchForStoragePoolDetails:Exception:" + e.getMessage(), e); } - } @Override diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java index b4ef595e99..ba1ee3cc54 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java @@ -52,7 +52,7 @@ public DataStore getCacheStore(Scope scope) { } List cacheStores = dataStoreMgr.getImageCacheStores(scope); - if (cacheStores.size() <= 0) { + if ((cacheStores == null) || (cacheStores.size() <= 0)) { s_logger.debug("Can't find staging storage in zone: " + scope.getScopeId()); return null; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index 6b12975500..ef0db85352 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -67,11 +67,14 @@ public class PrimaryDataStoreHelper { protected StoragePoolHostDao storagePoolHostDao; public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { + if(params == null) + { + throw new InvalidParameterValueException("createPrimaryDataStore: Input params is null, please check"); + } StoragePoolVO dataStoreVO = dataStoreDao.findPoolByUUID(params.getUuid()); if (dataStoreVO != null) { throw new CloudRuntimeException("duplicate uuid: " + params.getUuid()); } - dataStoreVO = new StoragePoolVO(); dataStoreVO.setStorageProviderName(params.getProviderName()); dataStoreVO.setHostAddress(params.getHost()); @@ -114,7 +117,6 @@ public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { dataStoreVO.setPath(updatedPath); } - String tags = params.getTags(); if (tags != null) { String[] tokens = tags.split(","); @@ -127,9 +129,7 @@ public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { details.put(tag, "true"); } } - dataStoreVO = dataStoreDao.persist(dataStoreVO, details); - return dataStoreMgr.getDataStore(dataStoreVO.getId(), DataStoreRole.Primary); } diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 3d0c3f5630..89d7d27825 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -53,15 +53,14 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase getInactiveList(Date cutTime) { @DB public int increaseAlertCount(long id) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; int changedRows = 0; try { txn.start(); - - pstmt = txn.prepareAutoCloseStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0"); - pstmt.setLong(1, id); - - changedRows = pstmt.executeUpdate(); + try(PreparedStatement pstmt = txn.prepareStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0");) { + pstmt.setLong(1, id); + changedRows = pstmt.executeUpdate(); + }catch (SQLException e) + { + throw new CloudRuntimeException("increaseAlertCount:Exception:"+e.getMessage(),e); + } txn.commit(); - } catch (Exception e) { - s_logger.warn("Unexpected exception, ", e); - throw new RuntimeException(e.getMessage(), e); + } catch (RuntimeException e) { + txn.rollback(); + s_logger.warn("increaseAlertCount:Exception:" + e.getMessage(), e); + throw new CloudRuntimeException("increaseAlertCount:Exception:" + e.getMessage(), e); + }finally + { + txn.close(); } - return changedRows; } @@ -211,21 +224,19 @@ protected ManagementServerHostDaoImpl() { @Override public void update(long id, long runId, State state, Date lastUpdate) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement("update mshost set state=?, last_update=? where id=? and runid=?"); - pstmt.setString(1, state.toString()); - pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); - pstmt.setLong(3, id); - pstmt.setLong(4, runId); - - int count = pstmt.executeUpdate(); - - if (count < 1) { - throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runId + " is no longer valid")); + try (PreparedStatement pstmt = txn.prepareStatement("update mshost set state=?, last_update=? where id=? and runid=?");){ + if (pstmt != null) { + pstmt.setString(1, state.toString()); + pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); + pstmt.setLong(3, id); + pstmt.setLong(4, runId); + int count = pstmt.executeUpdate(); + if (count < 1) { + throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runId + " is no longer valid")); + } } } catch (SQLException e) { - throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); + throw new CloudRuntimeException("update:Exception:" + e.getMessage(), e); } } @@ -241,22 +252,21 @@ public List listBy(ManagementServerHost.State... states) @Override public List listOrphanMsids() { List orphanList = new ArrayList(); - TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = - txn.prepareAutoCloseStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)"); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - orphanList.add(rs.getLong(1)); + try (PreparedStatement pstmt = + txn.prepareStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)");) + { + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + orphanList.add(rs.getLong(1)); + } + }catch (SQLException e) { + throw new CloudRuntimeException("listOrphanMsids:Exception:" + e.getMessage(), e); } + return orphanList; } catch (SQLException e) { - throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); + throw new CloudRuntimeException("listOrphanMsids:Exception:" + e.getMessage(), e); } - - return orphanList; } @Override diff --git a/framework/db/src/com/cloud/utils/db/DbUtil.java b/framework/db/src/com/cloud/utils/db/DbUtil.java index 792573cbce..43ed46272c 100755 --- a/framework/db/src/com/cloud/utils/db/DbUtil.java +++ b/framework/db/src/com/cloud/utils/db/DbUtil.java @@ -257,7 +257,7 @@ public static boolean releaseGlobalLock(String name) { rs = pstmt.executeQuery(); if (rs != null && rs.first()) return rs.getInt(1) > 0; - s_logger.error("RELEASE_LOCK() returns unexpected result : " + rs.getInt(1)); + s_logger.error("releaseGlobalLock:RELEASE_LOCK() returns unexpected result"); } catch (SQLException e) { s_logger.error("RELEASE_LOCK() throws exception ", e); } catch (Throwable e) { diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index 2052aadffd..4c47404438 100755 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -1486,9 +1486,9 @@ protected void prepareAttribute(final int j, final PreparedStatement pstmt, fina if (length < str.length()) { try { if (attr.is(Attribute.Flag.Encrypted)) { - pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, column.length())).getBytes("UTF-8")); + pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, length)).getBytes("UTF-8")); } else { - pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8")); + pstmt.setBytes(j, str.substring(0, length).getBytes("UTF-8")); } } catch (UnsupportedEncodingException e) { // no-way it can't support UTF-8 encoding diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index e684b8de5f..839cbaa35e 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -101,6 +101,10 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) { throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver"); } + if ((vNetId == null)||(protocol == null)) + { + throw new InternalErrorException("plug: protocol or vNetId value is null"); + } String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0; diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java index 579cc2414e..ee38072879 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java @@ -61,7 +61,6 @@ public SamplePrimaryDataStoreLifeCycleImpl() { @Override public DataStore initialize(Map dsInfos) { - DataStore store = primaryStoreHelper.createPrimaryDataStore(null); return providerMgr.getPrimaryDataStore(store.getId()); } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index a557c0e7a4..e788cb2971 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1642,7 +1642,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) { try { return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume); } finally { - if (VmJobEnabled.value()) + if ((VmJobEnabled.value())&&(placeHolder != null)) _workJobDao.expunge(placeHolder.getId()); } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index b77c55e090..ea032ad919 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -190,7 +190,7 @@ private Pair getAccountDomain(long resourceId, ResourceObjectType re accountId = Account.ACCOUNT_ID_SYSTEM; } - if ( ((accountId != null) && (domainId == -1)) || (domainId == null) ) + if ((domainId == null) || ((accountId != null) && (domainId.longValue() == -1))) { domainId = _accountDao.getDomainIdForGivenAccountId(accountId); } diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index e085b8d8fe..e46adeddd1 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -727,7 +727,7 @@ public boolean deleteAllVMSnapshots(long vmId, VMSnapshot.Type type) { try { return orchestrateDeleteAllVMSnapshots(vmId, type); } finally { - if (VmJobEnabled.value()) + if ( (VmJobEnabled.value()) && (placeHolder != null)) _workJobDao.expunge(placeHolder.getId()); } From 5c29f3ffd76a6ceaf01533b27fd37ae52fabce2f Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 13:44:02 +0200 Subject: [PATCH 006/819] Fix CID 1116694 Resource leak --- .../bridge/service/core/ec2/EC2Engine.java | 144 +++++++++--------- 1 file changed, 68 insertions(+), 76 deletions(-) diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index efca95c635..4879a4b6d4 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -35,7 +35,6 @@ import javax.naming.ConfigurationException; import javax.xml.parsers.ParserConfigurationException; -import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.xml.sax.SAXException; @@ -124,18 +123,12 @@ private void loadConfigValues() throws IOException { if (null != propertiesFile) { logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath()); Properties EC2Prop = new Properties(); - FileInputStream ec2PropFile = null; - try { - EC2Prop.load(new FileInputStream(propertiesFile)); - ec2PropFile = new FileInputStream(propertiesFile); + try (FileInputStream ec2PropFile = new FileInputStream(propertiesFile)) { EC2Prop.load(ec2PropFile); - } catch (FileNotFoundException e) { logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e); } catch (IOException e) { logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e); - } finally { - IOUtils.closeQuietly(ec2PropFile); } managementServer = EC2Prop.getProperty("managementServer"); cloudAPIPort = EC2Prop.getProperty("cloudAPIPort", null); @@ -372,12 +365,12 @@ public boolean authorizeSecurityGroup(EC2AuthorizeRevokeSecurityGroup request) { CloudStackSecurityGroup resp = null; if (ipPerm.getProtocol().equalsIgnoreCase("icmp")) { resp = - getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null, ipPerm.getIcmpCode(), ipPerm.getIcmpType(), - ipPerm.getProtocol(), null, request.getName(), null, secGroupList); + getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null, ipPerm.getIcmpCode(), ipPerm.getIcmpType(), + ipPerm.getProtocol(), null, request.getName(), null, secGroupList); } else { resp = - getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, ipPerm.getToPort().longValue(), null, null, - ipPerm.getProtocol(), null, request.getName(), ipPerm.getFromPort().longValue(), secGroupList); + getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, ipPerm.getToPort().longValue(), null, null, + ipPerm.getProtocol(), null, request.getName(), ipPerm.getFromPort().longValue(), secGroupList); } if (resp != null) { List ingressRules = resp.getIngressRules(); @@ -816,7 +809,7 @@ public boolean associateAddress(EC2AssociateAddress request) { CloudStackIpAddress cloudIp = cloudIps.get(0); List vmList = - getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null); + getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null); if (vmList == null || vmList.size() == 0) { throw new Exception("Instance not found"); } @@ -973,8 +966,8 @@ public EC2CreateImageResponse createImage(EC2CreateImage request) { String osTypeId = imageSet[0].getOsTypeId(); CloudStackTemplate resp = - getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(), osTypeId, null, null, null, null, null, - null, volumeId); + getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(), osTypeId, null, null, null, null, null, + null, volumeId); if (resp == null || resp.getId() == null) { throw new Exception("Image couldn't be created"); } @@ -1004,9 +997,9 @@ public EC2CreateImageResponse registerImage(EC2RegisterImage request) { EC2CreateImageResponse image = new EC2CreateImageResponse(); try { List templates = - getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()), request.getFormat(), - request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(), toZoneId(request.getZoneName(), null), null, - null, null, null, null, null, null, null, null); + getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()), request.getFormat(), + request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(), toZoneId(request.getZoneName(), null), null, + null, null, null, null, null, null, null, null); if (templates != null) { // technically we will only ever register a single template... for (CloudStackTemplate template : templates) { @@ -1227,7 +1220,7 @@ public EC2Volume createVolume(EC2CreateVolume request) { // -> no volume name is given in the Amazon request but is required in the cloud API CloudStackVolume vol = - getApi().createVolume(UUID.randomUUID().toString(), null, diskOfferingId, null, size, snapshotId, toZoneId(request.getZoneName(), null)); + getApi().createVolume(UUID.randomUUID().toString(), null, diskOfferingId, null, size, snapshotId, toZoneId(request.getZoneName(), null)); if (vol != null) { resp.setAttached(vol.getAttached()); resp.setCreated(vol.getCreated()); @@ -1429,8 +1422,7 @@ public EC2RunInstancesResponse runInstances(EC2RunInstances request) { logger.info("EC2 RunInstances - zone [" + request.getZoneName() + "] not found!"); throw new Exception("zone not found"); } - // we choose first zone? - CloudStackZone zone = zones.get(0); + zones.get(0); // network //CloudStackNetwork network = findNetwork(zone); @@ -1450,8 +1442,8 @@ public EC2RunInstancesResponse runInstances(EC2RunInstances request) { for (int i = 0; i < createInstances; i++) { try { CloudStackUserVm resp = - getApi().deployVirtualMachine(svcOffering.getId(), request.getTemplateId(), zoneId, null, null, null, null, null, null, null, - request.getKeyName(), null, null, groupIds, groupNames, request.getSize().longValue(), request.getUserData()); + getApi().deployVirtualMachine(svcOffering.getId(), request.getTemplateId(), zoneId, null, null, null, null, null, null, null, + request.getKeyName(), null, null, groupIds, groupNames, request.getSize().longValue(), request.getUserData()); EC2Instance vm = new EC2Instance(); vm.setId(resp.getId().toString()); vm.setName(resp.getName()); @@ -1674,7 +1666,7 @@ private int calculateAllowedInstances() throws Exception { * @param ifs - filter out unwanted instances */ private EC2DescribeInstancesResponse listVirtualMachines(String[] virtualMachineIds, EC2InstanceFilterSet ifs, List resourceTags) - throws Exception { + throws Exception { EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse(); if (null == virtualMachineIds || 0 == virtualMachineIds.length) { @@ -1698,7 +1690,7 @@ private EC2DescribeInstancesResponse listVirtualMachines(String[] virtualMachine * @param instanceId - if interested in volumes for a specific instance, null if instance is not important */ private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes, List resourceTagSet) - throws Exception { + throws Exception { List vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null, instanceId, null, resourceTagSet); if (vols != null && vols.size() > 0) { @@ -1890,11 +1882,11 @@ private EC2DescribeAvailabilityZonesResponse listZones(String[] interestedZones, * EC2Instance objects loaded. */ private EC2DescribeInstancesResponse lookupInstances(String instanceId, EC2DescribeInstancesResponse instances, List resourceTagSet) - throws Exception { + throws Exception { String instId = instanceId != null ? instanceId : null; List vms = - getApi().listVirtualMachines(null, null, true, null, null, null, null, instId, null, null, null, null, null, null, null, null, resourceTagSet); + getApi().listVirtualMachines(null, null, true, null, null, null, null, instId, null, null, null, null, null, null, null, null, resourceTagSet); if (vms != null && vms.size() > 0) { for (CloudStackUserVm cloudVm : vms) { @@ -2310,7 +2302,7 @@ private CloudStackNetwork getNetworksWithSecurityGroupEnabled(String zoneId) thr */ private CloudStackNetwork createDefaultGuestNetwork(String zoneId, CloudStackNetworkOffering offering, CloudStackAccount owner) throws Exception { return getApi().createNetwork(owner.getName() + "-network", owner.getName() + "-network", offering.getId(), zoneId, owner.getName(), owner.getDomainId(), true, - null, null, null, null, null, null, null, null); + null, null, null, null, null, null, null, null); } /** @@ -2430,49 +2422,49 @@ public String cloudDeviceIdToDevicePath(String hypervisor, String deviceId) { Integer devId = new Integer(deviceId); if (null != hypervisor && hypervisor.toLowerCase().contains("windows")) { switch (devId) { - case 1: - return "xvdb"; - case 2: - return "xvdc"; - case 3: - return "xvdd"; - case 4: - return "xvde"; - case 5: - return "xvdf"; - case 6: - return "xvdg"; - case 7: - return "xvdh"; - case 8: - return "xvdi"; - case 9: - return "xvdj"; - default: - return new String("" + deviceId); + case 1: + return "xvdb"; + case 2: + return "xvdc"; + case 3: + return "xvdd"; + case 4: + return "xvde"; + case 5: + return "xvdf"; + case 6: + return "xvdg"; + case 7: + return "xvdh"; + case 8: + return "xvdi"; + case 9: + return "xvdj"; + default: + return new String("" + deviceId); } } else { // -> assume its unix switch (devId) { - case 1: - return "/dev/sdb"; - case 2: - return "/dev/sdc"; - case 3: - return "/dev/sdd"; - case 4: - return "/dev/sde"; - case 5: - return "/dev/sdf"; - case 6: - return "/dev/sdg"; - case 7: - return "/dev/sdh"; - case 8: - return "/dev/sdi"; - case 9: - return "/dev/sdj"; - default: - return new String("" + deviceId); + case 1: + return "/dev/sdb"; + case 2: + return "/dev/sdc"; + case 3: + return "/dev/sdd"; + case 4: + return "/dev/sde"; + case 5: + return "/dev/sdf"; + case 6: + return "/dev/sdg"; + case 7: + return "/dev/sdh"; + case 8: + return "/dev/sdi"; + case 9: + return "/dev/sdj"; + default: + return new String("" + deviceId); } } } @@ -2697,8 +2689,8 @@ private void handleException(Exception e) { if (errorMessage.contains("Object vm_instance(uuid:") && errorMessage.contains(") does not exist")) { throw new EC2ServiceException(ClientError.InvalidInstanceID_NotFound, "Specified Instance ID does not exist"); } else if (errorMessage.contains("Unable to find security group by name") || errorMessage.contains("Unable to find security group") || - (errorMessage.contains("Object security_group(uuid:") && errorMessage.contains(") does not exist")) || - errorMessage.contains("Unable to find group by name ")) { + (errorMessage.contains("Object security_group(uuid:") && errorMessage.contains(") does not exist")) || + errorMessage.contains("Unable to find group by name ")) { throw new EC2ServiceException(ClientError.InvalidGroup_NotFound, "Specified Security Group does not exist"); } else if (errorMessage.contains("Invalid port numbers")) { throw new EC2ServiceException(ClientError.InvalidPermission_Malformed, "Specified Port value is invalid"); @@ -2717,7 +2709,7 @@ private void handleException(Exception e) { } else if (errorMessage.contains("Object snapshots(uuid:") && errorMessage.contains(") does not exist")) { throw new EC2ServiceException(ClientError.InvalidSnapshot_NotFound, "Specified Snapshot ID doesn't exist"); } else if ((errorMessage.contains("A key pair with name '") && errorMessage.contains("' does not exist")) || - (errorMessage.contains("A key pair with name '") && errorMessage.contains("' was not found"))) { + (errorMessage.contains("A key pair with name '") && errorMessage.contains("' was not found"))) { throw new EC2ServiceException(ClientError.InvalidKeyPair_NotFound, "Specified Key pair name is invalid"); } else if (errorMessage.contains("A key pair with name '") && errorMessage.contains("' already exists")) { throw new EC2ServiceException(ClientError.InvalidKeyPair_Duplicate, "Specified Key pair already exists"); @@ -2744,7 +2736,7 @@ private void handleException(Exception e) { } else if (errorMessage.contains("Unable to find tags by parameters specified")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified resourceTag for the specified resourceId doesn't exist"); } else if (errorMessage.contains("Failed to enable static nat for the ip address with specified ipId " - + "as vm with specified vmId is already associated with specified currentIp")) { + + "as vm with specified vmId is already associated with specified currentIp")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp is already associated to the specified VM"); } else if (errorMessage.contains("Specified IP address id is not associated with any vm Id")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp is not associated to any VM"); @@ -2792,7 +2784,7 @@ private void handleException(Exception e) { throw new EC2ServiceException(ClientError.InvalidAMIID_NotFound, "Specified ImageId is unavailable"); } else if (errorMessage.contains("cannot stop VM") && errorMessage.contains("when it is in state Starting")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to stop. One or more of the specified instances is in an incorrect state 'pending'"); + "Unable to stop. One or more of the specified instances is in an incorrect state 'pending'"); } else if (errorMessage.contains("Failed to authorize security group ingress rule(s)")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified Ip-permission is invalid" + " or the Ip-permission already exists"); } else if (errorMessage.contains("Failed to reboot vm instance")) { @@ -2807,7 +2799,7 @@ private void handleException(Exception e) { throw new EC2ServiceException(ClientError.VolumeLimitExceeded, "You have reached the limit on the number of volumes that can be created"); } else if (errorMessage.contains("Maximum number of resources of type 'public_ip' for account") && errorMessage.contains("has been exceeded")) { throw new EC2ServiceException(ClientError.AddressLimitExceeded, - "You have reached the limit on the number of elastic ip addresses your account can have"); + "You have reached the limit on the number of elastic ip addresses your account can have"); } else if (errorMessage.contains("Unable to apply save userdata entry on router")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "The value supplied for parameter UserData is invalid"); } else { @@ -2855,7 +2847,7 @@ private void handleException(Exception e) { throw new EC2ServiceException(ServerError.InternalError, "Unable to start the instance that was stopped during image creation"); } else if (errorMessage.contains("One or more of instanceIds specified is in stopped state")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to reboot. One or more of the specified instances is in an incorrect state 'stopped'"); + "Unable to reboot. One or more of the specified instances is in an incorrect state 'stopped'"); } else if (errorMessage.contains("Specified ipAddress doesn't exist")) { throw new EC2ServiceException(ClientError.InvalidParameterValue, "Specified publicIp doesn't exist"); } else if (errorMessage.contains("Min Count is greater than the number of instances left to allocate")) { @@ -2874,7 +2866,7 @@ private void handleException(Exception e) { throw new EC2ServiceException(ClientError.InvalidInstanceID_NotFound, "One or more of the specified instanceId not found"); } else if (errorMessage.contains("Cannot modify, instance should be in stopped state")) { throw new EC2ServiceException(ClientError.IncorrectInstanceState, - "Unable to modify instance attribute. Specified instance is not in the correct state 'stopped'"); + "Unable to modify instance attribute. Specified instance is not in the correct state 'stopped'"); } else { throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occured"); } From cc913cf0bb7e62b7a216e2de793336e61a49b485 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 13:50:03 +0200 Subject: [PATCH 007/819] Fix CID 1116497 Resource leak --- .../server/src/com/cloud/consoleproxy/ConsoleProxy.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java index 02fda6424b..3b3b82feed 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java @@ -307,6 +307,11 @@ public static void startWithContext(Properties conf, Object context, byte[] ksBi s_logger.error(e.toString(), e); } } + try { + confs.close(); + } catch (IOException e) { + s_logger.error("Failed to close consolepropxy.properties : " + e.toString(), e); + } start(conf); } From 539db08956eff322efd11771d46d29df0c7289b2 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 14:34:48 +0200 Subject: [PATCH 008/819] CLOUDSTACK-6892 Create separate package for the mysql HA component --- client/tomcatconf/catalina.properties.in | 2 +- packaging/centos63/cloud.spec | 36 ++++++++++++++++++++++-- packaging/centos63/package.sh | 7 ++++- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/client/tomcatconf/catalina.properties.in b/client/tomcatconf/catalina.properties.in index ce03ff6390..282892bb76 100644 --- a/client/tomcatconf/catalina.properties.in +++ b/client/tomcatconf/catalina.properties.in @@ -44,7 +44,7 @@ package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache # "foo/*.jar": Add all the JARs of the specified folder as class # repositories # "foo/bar.jar": Add bar.jar as a class repository -common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,/usr/share/java/mysql-connector-java.jar +common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,/usr/share/java/mysql-connector-java.jar,/usr/share/cloudstack-mysql-ha/lib/*jar # # List of comma-separated paths defining the contents of the "server" diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index d2f19cdb90..1d4d061851 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -165,6 +165,17 @@ Group: System Environment/Libraries %description awsapi Apache Cloudstack AWS API compatibility wrapper +%if "%{_ossnoss}" == "NOREDIST" +%package mysql-ha +Summary: Apache CloudStack Balancing Strategy for MySQL +Requires: mysql-connector-java +Requires: tomcat7 +Group: System Environmnet/Libraries +%description mysql-ha +Apache CloudStack Balancing Strategy for MySQL + +%endif + %prep echo Doing CloudStack build @@ -328,6 +339,12 @@ for name in cloud-bridge.properties commons-logging.properties ec2-service.prope ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/$name done +# MYSQL HA +if [ "x%{_ossnoss}" == "xNOREDIST" ] ; then + mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-mysql-ha/lib + cp -r plugins/database/mysql-ha/target/cloud-plugin-database-mysqlha-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-mysql-ha/lib +fi + #Don't package the below for AWS API rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-bridge/webapps/awsapi/WEB-INF/classes/db.properties rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-bridge/webapps/awsapi/WEB-INF/classes/LICENSE.txt @@ -347,9 +364,13 @@ install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-agen install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-usage-%{version}/NOTICE install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-usage-%{version}/LICENSE install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-awsapi-%{version}/NOTICE -install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-awsapi-%{version}/LICENSE -install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-cli-%{version}/NOTICE +install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-awsapi-%{version}/LICENSE +install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-cli-%{version}/NOTICE install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-cli-%{version}/LICENSE +if [ "x%{_ossnoss}" == "xNOREDIST" ] ; then + install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-mysql-ha-%{version}/LICENSE + install -D tools/whisker/NOTICE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-mysql-ha-%{version}/NOTICE +fi %clean [ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT} @@ -630,8 +651,17 @@ fi %{_defaultdocdir}/%{name}-awsapi-%{version}/LICENSE %{_defaultdocdir}/%{name}-awsapi-%{version}/NOTICE +%if "%{_ossnoss}" == "NOREDIST" +%files mysql-ha +%defattr(0644,cloud,cloud,0755) +%attr(0644,root,root) %{_datadir}/%{name}-mysql-ha/lib/* +%{_defaultdocdir}/%{name}-mysql-ha-%{version}/LICENSE +%{_defaultdocdir}/%{name}-mysql-ha-%{version}/NOTICE +%endif %changelog +* Fri Jul 04 2014 Hugo Trippaers 4.5.0 +- Add a package for the mysql ha module + * Fri Oct 03 2012 Hugo Trippaers 4.1.0 - new style spec file - diff --git a/packaging/centos63/package.sh b/packaging/centos63/package.sh index fa004afff3..07f95fc0cd 100755 --- a/packaging/centos63/package.sh +++ b/packaging/centos63/package.sh @@ -39,7 +39,7 @@ function packaging() { fi VERSION=`(cd ../../; mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version) | grep --color=none '^[0-9]\.'` - if echo $VERSION | grep SNAPSHOT ; then + if echo $VERSION | grep -q SNAPSHOT ; then REALVER=`echo $VERSION | cut -d '-' -f 1` DEFVER="-D_ver $REALVER" DEFPRE="-D_prerelease 1" @@ -50,19 +50,24 @@ function packaging() { DEFREL="-D_rel 1" fi + echo Preparing to package Apache CloudStack ${VERSION} + mkdir -p $RPMDIR/SPECS mkdir -p $RPMDIR/BUILD mkdir -p $RPMDIR/RPMS mkdir -p $RPMDIR/SRPMS mkdir -p $RPMDIR/SOURCES/$PACK_PROJECT-$VERSION + echo ". preparing source tarball" (cd ../../; tar -c --exclude .git --exclude dist . | tar -C $RPMDIR/SOURCES/$PACK_PROJECT-$VERSION -x ) (cd $RPMDIR/SOURCES/; tar -czf $PACK_PROJECT-$VERSION.tgz $PACK_PROJECT-$VERSION) + echo ". executing rpmbuild" cp cloud.spec $RPMDIR/SPECS (cd $RPMDIR; rpmbuild --define "_topdir $RPMDIR" "${DEFVER}" "${DEFREL}" ${DEFPRE+"${DEFPRE}"} ${DEFOSSNOSS+"$DEFOSSNOSS"} -bb SPECS/cloud.spec) + echo "Done" exit } From 362b4811765ed47c94e9c84e2dec03a311600fd6 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 15:50:23 +0200 Subject: [PATCH 009/819] Fix CID 1164032 Dodgy code --- .../cloudstack/storage/datastore/util/NexentaNmsClient.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java index 70565fcea3..ed1a780f87 100644 --- a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java @@ -45,10 +45,11 @@ import org.apache.http.impl.conn.BasicClientConnectionManager; import org.apache.log4j.Logger; -import com.cloud.utils.exception.CloudRuntimeException; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; +import com.cloud.utils.exception.CloudRuntimeException; + public class NexentaNmsClient { private static final Logger logger = Logger.getLogger(NexentaNmsClient.class); @@ -123,7 +124,7 @@ static class NmsRequest { private Object[] params; NmsRequest(String object, String method) { - this(method, object, null); + this(object, method, (Object[])null); } NmsRequest(String object, String method, Object... params) { @@ -132,6 +133,7 @@ static class NmsRequest { this.params = params; } + @Override public String toString() { StringBuffer b = new StringBuffer(); b.append("Request to ").append(object).append(" method ").append(method); From b9145beab6672e7c8cae96e227ffab00d433350e Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 16:32:53 +0200 Subject: [PATCH 010/819] Fix CID 1116267 Don't modify the set while the iterator is still in use. --- .../hypervisor/kvm/resource/KVMHAMonitor.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java index 4628fae55d..86950458fe 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java @@ -17,8 +17,10 @@ package com.cloud.hypervisor.kvm.resource; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; @@ -39,24 +41,24 @@ public class KVMHAMonitor extends KVMHABase implements Runnable { public KVMHAMonitor(NfsStoragePool pool, String host, String scriptPath) { if (pool != null) { - this._storagePool.put(pool._poolUUID, pool); + _storagePool.put(pool._poolUUID, pool); } - this._hostIP = host; + _hostIP = host; KVMHABase.s_heartBeatPath = scriptPath; } public void addStoragePool(NfsStoragePool pool) { synchronized (_storagePool) { - this._storagePool.put(pool._poolUUID, pool); + _storagePool.put(pool._poolUUID, pool); } } public void removeStoragePool(String uuid) { synchronized (_storagePool) { - NfsStoragePool pool = this._storagePool.get(uuid); + NfsStoragePool pool = _storagePool.get(uuid); if (pool != null) { Script.runSimpleBashScript("umount " + pool._mountDestPath); - this._storagePool.remove(uuid); + _storagePool.remove(uuid); } } } @@ -72,6 +74,7 @@ private class Monitor extends ManagedContextRunnable { @Override protected void runInContext() { synchronized (_storagePool) { + Set removedPools = new HashSet(); for (String uuid : _storagePool.keySet()) { NfsStoragePool primaryStoragePool = _storagePool.get(uuid); @@ -84,13 +87,13 @@ protected void runInContext() { storage = conn.storagePoolLookupByUUIDString(uuid); if (storage == null) { s_logger.debug("Libvirt storage pool " + uuid + " not found, removing from HA list"); - removeStoragePool(uuid); + removedPools.add(uuid); continue; } else if (storage.getInfo().state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) { s_logger.debug("Libvirt storage pool " + uuid + " found, but not running, removing from HA list"); - removeStoragePool(uuid); + removedPools.add(uuid); continue; } s_logger.debug("Found NFS storage pool " + uuid + " in libvirt, continuing"); @@ -102,7 +105,7 @@ protected void runInContext() { // connection fails if (e.toString().contains("pool not found")) { s_logger.debug("removing pool from HA monitor since it was deleted"); - removeStoragePool(uuid); + removedPools.add(uuid); continue; } } @@ -132,6 +135,12 @@ protected void runInContext() { result = cmd.execute(); } } + + if (!removedPools.isEmpty()) { + for (String uuid : removedPools) { + removeStoragePool(uuid); + } + } } } From fc23c70a1f349ff4c54fca18c17437cacf6c26dc Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 4 Jul 2014 16:47:11 +0200 Subject: [PATCH 011/819] Fix CID 1116481 Widening should happen before calculation --- .../apache/cloudstack/storage/template/DownloadManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index d45a6bbe60..ec5b56969c 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -357,7 +357,7 @@ private String postDownload(String jobId) { int imgSizeGigs = (int)Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024)); imgSizeGigs++; // add one just in case - long timeout = imgSizeGigs * installTimeoutPerGig; + long timeout = (long)imgSizeGigs * installTimeoutPerGig; Script scr = null; String script = resourceType == ResourceType.TEMPLATE ? createTmpltScr : createVolScr; scr = new Script(script, timeout, s_logger); From a413536f90c0e3b1d43862c0d2b9c1bf292cfc8a Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Mon, 7 Jul 2014 12:53:05 +0530 Subject: [PATCH 012/819] Added a simulator based test for VM sync --- .../api/commands/ConfigureSimulatorCmd.java | 5 +- .../cloud/simulator/MockConfigurationVO.java | 2 +- test/integration/smoke/test_vm_sync.py | 151 ++++++++++++++++++ tools/marvin/marvin/config/test_data.py | 10 +- tools/marvin/marvin/lib/base.py | 4 +- 5 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 test/integration/smoke/test_vm_sync.py diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java index 9498a93a23..b891c6cbae 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java +++ b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java @@ -69,12 +69,15 @@ public class ConfigureSimulatorCmd extends BaseCmd { @Parameter(name=ApiConstants.COUNT, type=CommandType.INTEGER, description="number of times the mock is active") private Integer count; - @Parameter(name="jsonresponse", type=CommandType.STRING, description="agent command response to be returned") + @Parameter(name="jsonresponse", type=CommandType.STRING, description="agent command response to be returned", length=4096) private String jsonResponse; @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + if (hostId != null && jsonResponse != null) { + jsonResponse = jsonResponse.replace("\"hostId\":0", "\"hostId\":" + hostId); + } Long id = _simMgr.configureSimulator(zoneId, podId, clusterId, hostId, command, values, count, jsonResponse); if (id == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure simulator"); diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java index 1beff76134..6edec12a81 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java @@ -60,7 +60,7 @@ public class MockConfigurationVO implements InternalIdentity { @Column(name="count") private Integer count; - @Column(name="json_response") + @Column(name="json_response", length=4096) private String jsonResponse; @Column(name="removed") diff --git a/test/integration/smoke/test_vm_sync.py b/test/integration/smoke/test_vm_sync.py new file mode 100644 index 0000000000..6d56945387 --- /dev/null +++ b/test/integration/smoke/test_vm_sync.py @@ -0,0 +1,151 @@ +# 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. + +#Test from the Marvin - Testing in Python wiki + +import time + +#All tests inherit from cloudstackTestCase +from marvin.cloudstackTestCase import cloudstackTestCase + +#Import Integration Libraries + +#base - contains all resources as entities and defines create, delete, list operations on them +from marvin.lib.base import Account, VirtualMachine, Cluster, Host, ServiceOffering, Configurations, SimulatorMock + +#utils - utility classes for common cleanup, external library wrappers etc +from marvin.lib.utils import cleanup_resources + +#common - commonly used methods for all tests are listed here +from marvin.lib.common import get_zone, get_domain, get_template + +from nose.plugins.attrib import attr + +class TestDeployVMSync(cloudstackTestCase): + """Test VM Sync + """ + + def setUp(self): + self.testdata = self.testClient.getParsedTestDataConfig() + self.apiclient = self.testClient.getApiClient() + + # Get Zone, Domain and Default Built-in template + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + + self.testdata["mode"] = self.zone.networktype + self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) + + hosts = Host.list(self.apiclient, type='Routing') + self.assertTrue(isinstance(hosts, list) and len(hosts) > 0, msg = "No hosts found") + self.host = hosts[0] + #update host tags + Host.update(self.apiclient, id=self.host.id, hosttags=self.testdata["service_offerings"]["taggedsmall"]["hosttags"]) + + #create a user account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + #create a service offering + self.service_offering = ServiceOffering.create( + self.apiclient, + self.testdata["service_offerings"]["taggedsmall"] + ) + #deploy vms + self.vm1 = VirtualMachine.create( + self.apiclient, + self.testdata["small"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + self.vm2 = VirtualMachine.create( + self.apiclient, + self.testdata["small"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + self.vm3 = VirtualMachine.create( + self.apiclient, + self.testdata["small"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + list_vms = VirtualMachine.list(self.apiclient, ids=[self.vm1.id, self.vm2.id, self.vm3.id], listAll=True) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 3, msg = "List VM response is empty") + clusters = Cluster.list(self.apiclient, id=self.host.clusterid) + self.assertTrue(isinstance(clusters, list) and len(clusters) > 0, msg = "Cluster not found") + + json_response = '{"com.cloud.agent.api.PingRoutingWithNwGroupsCommand":{"newGroupStates":{},"newStates":{},"_hostVmStateReport":{"%s":{"state":"PowerOn","host":"%s"},"%s":{"state":"PowerOff","host":"%s"}},"_gatewayAccessible":true,"_vnetAccessible":true,"hostType":"Routing","hostId":0,"contextMap":{},"wait":0}}' + json_response = json_response%(self.vm1.instancename, self.host.name, self.vm2.instancename, self.host.name) + + #create a mock to simulate vm1 as power-on, vm2 as power-off and vm3 as missing + self.mock_ping = SimulatorMock.create( + apiclient=self.apiclient, + command="PingRoutingWithNwGroupsCommand", + zoneid=self.zone.id, + podid=clusters[0].podid, + clusterid=clusters[0].id, + hostid=self.host.id, + value='', + jsonresponse=json_response, + method='POST') + + #build cleanup list + self.cleanup = [ + self.service_offering, + self.account, + self.mock_ping + ] + + @attr(tags = ['advanced'], required_hardware="false", BugId="CLOUDSTACK-6873") + def test_vm_sync(self): + """Test VM Sync + + # Validate the following: + # vm1 should be running, vm2 should be stopped as power report says PowerOff, vm3 should be stopped as missing from power report + """ + + #wait for vmsync to happen + ping_interval = Configurations.list(self.apiclient, name="ping.interval") + total_duration = int(float(ping_interval[0].value) * 3.2) + time.sleep(total_duration) + + list_vms = VirtualMachine.list(self.apiclient, ids=[self.vm1.id, self.vm2.id, self.vm3.id], listAll=True) + self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 3, msg = "List VM response is empty") + for vm in list_vms: + if vm.id == self.vm1.id: + self.assertTrue(vm.state == "Running", msg = "VM {0} is expected to be in running state".format(vm.name)) + elif vm.id == self.vm2.id or vm.id == self.vm3.id: + self.assertTrue(vm.state == "Stopped", msg = "VM {0} is expected to be in stopped state".format(vm.name)) + + def tearDown(self): + try: + Host.update(self.apiclient, id=self.host.id, hosttags="") + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 5607217126..19b9aa4afd 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -90,7 +90,7 @@ "memory": 128, "tiny": { - "name": "Tiny Instance", + "name": "Tiny Instance", "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, @@ -126,6 +126,14 @@ "hosttags": "ha", "offerha": True, }, + "taggedsmall": { + "name": "Tagged Small Instance", + "displaytext": "Tagged Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + "hosttags": "vmsync", + }, }, "disk_offering": { "name": "Disk offering", diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 2ef6f8209b..445fabab1a 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -4564,7 +4564,7 @@ def __init__(self, items): @classmethod def create(cls, apiclient, command, zoneid=None, podid=None, clusterid=None, hostid=None, value="result:fail", - count=None, jsonresponse=None): + count=None, jsonresponse=None, method="GET"): """Creates simulator mock""" cmd = configureSimulator.configureSimulatorCmd() cmd.zoneid = zoneid @@ -4576,7 +4576,7 @@ def create(cls, apiclient, command, zoneid=None, podid=None, cmd.count = count cmd.jsonresponse = jsonresponse try: - simulatormock = apiclient.configureSimulator(cmd) + simulatormock = apiclient.configureSimulator(cmd, method=method) if simulatormock is not None: return SimulatorMock(simulatormock.__dict__) except Exception as e: From 4f969057b2434cf09562c05a503592f661e7d83e Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 7 Jul 2014 12:01:38 +0530 Subject: [PATCH 013/819] CLOUDSTACK-7030. After the restart of MS in a clustered MS pool, not all hung worker VMs are recycled. Recycle worker VMs that originally belonged to other management servers too because in case of MS restart, the owner MS might change. --- .../cluster/src/com/cloud/cluster/ClusterManager.java | 2 ++ .../src/com/cloud/cluster/ClusterManagerImpl.java | 9 +++++++++ .../hypervisor/vmware/manager/VmwareManagerImpl.java | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManager.java b/framework/cluster/src/com/cloud/cluster/ClusterManager.java index ffdf3663f7..86d6fb3ab9 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManager.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManager.java @@ -60,6 +60,8 @@ public interface ClusterManager extends Manager { long getCurrentRunId(); + public long getManagementRunId(long msId); + public interface Dispatcher { String getName(); diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index 622aa62f07..4a0987f902 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -1072,6 +1072,15 @@ public long getCurrentRunId() { return _runId; } + @Override + public long getManagementRunId(long msId) { + ManagementServerHostVO mshost = _mshostDao.findByMsid(msId); + if (mshost != null) { + return mshost.getRunid(); + } + return -1; + } + public boolean isManagementNodeAlive(long msid) { ManagementServerHostVO mshost = _mshostDao.findByMsid(msid); if (mshost != null) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 36d23229b7..3fd1a9cd1b 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -531,7 +531,7 @@ public boolean needRecycle(String workerTag) { return true; } - if (msid == _clusterMgr.getManagementNodeId() && runid != _clusterMgr.getCurrentRunId()) { + if (runid != _clusterMgr.getManagementRunId(msid)) { if (s_logger.isInfoEnabled()) s_logger.info("Worker VM's owner management server has changed runid, recycle it"); return true; From 8cf94c9ec18dfb1c7d49837591691d2f35ffaad8 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 7 Jul 2014 14:36:58 +0530 Subject: [PATCH 014/819] CLOUDSTACK-7069. [VMware] While setting 'numCoresPerSocket' property for a Virtual Machine in VMware add a check to ensure the vSphere version is 5.0 or above. --- .../vmware/resource/VmwareResource.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 5b49e5b8ee..08d69e0592 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1438,17 +1438,32 @@ protected StartAnswer execute(StartCommand cmd) { getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse()); - // Check for hotadd settings - vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId)); - vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId)); - configNestedHVSupport(vmMo, vmSpec, vmConfigSpec); - // Check for multi-cores per socket settings + int numCoresPerSocket = 1; String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket"); if (coresPerSocket != null) { - vmConfigSpec.setNumCoresPerSocket(NumbersUtil.parseInt(coresPerSocket, 1)); + String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext()); + // Property 'numCoresPerSocket' is supported since vSphere API 5.0 + if (apiVersion.compareTo("5.0") >= 0) { + numCoresPerSocket = NumbersUtil.parseInt(coresPerSocket, 1); + vmConfigSpec.setNumCoresPerSocket(numCoresPerSocket); + } } + // Check for hotadd settings + vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId)); + + String hostApiVersion = ((HostMO)hyperHost).getHostAboutInfo().getApiVersion(); + if (numCoresPerSocket > 1 && hostApiVersion.compareTo("5.0") < 0) { + s_logger.warn("Dynamic scaling of CPU is not supported for Virtual Machines with multi-core vCPUs in case of ESXi hosts 4.1 and prior. Hence CpuHotAdd will not be" + + " enabled for Virtual Machine: " + vmInternalCSName); + vmConfigSpec.setCpuHotAddEnabled(false); + } else { + vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId)); + } + + configNestedHVSupport(vmMo, vmSpec, vmConfigSpec); + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices]; int i = 0; int ideUnitNumber = 0; From 8e112858d35a77943e154e69736caaf2e5b94e7d Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 4 Jul 2014 12:24:25 +0530 Subject: [PATCH 015/819] CLOUDSTACK-7071. Upgrade to CCP 4.2 fails in case a VMware setup has multiple zones mapping to the same VMware datacenter. If 2 or more CloudStack zones map to the same VMware datacenter, mark the zones as legacy zones. --- .../cloud/upgrade/dao/Upgrade410to420.java | 163 +++++++++++++----- 1 file changed, 117 insertions(+), 46 deletions(-) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 671cbb7269..097f6c544f 100755 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -863,14 +863,14 @@ private void upgradeVmwareLabels(Connection conn) { private void persistLegacyZones(Connection conn) { List listOfLegacyZones = new ArrayList(); + List listOfNonLegacyZones = new ArrayList(); + Map> dcToZoneMap = new HashMap>(); PreparedStatement pstmt = null; PreparedStatement clustersQuery = null; PreparedStatement clusterDetailsQuery = null; ResultSet rs = null; ResultSet clusters = null; ResultSet clusterDetails = null; - ResultSet dcInfo = null; - Long vmwareDcId = 1L; Long zoneId; Long clusterId; String clusterHypervisorType; @@ -881,13 +881,8 @@ private void persistLegacyZones(Connection conn) { String dcOfCurrentCluster = null; String[] tokens; String url; - String user = ""; - String password = ""; String vc = ""; String dcName = ""; - String guid; - String key; - String value; try { pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where removed is NULL"); @@ -899,6 +894,7 @@ private void persistLegacyZones(Connection conn) { clustersQuery.setLong(1, zoneId); legacyZone = false; ignoreZone = true; + ArrayList dcList = new ArrayList(); count = 0L; // Legacy zone term is meant only for VMware // Legacy zone is a zone with atleast 2 clusters & with multiple DCs or VCs @@ -923,6 +919,9 @@ private void persistLegacyZones(Connection conn) { dcName = tokens[3]; dcOfPreviousCluster = dcOfCurrentCluster; dcOfCurrentCluster = dcName + "@" + vc; + if (!dcList.contains(dcOfCurrentCluster)) { + dcList.add(dcOfCurrentCluster); + } if (count > 0) { if (!dcOfPreviousCluster.equalsIgnoreCase(dcOfCurrentCluster)) { legacyZone = true; @@ -942,47 +941,30 @@ private void persistLegacyZones(Connection conn) { if (legacyZone) { listOfLegacyZones.add(zoneId); } else { - assert (clusterDetails != null) : "Couldn't retrieve details of cluster!"; - s_logger.debug("Discovered non-legacy zone " + zoneId + ". Processing the zone to associate with VMware datacenter."); - - clusterDetailsQuery = conn.prepareStatement("select name, value from `cloud`.`cluster_details` where cluster_id=?"); - clusterDetailsQuery.setLong(1, clusterId); - clusterDetails = clusterDetailsQuery.executeQuery(); - while (clusterDetails.next()) { - key = clusterDetails.getString(1); - value = clusterDetails.getString(2); - if (key.equalsIgnoreCase("username")) { - user = value; - } else if (key.equalsIgnoreCase("password")) { - password = value; - } + listOfNonLegacyZones.add(zoneId); + } + for (String dc : dcList) { + ArrayList dcZones = new ArrayList(); + if (dcToZoneMap.get(dc) != null) { + dcZones = dcToZoneMap.get(dc); } - guid = dcName + "@" + vc; - - pstmt = - conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center` (uuid, name, guid, vcenter_host, username, password) values(?, ?, ?, ?, ?, ?)"); - pstmt.setString(1, UUID.randomUUID().toString()); - pstmt.setString(2, dcName); - pstmt.setString(3, guid); - pstmt.setString(4, vc); - pstmt.setString(5, user); - pstmt.setString(6, password); - pstmt.executeUpdate(); - - pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`vmware_data_center` where guid=?"); - pstmt.setString(1, guid); - dcInfo = pstmt.executeQuery(); - if (dcInfo.next()) { - vmwareDcId = dcInfo.getLong("id"); + dcZones.add(zoneId); + dcToZoneMap.put(dc, dcZones); + } + } + // If a VMware datacenter in a vCenter maps to more than 1 CloudStack zone, mark all the zones it is mapped to as legacy + for (Map.Entry> entry : dcToZoneMap.entrySet()) { + if (entry.getValue().size() > 1) { + for (Long newLegacyZone : entry.getValue()) { + if (listOfNonLegacyZones.contains(newLegacyZone)) { + listOfNonLegacyZones.remove(newLegacyZone); + listOfLegacyZones.add(newLegacyZone); + } } - - pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center_zone_map` (zone_id, vmware_data_center_id) values(?, ?)"); - pstmt.setLong(1, zoneId); - pstmt.setLong(2, vmwareDcId); - pstmt.executeUpdate(); } } updateLegacyZones(conn, listOfLegacyZones); + updateNonLegacyZones(conn, listOfNonLegacyZones); } catch (SQLException e) { String msg = "Unable to discover legacy zones." + e.getMessage(); s_logger.error(msg); @@ -995,9 +977,6 @@ private void persistLegacyZones(Connection conn) { if (pstmt != null) { pstmt.close(); } - if (dcInfo != null) { - dcInfo.close(); - } if (clusters != null) { clusters.close(); } @@ -1037,6 +1016,98 @@ private void updateLegacyZones(Connection conn, List zones) { } } + private void updateNonLegacyZones(Connection conn, List zones) { + PreparedStatement clustersQuery = null; + PreparedStatement clusterDetailsQuery = null; + PreparedStatement pstmt = null; + ResultSet clusters = null; + ResultSet clusterDetails = null; + ResultSet dcInfo = null; + try { + for (Long zoneId : zones) { + s_logger.debug("Discovered non-legacy zone " + zoneId + ". Processing the zone to associate with VMware datacenter."); + + // All clusters in a non legacy zone will belong to the same VMware DC, hence pick the first cluster + clustersQuery = conn.prepareStatement("select id from `cloud`.`cluster` where removed is NULL AND data_center_id=?"); + clustersQuery.setLong(1, zoneId); + clusters = clustersQuery.executeQuery(); + clusters.next(); + Long clusterId = clusters.getLong("id"); + + // Get VMware datacenter details from cluster_details table + String user = null; + String password = null; + String url = null; + clusterDetailsQuery = conn.prepareStatement("select name, value from `cloud`.`cluster_details` where cluster_id=?"); + clusterDetailsQuery.setLong(1, clusterId); + clusterDetails = clusterDetailsQuery.executeQuery(); + while (clusterDetails.next()) { + String key = clusterDetails.getString(1); + String value = clusterDetails.getString(2); + if (key.equalsIgnoreCase("username")) { + user = value; + } else if (key.equalsIgnoreCase("password")) { + password = value; + } else if (key.equalsIgnoreCase("url")) { + url = value; + } + } + String[] tokens = url.split("/"); // url format - http://vcenter/dc/cluster + String vc = tokens[2]; + String dcName = tokens[3]; + String guid = dcName + "@" + vc; + + pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center` (uuid, name, guid, vcenter_host, username, password) values(?, ?, ?, ?, ?, ?)"); + pstmt.setString(1, UUID.randomUUID().toString()); + pstmt.setString(2, dcName); + pstmt.setString(3, guid); + pstmt.setString(4, vc); + pstmt.setString(5, user); + pstmt.setString(6, password); + pstmt.executeUpdate(); + + pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`vmware_data_center` where guid=?"); + pstmt.setString(1, guid); + dcInfo = pstmt.executeQuery(); + Long vmwareDcId = -1L; + if (dcInfo.next()) { + vmwareDcId = dcInfo.getLong("id"); + } + + pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center_zone_map` (zone_id, vmware_data_center_id) values(?, ?)"); + pstmt.setLong(1, zoneId); + pstmt.setLong(2, vmwareDcId); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Unable to update non legacy zones." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try { + if (clustersQuery != null) { + clustersQuery.close(); + } + if (clusterDetails != null) { + clusterDetails.close(); + } + if (clusterDetailsQuery != null) { + clusterDetailsQuery.close(); + } + if (clusters != null) { + clusters.close(); + } + if (dcInfo != null) { + dcInfo.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + } + private void createPlaceHolderNics(Connection conn) { PreparedStatement pstmt = null; ResultSet rs = null; From 4be369c94c4c9a2609f922fa414178191753c8bd Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 23 Jun 2014 15:30:37 +0530 Subject: [PATCH 016/819] CLOUDSTACK-7072. Volume attachment fails with 'A specified parameter was not correct' error. [VMware] While attaching a new disk to an instance, the unit number on the controller key should be the lowest unit number on the key that is not in use. Instead of a number that is 1 digit higher the highest unit number that is currently in use. --- .../hypervisor/vmware/mo/VirtualMachineMO.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 263c656868..b5b9a5ef83 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -2295,17 +2295,22 @@ public int getNextPCIDeviceNumber() throws Exception { public int getNextDeviceNumber(int controllerKey) throws Exception { List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - int deviceNumber = -1; + List existingUnitNumbers = new ArrayList(); + int deviceNumber = 0; if (devices != null && devices.size() > 0) { for (VirtualDevice device : devices) { if (device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) { - if (device.getUnitNumber() != null && device.getUnitNumber().intValue() > deviceNumber) { - deviceNumber = device.getUnitNumber().intValue(); - } + existingUnitNumbers.add(device.getUnitNumber()); } } } - return ++deviceNumber; + while (true) { + if (!existingUnitNumbers.contains(Integer.valueOf(deviceNumber))) { + break; + } + ++deviceNumber; + } + return deviceNumber; } private List getNicDevices(boolean sorted) throws Exception { From 7b444183db7e84616a377f76737237e704785df0 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 11:37:38 -0700 Subject: [PATCH 017/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- plugins/hypervisors/baremetal/pom.xml | 12 +- .../spring-baremetal-compute-context.xml | 2 +- .../spring-baremetal-discoverer-context.xml | 2 +- .../spring-baremetal-network-context.xml | 2 +- .../spring-baremetal-planner-context.xml | 2 +- .../core/spring-baremetal-core-context.xml | 4 +- .../resources/security_group_agent/cs-sgagent | 40 +-- .../security_group_agent/__init__.py | 6 +- .../security_group_agent/cs_sg_agent.py | 7 +- .../security_group_agent/sglib.py | 68 ++--- .../security_group_agent/xmlobject.py | 6 +- .../resources/security_group_agent/setup.py | 6 +- .../baremetal/database/BaremetalRctDao.java | 9 + .../database/BaremetalRctDaoImpl.java | 9 + .../baremetal/database/BaremetalRctVO.java | 62 +++++ .../manager/BareMetalDiscoverer.java | 34 ++- .../cloud/baremetal/manager/BaremetalRct.java | 108 +++++++ .../manager/BaremetalVlanManager.java | 13 + .../manager/BaremetalVlanManagerImpl.java | 71 +++++ .../networkservice/BareMetalResourceBase.java | 171 ++++++++---- .../networkservice/BaremetaNetworkGuru.java | 6 +- .../BaremetalDhcpdResource.java | 2 +- .../networkservice/BaremetalPxeElement.java | 19 +- .../BaremetalPxeManagerImpl.java | 2 +- .../networkservice/BaremetalRctResponse.java | 35 +++ .../SecurityGroupHttpClient.java | 243 +++++++++++++--- .../networkservice/schema/ObjectFactory.java | 55 ++++ .../schema/SecurityGroupRule.java | 146 ++++++++++ .../schema/SecurityGroupVmRuleSet.java | 263 ++++++++++++++++++ .../cloudstack/api/AddBaremetalRctCmd.java | 68 +++++ 30 files changed, 1273 insertions(+), 200 deletions(-) create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java create mode 100755 plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index b75619557c..8f1237e480 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -21,17 +21,17 @@ org.apache.cloudstack cloudstack-plugins - 4.5.0-SNAPSHOT + 4.4.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal Apache CloudStack Plugin - Hypervisor Baremetal - - commons-lang - commons-lang - 2.6 - + + commons-lang + commons-lang + 2.6 + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml index cce6805123..d0b52a1bb0 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml @@ -31,5 +31,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml index 8792909ffe..c01d9c62af 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml index 40d9f50577..c5068e7b14 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml @@ -42,5 +42,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml index 8c14c3e290..046aca67e8 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml index 11cc6c89e3..e1a21bc059 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml @@ -28,6 +28,7 @@ > + @@ -38,5 +39,6 @@ - + + diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent index 02426d0aa1..f8a5d7d2c9 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent @@ -18,9 +18,9 @@ # 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 @@ -29,31 +29,31 @@ # under the License. check_status() { - pidfile='/var/run/cssgagent.pid' - if [ ! -f $pidfile ]; then - echo "cloudstack baremetal security group agent is stopped" - exit 1 - else - pid=`cat $pidfile` - ps -p $pid > /dev/null - if [ $? -eq 0 ]; then - echo "cloudstack baremetal security group agent is running, pid is $pid" - exit 0 - else - echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" - exit 1 - fi - fi + pidfile='/var/run/cssgagent.pid' + if [ ! -f $pidfile ]; then + echo "cloudstack baremetal security group agent is stopped" + exit 1 + else + pid=`cat $pidfile` + ps -p $pid > /dev/null + if [ $? -eq 0 ]; then + echo "cloudstack baremetal security group agent is running, pid is $pid" + exit 0 + else + echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" + exit 1 + fi + fi } if [ $# -eq 0 ]; then - echo "usage: $0 + echo "usage: $0 [start|stop|restart|status]" - exit 1 + exit 1 fi if [ "$@" = "status" ]; then - check_status + check_status else python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@ fi diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py index f7f5f60ff0..76bd5c1b21 100644 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py @@ -5,14 +5,14 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py index a292c0bcfb..0c49a3f786 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Jan 2, 2013 @@ -234,4 +234,3 @@ def main(): agentdaemon.restart() sys.exit(0) - \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py index bf64effa19..bc675b540a 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py @@ -6,16 +6,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 import sys, os, time, atexit @@ -31,7 +31,7 @@ def __init__(self): self.body = None self.method = None self.query_string = None - + @staticmethod def from_cherrypy_request(creq): req = Request() @@ -40,10 +40,10 @@ def from_cherrypy_request(creq): req.method = copy.copy(creq.method) req.query_string = copy.copy(creq.query_string) if creq.query_string else None return req - + class ShellError(Exception): '''shell error''' - + class ShellCmd(object): ''' classdocs @@ -57,11 +57,11 @@ def __init__(self, cmd, workdir=None, pipe=True): self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/sh', cwd=workdir) else: self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir) - + self.stdout = None self.stderr = None self.return_code = None - + def __call__(self, is_exception=True): (self.stdout, self.stderr) = self.process.communicate() if is_exception and self.process.returncode != 0: @@ -71,18 +71,18 @@ def __call__(self, is_exception=True): err.append('stdout: %s' % self.stdout) err.append('stderr: %s' % self.stderr) raise ShellError('\n'.join(err)) - + self.return_code = self.process.returncode return self.stdout class Daemon(object): """ A generic daemon class. - + Usage: subclass the Daemon class and override the run() method """ atexit_hooks = [] - + def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin self.stdout = stdout @@ -102,37 +102,37 @@ def _atexit(): content = traceback.format_exc() err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content) #logger.error(err) - + def daemonize(self): """ - do the UNIX double-fork magic, see Stevens' "Advanced + do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit first parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) - + # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - + os.chdir("/") + os.setsid() + os.umask(0) + # do second fork - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit from second parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) - sys.exit(1) - + sys.exit(1) + # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() @@ -142,13 +142,13 @@ def daemonize(self): os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) - + # write pidfile Daemon.register_atexit_hook(self.delpid) atexit.register(Daemon._atexit) pid = str(os.getpid()) file(self.pidfile,'w').write("%s\n" % pid) - + def delpid(self): os.remove(self.pidfile) @@ -163,7 +163,7 @@ def start(self): pf.close() except IOError: pid = None - + if pid: pscmd = ShellCmd('ps -p %s > /dev/null' % pid) pscmd(is_exception=False) @@ -171,7 +171,7 @@ def start(self): message = "Daemon already running, pid is %s\n" sys.stderr.write(message % pid) sys.exit(0) - + # Start the daemon self.daemonize() try: @@ -192,13 +192,13 @@ def stop(self): pf.close() except IOError: pid = None - + if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py index cb66d265a5..175349958c 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Dec 25, 2012 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py index 384e04d6a9..ed106313ff 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 from setuptools import setup, find_packages import sys, os diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java new file mode 100755 index 0000000000..fee2d71724 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java @@ -0,0 +1,9 @@ +package com.cloud.baremetal.database; + +import com.cloud.utils.db.GenericDao; + +/** + * Created by frank on 5/8/14. + */ +public interface BaremetalRctDao extends GenericDao { +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java new file mode 100755 index 0000000000..89df902e6c --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java @@ -0,0 +1,9 @@ +package com.cloud.baremetal.database; + +import com.cloud.utils.db.GenericDaoBase; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRctDaoImpl extends GenericDaoBase implements BaremetalRctDao { +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java new file mode 100755 index 0000000000..ae1f794aab --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java @@ -0,0 +1,62 @@ +package com.cloud.baremetal.database; + +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 java.util.UUID; + +/** + * Created by frank on 5/8/14. + */ +@Entity +@Table(name = "baremetal_rct") +public class BaremetalRctVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "uuid") + private String uuid = UUID.randomUUID().toString(); + + @Column(name = "url") + private String url; + + @Column(name = "rct") + private String rct; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRct() { + return rct; + } + + public void setRct(String rct) { + this.rct = rct; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java index c312df7b79..8b4b45348f 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java @@ -80,8 +80,8 @@ public boolean stop() { } @Override - public Map> - find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { + public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) + throws DiscoveryException { /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME); @@ -130,18 +130,18 @@ public boolean stop() { String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { - throw new CloudRuntimeException("Unable to find key ipmi script " + injectScript); + throw new CloudRuntimeException("Unable to find key ipmi script " + + injectScript); } final Script2 command = new Script2(scriptPath, s_logger); command.add("ping"); - command.add("hostname=" + ipmiIp); - command.add("usrname=" + username); - command.add("password=" + password, ParamType.PASSWORD); + command.add("hostname="+ipmiIp); + command.add("usrname="+username); + command.add("password="+password, ParamType.PASSWORD); final String result = command.execute(); if (result != null) { - s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", - result)); + s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", result)); return null; } @@ -155,21 +155,22 @@ public boolean stop() { params.putAll(_params); params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); - params.put("cluster", Long.toString(clusterId)); + params.put("cluster", Long.toString(clusterId)); params.put("guid", guid); params.put(ApiConstants.PRIVATE_IP, ipmiIp); params.put(ApiConstants.USERNAME, username); params.put(ApiConstants.PASSWORD, password); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key()); BareMetalResourceBase resource = null; if (resourceClassName != null) { Class clazz = Class.forName(resourceClassName); - resource = (BareMetalResourceBase)clazz.newInstance(); + resource = (BareMetalResourceBase) clazz.newInstance(); String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key()); if (externalUrl == null) { - throw new IllegalArgumentException( - String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); + throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); } details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl); } else { @@ -206,8 +207,8 @@ public boolean stop() { zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName()); _dcDao.update(zone.getId(), zone); - s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," - + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); + s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," + + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); return resources; } catch (Exception e) { s_logger.warn("Can not set up bare metal agent", e); @@ -217,7 +218,8 @@ public boolean stop() { } @Override - public void postDiscovery(List hosts, long msId) throws DiscoveryException { + public void postDiscovery(List hosts, long msId) + throws DiscoveryException { } @Override @@ -273,6 +275,8 @@ protected HashMap buildConfigParams(HostVO host) { HashMap params = super.buildConfigParams(host); params.put("hostId", host.getId()); params.put("ipaddress", host.getPrivateIpAddress()); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); return params; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java new file mode 100755 index 0000000000..796023e7ff --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java @@ -0,0 +1,108 @@ +package com.cloud.baremetal.manager; + +import java.util.List; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRct { + public static class SwitchEntry { + private String ip; + private String username; + private String password; + private String type; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + + public static class HostEntry { + private String uuid; + private String mac; + private int port; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + } + + public static class Rack { + private SwitchEntry l2Switch; + private List hosts; + + public SwitchEntry getL2Switch() { + return l2Switch; + } + + public void setL2Switch(SwitchEntry l2Switch) { + this.l2Switch = l2Switch; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + } + + private List racks; + + public List getRacks() { + return racks; + } + + public void setRacks(List racks) { + this.racks = racks; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java new file mode 100755 index 0000000000..8b57eb4032 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java @@ -0,0 +1,13 @@ +package com.cloud.baremetal.manager; + +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.PluggableService; +import org.apache.cloudstack.api.AddBaremetalRctCmd; + +/** + * Created by frank on 4/30/14. + */ +public interface BaremetalVlanManager extends Manager, PluggableService { + BaremetalRctResponse addRct(AddBaremetalRctCmd cmd); +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java new file mode 100755 index 0000000000..5bb59a2edb --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java @@ -0,0 +1,71 @@ +package com.cloud.baremetal.manager; + +import com.cloud.baremetal.database.BaremetalRctDao; +import com.cloud.baremetal.database.BaremetalRctVO; +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.google.gson.Gson; +import org.apache.cloudstack.api.AddBaremetalRctCmd; +import org.springframework.web.client.RestTemplate; + +import javax.inject.Inject; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager { + private Gson gson = new Gson(); + + @Inject + private BaremetalRctDao rctDao; + + @Override + public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) { + try { + URL url = new URL(cmd.getRctUrl()); + RestTemplate rest = new RestTemplate(); + String rctStr = rest.getForObject(url.toString(), String.class); + + // validate it's right format + BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class); + QueryBuilder sc = QueryBuilder.create(BaremetalRctVO.class); + sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl()); + BaremetalRctVO vo = sc.find(); + if (vo == null) { + vo = new BaremetalRctVO(); + vo.setRct(gson.toJson(rct)); + vo.setUrl(cmd.getRctUrl()); + vo = rctDao.persist(vo); + } else { + vo.setRct(gson.toJson(rct)); + rctDao.update(vo.getId(), vo); + } + + BaremetalRctResponse rsp = new BaremetalRctResponse(); + rsp.setUrl(vo.getUrl()); + rsp.setId(vo.getUuid()); + return rsp; + } catch (MalformedURLException e) { + throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl())); + } + } + + @Override + public String getName() { + return "Baremetal Vlan Manager"; + } + + + @Override + public List> getCommands() { + List> cmds = new ArrayList>(); + cmds.add(AddBaremetalRctCmd.class); + return cmds; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java index b729d9bb3e..828533708e 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -22,18 +22,6 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.baremetal.networkservice; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.ApiConstants; - import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckNetworkAnswer; @@ -48,6 +36,7 @@ import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyAnswer; @@ -66,10 +55,11 @@ import com.cloud.agent.api.baremetal.IpmiBootorResetCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.baremetal.manager.BaremetalManager; +import com.cloud.configuration.Config; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.resource.ServerResource; -import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; @@ -81,6 +71,16 @@ import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; @Local(value = ServerResource.class) public class BareMetalResourceBase extends ManagerBase implements ServerResource { @@ -111,6 +111,9 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource protected Script2 _forcePowerOffCommand; protected Script2 _bootOrRebootCommand; protected String _vmName; + protected int ipmiRetryTimes = 5; + + protected ConfigurationDao configDao; protected VMInstanceDao vmDao; private void changeVmState(String vmName, VirtualMachine.State state) { @@ -128,27 +131,29 @@ private State removeVmState(String vmName) { @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; - _uuid = (String)params.get("guid"); + _uuid = (String) params.get("guid"); try { - _memCapacity = Long.parseLong((String)params.get(ApiConstants.MEMORY)) * 1024L * 1024L; - _cpuCapacity = Long.parseLong((String)params.get(ApiConstants.CPU_SPEED)); - _cpuNum = Long.parseLong((String)params.get(ApiConstants.CPU_NUMBER)); + _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L; + _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED)); + _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER)); } catch (NumberFormatException e) { throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity " - + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), params.get(ApiConstants.MEMORY), - params.get(ApiConstants.CPU_SPEED))); + + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), + params.get(ApiConstants.MEMORY), params.get(ApiConstants.CPU_SPEED))); } - _zone = (String)params.get("zone"); - _pod = (String)params.get("pod"); - _cluster = (String)params.get("cluster"); - hostId = (Long)params.get("hostId"); - _ip = (String)params.get(ApiConstants.PRIVATE_IP); - _mac = (String)params.get(ApiConstants.HOST_MAC); - _username = (String)params.get(ApiConstants.USERNAME); - _password = (String)params.get(ApiConstants.PASSWORD); - _vmName = (String)params.get("vmName"); - String echoScAgent = (String)params.get(BaremetalManager.EchoSecurityGroupAgent); + _zone = (String) params.get("zone"); + _pod = (String) params.get("pod"); + _cluster = (String) params.get("cluster"); + hostId = (Long) params.get("hostId"); + _ip = (String) params.get(ApiConstants.PRIVATE_IP); + _mac = (String) params.get(ApiConstants.HOST_MAC); + _username = (String) params.get(ApiConstants.USERNAME); + _password = (String) params.get(ApiConstants.PASSWORD); + _vmName = (String) params.get("vmName"); + String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent); + vmDao = (VMInstanceDao) params.get("vmDao"); + configDao = (ConfigurationDao) params.get("configDao"); if (_pod == null) { throw new ConfigurationException("Unable to get the pod"); @@ -167,7 +172,8 @@ public boolean configure(String name, Map params) throws Configu } if (_mac.split(":").length != 6) { - throw new ConfigurationException("Wrong MAC format(" + _mac + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); + throw new ConfigurationException("Wrong MAC format(" + _mac + + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); } if (_uuid == null) { @@ -178,6 +184,19 @@ public boolean configure(String name, Map params) throws Configu _isEchoScAgent = Boolean.valueOf(echoScAgent); } + String ipmiIface = "default"; + try { + ipmiIface = configDao.getValue(Config.BaremetalIpmiLanInterface.key()); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + + try { + ipmiRetryTimes = Integer.valueOf(configDao.getValue(Config.BaremetalIpmiRetryTimes.key())); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { @@ -187,6 +206,7 @@ public boolean configure(String name, Map params) throws Configu _pingCommand = new Script2(pythonPath, s_logger); _pingCommand.add(scriptPath); _pingCommand.add("ping"); + _pingCommand.add("interface=" + ipmiIface); _pingCommand.add("hostname=" + _ip); _pingCommand.add("usrname=" + _username); _pingCommand.add("password=" + _password, ParamType.PASSWORD); @@ -194,6 +214,7 @@ public boolean configure(String name, Map params) throws Configu _setPxeBootCommand = new Script2(pythonPath, s_logger); _setPxeBootCommand.add(scriptPath); _setPxeBootCommand.add("boot_dev"); + _setPxeBootCommand.add("interface=" + ipmiIface); _setPxeBootCommand.add("hostname=" + _ip); _setPxeBootCommand.add("usrname=" + _username); _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -202,6 +223,7 @@ public boolean configure(String name, Map params) throws Configu _setDiskBootCommand = new Script2(pythonPath, s_logger); _setDiskBootCommand.add(scriptPath); _setDiskBootCommand.add("boot_dev"); + _setDiskBootCommand.add("interface=" + ipmiIface); _setDiskBootCommand.add("hostname=" + _ip); _setDiskBootCommand.add("usrname=" + _username); _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -210,6 +232,7 @@ public boolean configure(String name, Map params) throws Configu _rebootCommand = new Script2(pythonPath, s_logger); _rebootCommand.add(scriptPath); _rebootCommand.add("reboot"); + _rebootCommand.add("interface=" + ipmiIface); _rebootCommand.add("hostname=" + _ip); _rebootCommand.add("usrname=" + _username); _rebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -217,6 +240,7 @@ public boolean configure(String name, Map params) throws Configu _getStatusCommand = new Script2(pythonPath, s_logger); _getStatusCommand.add(scriptPath); _getStatusCommand.add("ping"); + _getStatusCommand.add("interface=" + ipmiIface); _getStatusCommand.add("hostname=" + _ip); _getStatusCommand.add("usrname=" + _username); _getStatusCommand.add("password=" + _password, ParamType.PASSWORD); @@ -224,6 +248,7 @@ public boolean configure(String name, Map params) throws Configu _powerOnCommand = new Script2(pythonPath, s_logger); _powerOnCommand.add(scriptPath); _powerOnCommand.add("power"); + _powerOnCommand.add("interface=" + ipmiIface); _powerOnCommand.add("hostname=" + _ip); _powerOnCommand.add("usrname=" + _username); _powerOnCommand.add("password=" + _password, ParamType.PASSWORD); @@ -232,6 +257,7 @@ public boolean configure(String name, Map params) throws Configu _powerOffCommand = new Script2(pythonPath, s_logger); _powerOffCommand.add(scriptPath); _powerOffCommand.add("power"); + _powerOffCommand.add("interface=" + ipmiIface); _powerOffCommand.add("hostname=" + _ip); _powerOffCommand.add("usrname=" + _username); _powerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -240,6 +266,7 @@ public boolean configure(String name, Map params) throws Configu _forcePowerOffCommand = new Script2(pythonPath, s_logger); _forcePowerOffCommand.add(scriptPath); _forcePowerOffCommand.add("power"); + _forcePowerOffCommand.add("interface=" + ipmiIface); _forcePowerOffCommand.add("hostname=" + _ip); _forcePowerOffCommand.add("usrname=" + _username); _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -248,6 +275,7 @@ public boolean configure(String name, Map params) throws Configu _bootOrRebootCommand = new Script2(pythonPath, s_logger); _bootOrRebootCommand.add(scriptPath); _bootOrRebootCommand.add("boot_or_reboot"); + _bootOrRebootCommand.add("interface=" + ipmiIface); _bootOrRebootCommand.add("hostname=" + _ip); _bootOrRebootCommand.add("usrname=" + _username); _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -259,8 +287,15 @@ protected boolean doScript(Script cmd) { return doScript(cmd, null); } + protected boolean doScript(Script cmd, int retry) { + return doScript(cmd, null, retry); + } + protected boolean doScript(Script cmd, OutputInterpreter interpreter) { - int retry = 5; + return doScript(cmd, interpreter, ipmiRetryTimes); + } + + protected boolean doScript(Script cmd, OutputInterpreter interpreter, int retry) { String res = null; while (retry-- > 0) { if (interpreter == null) { @@ -270,6 +305,10 @@ protected boolean doScript(Script cmd, OutputInterpreter interpreter) { } if (res != null && res.startsWith("Error: Unable to establish LAN")) { s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times"); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + } continue; } else if (res == null) { return true; @@ -318,7 +357,6 @@ protected State getVmState() { protected Map fullSync() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { states.put(vm.getInstanceName(), vm.getState()); @@ -337,10 +375,14 @@ protected Map fullSync() { protected Map getHostVmStateReport() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { - states.put(vm.getInstanceName(), new HostVmStateReportEntry(vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId)); + states.put( + vm.getInstanceName(), + new HostVmStateReportEntry( + vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId + ) + ); } } /* @@ -355,7 +397,8 @@ protected Map getHostVmStateReport() { @Override public StartupCommand[] initialize() { - StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, new HashMap(), null, null); + StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, + new HashMap(), null, null); cmd.setDataCenter(_zone); cmd.setPod(_pod); @@ -365,13 +408,13 @@ public StartupCommand[] initialize() { cmd.setPrivateIpAddress(_ip); cmd.setStorageIpAddress(_ip); cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion()); - cmd.setCpus((int)_cpuNum); + cmd.setCpus((int) _cpuNum); cmd.setSpeed(_cpuCapacity); cmd.setMemory(_memCapacity); cmd.setPrivateMacAddress(_mac); cmd.setPublicMacAddress(_mac); cmd.setStateChanges(fullSync()); - return new StartupCommand[] {cmd}; + return new StartupCommand[] { cmd }; } private boolean ipmiPing() { @@ -393,7 +436,19 @@ public PingCommand getCurrentStatus(long id) { return null; } - return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + if (hostId != null) { + final List vms = vmDao.listByHostId(hostId); + if (vms.isEmpty()) { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } else { + VMInstanceVO vm = vms.get(0); + SecurityGroupHttpClient client = new SecurityGroupHttpClient(); + HashMap> nwGrpStates = client.sync(vm.getInstanceName(), vm.getId(), vm.getPrivateIpAddress()); + return new PingRoutingWithNwGroupsCommand(getType(), id, null, getHostVmStateReport(), nwGrpStates); + } + } else { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } } protected Answer execute(IpmISetBootDevCommand cmd) { @@ -456,29 +511,29 @@ protected Answer execute(SecurityGroupRulesCmd cmd) { public Answer executeRequest(Command cmd) { try { if (cmd instanceof ReadyCommand) { - return execute((ReadyCommand)cmd); + return execute((ReadyCommand) cmd); } else if (cmd instanceof StartCommand) { - return execute((StartCommand)cmd); + return execute((StartCommand) cmd); } else if (cmd instanceof StopCommand) { - return execute((StopCommand)cmd); + return execute((StopCommand) cmd); } else if (cmd instanceof RebootCommand) { - return execute((RebootCommand)cmd); + return execute((RebootCommand) cmd); } else if (cmd instanceof IpmISetBootDevCommand) { - return execute((IpmISetBootDevCommand)cmd); + return execute((IpmISetBootDevCommand) cmd); } else if (cmd instanceof MaintainCommand) { - return execute((MaintainCommand)cmd); + return execute((MaintainCommand) cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return execute((PrepareForMigrationCommand)cmd); + return execute((PrepareForMigrationCommand) cmd); } else if (cmd instanceof MigrateCommand) { - return execute((MigrateCommand)cmd); + return execute((MigrateCommand) cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return execute((CheckVirtualMachineCommand)cmd); + return execute((CheckVirtualMachineCommand) cmd); } else if (cmd instanceof IpmiBootorResetCommand) { - return execute((IpmiBootorResetCommand)cmd); + return execute((IpmiBootorResetCommand) cmd); } else if (cmd instanceof SecurityGroupRulesCmd) { - return execute((SecurityGroupRulesCmd)cmd); + return execute((SecurityGroupRulesCmd) cmd); } else if (cmd instanceof CheckNetworkCommand) { - return execute((CheckNetworkCommand)cmd); + return execute((CheckNetworkCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -499,8 +554,17 @@ protected boolean isPowerOn(String str) { } protected RebootAnswer execute(final RebootCommand cmd) { - if (!doScript(_rebootCommand)) { - return new RebootAnswer(cmd, "IPMI reboot failed", false); + String infoStr = "Command not supported in present state"; + OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); + if (!doScript(_rebootCommand, interpreter, 10)) { + if (interpreter.getLines().contains(infoStr)) { + // try again, this error should be temporary + if (!doScript(_rebootCommand, interpreter, 10)) { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } + } else { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } } return new RebootAnswer(cmd, "reboot succeeded", true); @@ -524,7 +588,8 @@ protected StopAnswer execute(final StopCommand cmd) { OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); if (!doScript(_getStatusCommand, interpreter)) { - s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed"); + success = true; + s_logger.warn("Cannot get power status of " + _name + ", assume VM state changed successfully"); break; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java index 596b84ead2..808c61ecb6 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java @@ -37,7 +37,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -81,7 +81,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException { + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { if (dest.getHost().getHypervisorType() != HypervisorType.BareMetal) { super.reserve(nic, network, vm, dest, context); return; @@ -153,7 +153,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { s_logger.debug("Allocated a nic " + nic + " for " + vm); } - private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientVirtualNetworkCapacityException, + private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(pod.getDataCenterId()); if (nic.getIp4Address() == null) { diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java index 8e43d0c3c5..aab936ce20 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java @@ -93,7 +93,7 @@ public boolean configure(String name, Map params) throws Configu s_logger.debug("Dhcpd resource configure successfully"); return true; } catch (Exception e) { - s_logger.debug("Dhcpd resorce configure failed", e); + s_logger.debug("Dhcpd resource configure failed", e); throw new ConfigurationException(e.getMessage()); } finally { SSHCmdHelper.releaseSshConnection(sshConnection); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java index 5da52a5c73..d5a7188cc9 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java @@ -18,17 +18,7 @@ // Automatically generated by addcopyright.py at 01/29/2013 package com.cloud.baremetal.networkservice; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.log4j.Logger; - import com.cloud.baremetal.database.BaremetalPxeVO; -import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Pod; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -57,6 +47,13 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; @Local(value = NetworkElement.class) public class BaremetalPxeElement extends AdapterBase implements NetworkElement { @@ -90,7 +87,7 @@ public Provider getProvider() { private boolean canHandle(DeployDestination dest, TrafficType trafficType, GuestType networkType) { Pod pod = dest.getPod(); - if (pod != null && dest.getDataCenter().getNetworkType() == NetworkType.Basic && trafficType == TrafficType.Guest) { + if (pod != null && trafficType == TrafficType.Guest) { QueryBuilder sc = QueryBuilder.create(BaremetalPxeVO.class); sc.and(sc.entity().getPodId(), Op.EQ, pod.getId()); return sc.find() != null; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index ca2f8fe703..261534a3dd 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -193,7 +193,7 @@ public List listPxeServers(ListBaremetalPxeServersCmd cmd) @Override public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) { - UserVmVO vm = (UserVmVO)profile.getVirtualMachine(); + UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId()); _vmDao.loadDetails(vm); String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java new file mode 100755 index 0000000000..837c615292 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java @@ -0,0 +1,35 @@ +package com.cloud.baremetal.networkservice; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRctResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) + @Param(description = "id of rct") + private String id; + + @SerializedName(ApiConstants.URL) + @Param(description = "url") + private String url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java index a3998a3bc7..b9e4858895 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java @@ -1,38 +1,205 @@ -// 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. -// -// Automatically generated by addcopyright.py at 01/29/2013 -// Apache License, Version 2.0 (the "License"); you may not use this -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -package com.cloud.baremetal.networkservice; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.SecurityGroupRulesCmd; - -public class SecurityGroupHttpClient { - - public Answer call(String guestIp, SecurityGroupRulesCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - public boolean echo(String ip, long millis, long millis2) { - // TODO Auto-generated method stub - return false; - } - -} +// 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. +// +// Automatically generated by addcopyright.py at 01/29/2013 +// Apache License, Version 2.0 (the "License"); you may not use this +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// Automatically generated by addcopyright.py at 04/03/2012 + +package com.cloud.baremetal.networkservice; + +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; +import com.cloud.baremetal.networkservice.schema.SecurityGroupRule; +import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.log4j.Logger; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import java.io.StringWriter; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class SecurityGroupHttpClient { + private static final Logger logger = Logger.getLogger(SecurityGroupHttpClient.class); + private static final String ARG_NAME = "args"; + private static final String COMMAND = "command"; + private JAXBContext context; + private int port; + private static HttpClient httpClient; + static { + MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager(); + httpClient = new HttpClient(connman); + httpClient.setConnectionTimeout(5000); + } + + private enum OpConstant { + setRules, echo, + } + + public SecurityGroupHttpClient() { + try { + context = JAXBContext.newInstance(SecurityGroupRule.class, SecurityGroupVmRuleSet.class); + port = 9988; + } catch (Exception e) { + throw new CloudRuntimeException( + "Unable to create JAXBContext for security group", e); + } + } + + private List generateRules(IpPortAndProto[] ipps) { + List rules = new ArrayList( + ipps.length); + for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) { + SecurityGroupRule r = new SecurityGroupRule(); + r.setProtocol(ipp.getProto()); + r.setStartPort(ipp.getStartPort()); + r.setEndPort(ipp.getEndPort()); + for (String cidr : ipp.getAllowedCidrs()) { + r.getIp().add(cidr); + } + rules.add(r); + } + return rules; + } + + public HashMap> sync(String vmName, Long vmId, String agentIp) { + HashMap> states = new HashMap>(); + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "sync"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + String res = post.getResponseBodyAsString(); + // res = ';'.join([vmName, vmId, seqno]) + String[] rulelogs = res.split(","); + if (rulelogs.length != 6) { + logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res)); + states.put(vmName, new Pair(vmId, -1L)); + return states; + } + Pair p = new Pair(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5])); + states.put(rulelogs[0], p); + return states; + } + } catch (SocketTimeoutException se) { + logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage())); + } catch (Exception e) { + logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + return states; + } + + + public boolean echo(String agentIp, long l, long m) { + boolean ret = false; + int count = 1; + while (true) { + try { + Thread.sleep(m); + count++; + } catch (InterruptedException e1) { + logger.warn("", e1); + break; + } + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "echo"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + ret = true; + } + break; + } catch (Exception e) { + if (count*m >= l) { + logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count)); + break; + } else { + logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count)); + } + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + return ret; + } + + public SecurityGroupRuleAnswer call(String agentIp, SecurityGroupRulesCmd cmd) { + PostMethod post = new PostMethod(String.format( + "http://%s:%s", agentIp, getPort())); + try { + SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet(); + rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet())); + rset.getIngressRules().addAll( + generateRules(cmd.getIngressRuleSet())); + rset.setVmName(cmd.getVmName()); + rset.setVmIp(cmd.getGuestIp()); + rset.setVmMac(cmd.getGuestMac()); + rset.setVmId(cmd.getVmId()); + rset.setSignature(cmd.getSignature()); + rset.setSequenceNumber(cmd.getSeqNum()); + Marshaller marshaller = context.createMarshaller(); + StringWriter writer = new StringWriter(); + marshaller.marshal(rset, writer); + String xmlContents = writer.toString(); + logger.debug(xmlContents); + + post.addRequestHeader("command", "set_rules"); + StringRequestEntity entity = new StringRequestEntity(xmlContents); + post.setRequestEntity(entity); + if (httpClient.executeMethod(post) != 200) { + return new SecurityGroupRuleAnswer(cmd, false, + post.getResponseBodyAsString()); + } else { + return new SecurityGroupRuleAnswer(cmd); + } + } catch (Exception e) { + return new SecurityGroupRuleAnswer(cmd, false, e.getMessage()); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java new file mode 100644 index 0000000000..b5bc694516 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java @@ -0,0 +1,55 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.cloud.network.security.schema package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.cloud.network.security.schema + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link SecurityGroupRule } + * + */ + public SecurityGroupRule createSecurityGroupRule() { + return new SecurityGroupRule(); + } + + /** + * Create an instance of {@link SecurityGroupVmRuleSet } + * + */ + public SecurityGroupVmRuleSet createSecurityGroupVmRuleSet() { + return new SecurityGroupVmRuleSet(); + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java new file mode 100644 index 0000000000..050c3fdee7 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java @@ -0,0 +1,146 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for SecurityGroupRule complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="SecurityGroupRule">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="startPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <element name="endPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ip" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SecurityGroupRule", propOrder = { + "protocol", + "startPort", + "endPort", + "ip" +}) +public class SecurityGroupRule { + + @XmlElement(required = true) + protected String protocol; + @XmlSchemaType(name = "unsignedInt") + protected long startPort; + @XmlSchemaType(name = "unsignedInt") + protected long endPort; + protected List ip; + + /** + * Gets the value of the protocol property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProtocol() { + return protocol; + } + + /** + * Sets the value of the protocol property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProtocol(String value) { + this.protocol = value; + } + + /** + * Gets the value of the startPort property. + * + */ + public long getStartPort() { + return startPort; + } + + /** + * Sets the value of the startPort property. + * + */ + public void setStartPort(long value) { + this.startPort = value; + } + + /** + * Gets the value of the endPort property. + * + */ + public long getEndPort() { + return endPort; + } + + /** + * Sets the value of the endPort property. + * + */ + public void setEndPort(long value) { + this.endPort = value; + } + + /** + * Gets the value of the ip property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ip property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIp().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getIp() { + if (ip == null) { + ip = new ArrayList(); + } + return this.ip; + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java new file mode 100644 index 0000000000..2c50c0e24d --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java @@ -0,0 +1,263 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="vmName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmId" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <element name="vmIp" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmMac" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="signature" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="sequenceNumber" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ingressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="egressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "vmName", + "vmId", + "vmIp", + "vmMac", + "signature", + "sequenceNumber", + "ingressRules", + "egressRules" +}) +@XmlRootElement(name = "SecurityGroupVmRuleSet") +public class SecurityGroupVmRuleSet { + + @XmlElement(required = true) + protected String vmName; + protected long vmId; + @XmlElement(required = true) + protected String vmIp; + @XmlElement(required = true) + protected String vmMac; + @XmlElement(required = true) + protected String signature; + protected long sequenceNumber; + protected List ingressRules; + protected List egressRules; + + /** + * Gets the value of the vmName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmName() { + return vmName; + } + + /** + * Sets the value of the vmName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmName(String value) { + this.vmName = value; + } + + /** + * Gets the value of the vmId property. + * + */ + public long getVmId() { + return vmId; + } + + /** + * Sets the value of the vmId property. + * + */ + public void setVmId(long value) { + this.vmId = value; + } + + /** + * Gets the value of the vmIp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmIp() { + return vmIp; + } + + /** + * Sets the value of the vmIp property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmIp(String value) { + this.vmIp = value; + } + + /** + * Gets the value of the vmMac property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmMac() { + return vmMac; + } + + /** + * Sets the value of the vmMac property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmMac(String value) { + this.vmMac = value; + } + + /** + * Gets the value of the signature property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSignature() { + return signature; + } + + /** + * Sets the value of the signature property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSignature(String value) { + this.signature = value; + } + + /** + * Gets the value of the sequenceNumber property. + * + */ + public long getSequenceNumber() { + return sequenceNumber; + } + + /** + * Sets the value of the sequenceNumber property. + * + */ + public void setSequenceNumber(long value) { + this.sequenceNumber = value; + } + + /** + * Gets the value of the ingressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ingressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIngressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getIngressRules() { + if (ingressRules == null) { + ingressRules = new ArrayList(); + } + return this.ingressRules; + } + + /** + * Gets the value of the egressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the egressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getEgressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getEgressRules() { + if (egressRules == null) { + egressRules = new ArrayList(); + } + return this.egressRules; + } + +} diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java new file mode 100755 index 0000000000..554e2ec378 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java @@ -0,0 +1,68 @@ +package org.apache.cloudstack.api; + +import com.cloud.baremetal.manager.BaremetalVlanManager; +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +import javax.inject.Inject; + +/** + * Created by frank on 5/8/14. + */ +@APICommand(name = "addBaremetalRct", description = "adds baremetal rack configuration text", responseObject = BaremetalRctResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class AddBaremetalRctCmd extends BaseAsyncCmd { + private static final String s_name = "addbaremetalrctresponse"; + public static final Logger s_logger = Logger.getLogger(AddBaremetalRctCmd.class); + + @Inject + private BaremetalVlanManager vlanMgr; + + @Parameter(name=ApiConstants.BAREMETAL_RCT_URL, required = true, description = "http url to baremetal RCT configuration") + private String rctUrl; + + public String getRctUrl() { + return rctUrl; + } + + public void setRctUrl(String rctUrl) { + this.rctUrl = rctUrl; + } + + public String getEventType() { + return EventTypes.EVENT_BAREMETAL_RCT_ADD; + } + + @Override + public String getEventDescription() { + return "Adding baremetal rct configuration"; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + try { + BaremetalRctResponse rsp = vlanMgr.addRct(this); + this.setResponseObject(rsp); + } catch (Exception e) { + s_logger.warn(String.format("unable to add baremetal RCT[%s]", getRctUrl()), e); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } +} From 3ddc9e7674c4a12b0e12ca51bb8795dcff5de974 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 11:40:21 -0700 Subject: [PATCH 018/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- .../src/com/cloud/configuration/Config.java | 8 ++++++++ .../VirtualNetworkApplianceManagerImpl.java | 20 ++++++++++++++++++- .../src/com/cloud/utils/fsm/StateObject.java | 4 ++-- 3 files changed, 29 insertions(+), 3 deletions(-) mode change 100644 => 100755 utils/src/com/cloud/utils/fsm/StateObject.java diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 196db9306e..7863001f4b 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -1761,6 +1761,14 @@ public enum Config { "The maximum number of retrying times to search for an available IPv6 address in the table", null), + BaremetalPeerHypervisorType( + "Advanced", + ManagementServer.class, + String.class, + "baremetal.peer.hypervisor.type", + "XenServer", + "Hypervisor[Xenserver/KVM/VMWare] used to spring up virtual router for baremetal instances. The cluster having this hypervisor type must be in the same zone with baremetal cluster", + null), ExternalBaremetalSystemUrl( "Advanced", ManagementServer.class, diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 1068a2f4d8..d8e3761464 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1738,7 +1738,7 @@ protected DomainRouterVO deployRouter(final Account owner, final DeployDestinati int startRetry = 0; DomainRouterVO router = null; for (final Iterator iter = hypervisors.iterator(); iter.hasNext();) { - final HypervisorType hType = iter.next(); + HypervisorType hType = iter.next(); try { final long id = _routerDao.getNextInSequence(Long.class, "id"); if (s_logger.isDebugEnabled()) { @@ -1762,6 +1762,24 @@ protected DomainRouterVO deployRouter(final Account owner, final DeployDestinati case LXC: templateName = RouterTemplateLxc.valueIn(dest.getDataCenter().getId()); break; + case BareMetal: + String peerHvType = _configDao.getValue(Config.BaremetalPeerHypervisorType.key()); + if (peerHvType == null) { + throw new CloudRuntimeException(String.format("To use baremetal in advanced networking, you must set %s to type of hypervisor(e.g XenServer)" + + " that exists in the same zone with baremetal host. That hyperivsor is used to spring up virtual router for baremetal instance", Config.BaremetalPeerHypervisorType.key())); + } + + hType = HypervisorType.getType(peerHvType); + if (HypervisorType.XenServer.toString().equals(peerHvType)) { + templateName = RouterTemplateXen.valueIn(dest.getDataCenter().getId()); + } else if (HypervisorType.KVM.toString().equals(peerHvType)) { + templateName = RouterTemplateKvm.valueIn(dest.getDataCenter().getId()); + } else if (HypervisorType.VMware.toString().equals(peerHvType)) { + templateName = RouterTemplateVmware.valueIn(dest.getDataCenter().getId()); + } else { + throw new CloudRuntimeException(String.format("Baremetal only supports peer hypervisor(XenServer/KVM/VMWare) right now, you specified %s", peerHvType)); + } + break; default: break; } diff --git a/utils/src/com/cloud/utils/fsm/StateObject.java b/utils/src/com/cloud/utils/fsm/StateObject.java old mode 100644 new mode 100755 index 4ee4dac491..85dd4418fd --- a/utils/src/com/cloud/utils/fsm/StateObject.java +++ b/utils/src/com/cloud/utils/fsm/StateObject.java @@ -21,7 +21,7 @@ public interface StateObject { /** - * @return finite state. - */ + * @return finite state. + */ S getState(); } From 781ad96b04c9030fc1c0a0401145414e7f3978aa Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 11:43:05 -0700 Subject: [PATCH 019/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- .gitignore | 1 + api/src/com/cloud/event/EventTypes.java | 1 + api/src/org/apache/cloudstack/api/ApiConstants.java | 1 + setup/db/db/schema-430to440.sql | 8 ++++++++ 4 files changed, 11 insertions(+) diff --git a/.gitignore b/.gitignore index a0307a771d..f541d41e7d 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,4 @@ tools/apidoc/log/ log/ plugins/network-elements/juniper-contrail/logs/ scripts/vm/hypervisor/xenserver/vhd-util +*.orig diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 5b9ea5c1a9..bc8a8c2e73 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -448,6 +448,7 @@ public class EventTypes { public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE"; public static final String EVENT_BAREMETAL_PXE_SERVER_ADD = "PHYSICAL.PXE.ADD"; public static final String EVENT_BAREMETAL_PXE_SERVER_DELETE = "PHYSICAL.PXE.DELETE"; + public static final String EVENT_BAREMETAL_RCT_ADD = "BAREMETAL.RCT.ADD"; public static final String EVENT_AFFINITY_GROUP_CREATE = "AG.CREATE"; public static final String EVENT_AFFINITY_GROUP_DELETE = "AG.DELETE"; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index adda5f4cee..3a5a42b2ce 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -525,6 +525,7 @@ public class ApiConstants { public static final String COUNTERPARAM_LIST = "counterparam"; public static final String AUTOSCALE_USER_ID = "autoscaleuserid"; public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername"; + public static final String BAREMETAL_RCT_URL = "baremetalrcturl"; public static final String UCS_DN = "ucsdn"; public static final String GSLB_PROVIDER = "gslbprovider"; public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider"; diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 9043fb2158..d89e32f883 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -685,6 +685,14 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'CentOS 6.5 (64-bit)', 228); INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 6.5 (64-bit)', 228); +CREATE TABLE `cloud`.`baremetal_rct` ( + `id` bigint unsigned UNIQUE AUTO_INCREMENT, + `uuid` varchar(40) UNIQUE NOT NULL, + `url` varchar(2048) NOT NULL, + `rct` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `cloud`.`op_router_monitoring_services` ( `vm_id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key', `router_name` varchar(255) NOT NULL COMMENT 'Name of the Virtual Router', From ce1b633daf8145247820bbf3248ce6306e18b6cf Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 11:46:55 -0700 Subject: [PATCH 020/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- .../baremetal/database/BaremetalRctDao.java | 17 +++++++++++++++ .../database/BaremetalRctDaoImpl.java | 17 +++++++++++++++ .../cloud/baremetal/manager/BaremetalRct.java | 17 +++++++++++++++ .../manager/BaremetalVlanManager.java | 17 +++++++++++++++ .../manager/BaremetalVlanManagerImpl.java | 17 +++++++++++++++ .../networkservice/schema/ObjectFactory.java | 21 +++++++++++++------ .../schema/SecurityGroupRule.java | 21 +++++++++++++------ .../cloudstack/api/AddBaremetalRctCmd.java | 17 +++++++++++++++ 8 files changed, 132 insertions(+), 12 deletions(-) mode change 100644 => 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java mode change 100644 => 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java index fee2d71724..7da7fe69a7 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java @@ -1,3 +1,20 @@ +// 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.baremetal.database; import com.cloud.utils.db.GenericDao; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java index 89df902e6c..8f4d74ad87 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java @@ -1,3 +1,20 @@ +// 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.baremetal.database; import com.cloud.utils.db.GenericDaoBase; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java index 796023e7ff..9ed7cf4caa 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java @@ -1,3 +1,20 @@ +// 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.baremetal.manager; import java.util.List; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java index 8b57eb4032..7ffe461c69 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java @@ -1,3 +1,20 @@ +// 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.baremetal.manager; import com.cloud.baremetal.networkservice.BaremetalRctResponse; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java index 5bb59a2edb..16daa5baa5 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java @@ -1,3 +1,20 @@ +// 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.baremetal.manager; import com.cloud.baremetal.database.BaremetalRctDao; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java old mode 100644 new mode 100755 index b5bc694516..a80625bb7c --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java @@ -1,11 +1,20 @@ +// 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 // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.07.11 at 03:24:15 PM PDT +// 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.baremetal.networkservice.schema; import javax.xml.bind.annotation.XmlRegistry; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java old mode 100644 new mode 100755 index 050c3fdee7..83315714f3 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java @@ -1,11 +1,20 @@ +// 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 // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.07.11 at 03:24:15 PM PDT +// 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.baremetal.networkservice.schema; import java.util.ArrayList; diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java index 554e2ec378..2015fe528b 100755 --- a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java @@ -1,3 +1,20 @@ +// 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 org.apache.cloudstack.api; import com.cloud.baremetal.manager.BaremetalVlanManager; From 65497b69c7226550e0eec8d66bb1c2f0b9fc0670 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 14:52:45 -0700 Subject: [PATCH 021/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- plugins/hypervisors/baremetal/pom.xml | 2 +- .../networkservice/BaremetaNetworkGuru.java | 20 +++++++++---------- .../src/com/cloud/configuration/Config.java | 17 ++++++++++++++++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 8f1237e480..154e0c3350 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -21,7 +21,7 @@ org.apache.cloudstack cloudstack-plugins - 4.4.0-SNAPSHOT + 4.5.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java index 808c61ecb6..a0b4199898 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java @@ -18,14 +18,6 @@ // Automatically generated by addcopyright.py at 01/29/2013 package com.cloud.baremetal.networkservice; -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; - import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; @@ -37,7 +29,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -58,6 +50,12 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.inject.Inject; @Local(value = {NetworkGuru.class}) public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { @@ -81,7 +79,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + throws InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientVirtualNetworkCapacityException { if (dest.getHost().getHypervisorType() != HypervisorType.BareMetal) { super.reserve(nic, network, vm, dest, context); return; @@ -153,7 +151,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { s_logger.debug("Allocated a nic " + nic + " for " + vm); } - private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientVirtualNetworkCapcityException, + private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(pod.getDataCenterId()); if (nic.getIp4Address() == null) { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 7863001f4b..fbcb1f42ea 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -1810,6 +1810,23 @@ public enum Config { "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null), + BaremetalIpmiLanInterface( + "Advanced", + ManagementServer.class, + String.class, + "baremetal.ipmi.lan.interface", + "default", + "option specified in -I option of impitool. candidates are: open/bmc/lipmi/lan/lanplus/free/imb, see ipmitool man page for details. default valule 'default' means using default option of ipmitool", + null), + + BaremetalIpmiRetryTimes("Advanced", + ManagementServer.class, + String.class, + "baremetal.ipmi.fail.retry", + "5", + "ipmi interface will be temporary out of order after power opertions(e.g. cycle, on), it leads following commands fail immediately. The value specifies retry times before accounting it as real failure", + null), + ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null), ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null), ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null), From 62e005b97edb6c0307f92c502d7da8485694bd88 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 16:06:33 -0700 Subject: [PATCH 022/819] CLOUDSTACK-6278 Baremetal Advanced Networking support --- .../baremetal/database/BaremetalRctVO.java | 17 +++++++++++++++++ .../networkservice/BaremetalRctResponse.java | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java index ae1f794aab..91cbc9fe12 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java @@ -1,3 +1,20 @@ +// 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.baremetal.database; import javax.persistence.Column; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java index 837c615292..cf85f1943d 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java @@ -1,3 +1,20 @@ +// 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.baremetal.networkservice; import com.cloud.serializer.Param; From b87a5ce5fe6b3ed5002aaacdd39e045dd4eca803 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 7 Jul 2014 15:11:53 -0700 Subject: [PATCH 023/819] Fixed deploydb for 4.5 branch --- setup/db/create-schema.sql | 60 ++++++++++++++++----------------- setup/db/db/schema-440to450.sql | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index fe5cd0a169..f95b02f6ce 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -246,7 +246,7 @@ CREATE TABLE `cloud`.`networks` ( `broadcast_domain_type` varchar(32) NOT NULL COMMENT 'type of broadcast domain used', `broadcast_uri` varchar(255) COMMENT 'broadcast domain specifier', `gateway` varchar(15) COMMENT 'gateway for this network configuration', - `cidr` varchar(18) COMMENT 'network cidr', + `cidr` varchar(18) COMMENT 'network cidr', `mode` varchar(32) COMMENT 'How to retrieve ip address in this network', `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id that this configuration is created from', `physical_network_id` bigint unsigned COMMENT 'physical network id that this configuration is based on', @@ -270,14 +270,14 @@ CREATE TABLE `cloud`.`networks` ( `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network provides an ability to define ip ranges', `vpc_id` bigint unsigned COMMENT 'vpc this network belongs to', PRIMARY KEY (`id`), - CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), + CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), CONSTRAINT `fk_networks__vpc_id` FOREIGN KEY(`vpc_id`) REFERENCES `vpc`(`id`), CONSTRAINT `uc_networks__uuid` UNIQUE (`uuid`), - INDEX `i_networks__removed`(`removed`) + INDEX `i_networks__removed`(`removed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`account_network_ref` ( @@ -301,7 +301,7 @@ CREATE TABLE `cloud`.`nics` ( `ip_type` varchar(32) COMMENT 'type of ip', `broadcast_uri` varchar(255) COMMENT 'broadcast uri', `network_id` bigint unsigned NOT NULL COMMENT 'network configuration id', - `mode` varchar(32) COMMENT 'mode of getting ip address', + `mode` varchar(32) COMMENT 'mode of getting ip address', `state` varchar(32) NOT NULL COMMENT 'state of the creation', `strategy` varchar(32) NOT NULL COMMENT 'reservation strategy', `reserver_name` varchar(255) COMMENT 'Name of the component that reserved the ip address', @@ -431,11 +431,11 @@ CREATE TABLE `cloud`.`op_ha_work` ( `time_to_try` bigint COMMENT 'time to try do this work', `updated` bigint unsigned NOT NULL COMMENT 'time the VM state was updated when it was stored into work queue', PRIMARY KEY (`id`), - CONSTRAINT `fk_op_ha_work__instance_id` FOREIGN KEY `fk_op_ha_work__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_op_ha_work__instance_id` FOREIGN KEY `fk_op_ha_work__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, INDEX `i_op_ha_work__instance_id`(`instance_id`), CONSTRAINT `fk_op_ha_work__host_id` FOREIGN KEY `fk_op_ha_work__host_id` (`host_id`) REFERENCES `host` (`id`), - INDEX `i_op_ha_work__host_id`(`host_id`), - INDEX `i_op_ha_work__step`(`step`), + INDEX `i_op_ha_work__host_id`(`host_id`), + INDEX `i_op_ha_work__step`(`step`), INDEX `i_op_ha_work__type`(`type`), CONSTRAINT `fk_op_ha_work__mgmt_server_id` FOREIGN KEY `fk_op_ha_work__mgmt_server_id`(`mgmt_server_id`) REFERENCES `mshost`(`msid`), INDEX `i_op_ha_work__mgmt_server_id`(`mgmt_server_id`) @@ -682,7 +682,7 @@ CREATE TABLE `cloud`.`host_pod_ref` ( `gateway` varchar(255) NOT NULL COMMENT 'gateway for the pod', `cidr_address` varchar(15) NOT NULL COMMENT 'CIDR address for the pod', `cidr_size` bigint unsigned NOT NULL COMMENT 'CIDR size for the pod', - `description` varchar(255) COMMENT 'store private ip range in startIP-endIP format', + `description` varchar(255) COMMENT 'store private ip range in startIP-endIP format', `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this Pod enabled for allocation for new resources', `external_dhcp` tinyint NOT NULL DEFAULT 0 COMMENT 'Is this Pod using external DHCP', `removed` datetime COMMENT 'date removed if not null', @@ -692,13 +692,13 @@ CREATE TABLE `cloud`.`host_pod_ref` ( INDEX `i_host_pod_ref__allocation_state`(`allocation_state`), INDEX `i_host_pod_ref__removed`(`removed`), CONSTRAINT `uc_host_pod_ref__uuid` UNIQUE (`uuid`) - + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`op_dc_vnet_alloc` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary id', `vnet` varchar(18) NOT NULL COMMENT 'vnet', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network the vnet belongs to', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network the vnet belongs to', `data_center_id` bigint unsigned NOT NULL COMMENT 'data center the vnet belongs to', `reservation_id` char(40) NULL COMMENT 'reservation id', `account_id` bigint unsigned NULL COMMENT 'account the vnet belongs to right now', @@ -812,7 +812,7 @@ CREATE TABLE `cloud`.`port_forwarding_rules` ( CREATE TABLE `cloud`.`host` ( `id` bigint unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL, - `uuid` varchar(40) COMMENT 'this uuid is different with guid below, the later one is used by hypervisor resource', + `uuid` varchar(40) COMMENT 'this uuid is different with guid below, the later one is used by hypervisor resource', `status` varchar(32) NOT NULL, `type` varchar(32) NOT NULL, `private_ip_address` char(40) NOT NULL, @@ -869,7 +869,7 @@ CREATE TABLE `cloud`.`op_host` ( `id` bigint unsigned NOT NULL UNIQUE COMMENT 'host id', `sequence` bigint unsigned DEFAULT 1 NOT NULL COMMENT 'sequence for the host communication', PRIMARY KEY (`id`), - CONSTRAINT `fk_op_host__id` FOREIGN KEY (`id`) REFERENCES `host`(`id`) ON DELETE CASCADE + CONSTRAINT `fk_op_host__id` FOREIGN KEY (`id`) REFERENCES `host`(`id`) ON DELETE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`account_details` ( @@ -915,7 +915,7 @@ CREATE TABLE `cloud`.`mshost_peer` ( `peer_runid` bigint NOT NULL, `peer_state` varchar(10) NOT NULL DEFAULT 'Down', `last_update` DATETIME NULL COMMENT 'Last record update time', - + PRIMARY KEY (`id`), CONSTRAINT `fk_mshost_peer__owner_mshost` FOREIGN KEY (`owner_mshost`) REFERENCES `mshost`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_mshost_peer__peer_mshost` FOREIGN KEY (`peer_mshost`) REFERENCES `mshost`(`id`), @@ -965,7 +965,7 @@ CREATE TABLE `cloud`.`event` ( `description` varchar(1024) NOT NULL, `user_id` bigint unsigned NOT NULL, `account_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, `created` datetime NOT NULL, `level` varchar(16) NOT NULL, `start_id` bigint unsigned NOT NULL DEFAULT 0, @@ -1046,7 +1046,7 @@ CREATE TABLE `cloud`.`vm_template` ( `hvm` int(1) unsigned NOT NULL COMMENT 'requires HVM', `bits` int(6) unsigned NOT NULL COMMENT '32 bit or 64 bit', `url` varchar(255) NULL COMMENT 'the url where the template exists externally', - `format` varchar(32) NOT NULL COMMENT 'format for the template', + `format` varchar(32) NOT NULL COMMENT 'format for the template', `created` datetime NOT NULL COMMENT 'Date created', `removed` datetime COMMENT 'Date removed if not null', `account_id` bigint unsigned NOT NULL COMMENT 'id of the account that created this template', @@ -1153,7 +1153,7 @@ CREATE TABLE `cloud`.`domain_router` ( `public_ip_address` char(40) COMMENT 'public ip address used for source net', `public_netmask` varchar(15) COMMENT 'netmask used for the domR', `guest_netmask` varchar(15) COMMENT 'netmask used for the guest network', - `guest_ip_address` char(40) COMMENT ' ip address in the guest network', + `guest_ip_address` char(40) COMMENT ' ip address in the guest network', `is_redundant_router` int(1) unsigned NOT NULL COMMENT 'if in redundant router mode', `priority` int(4) unsigned COMMENT 'priority of router in the redundant router mode', `is_priority_bumpup` int(1) unsigned NOT NULL COMMENT 'if the priority has been bumped up', @@ -1230,7 +1230,7 @@ CREATE TABLE `cloud`.`volume_host_ref` ( `local_path` varchar(255), `install_path` varchar(255), `url` varchar(255), - `format` varchar(32) NOT NULL COMMENT 'format for the volume', + `format` varchar(32) NOT NULL COMMENT 'format for the volume', `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', PRIMARY KEY (`id`), CONSTRAINT `fk_volume_host_ref__host_id` FOREIGN KEY `fk_volume_host_ref__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, @@ -1330,9 +1330,9 @@ CREATE TABLE `cloud`.`account` ( INDEX i_account__removed(`removed`), CONSTRAINT `fk_account__default_zone_id` FOREIGN KEY `fk_account__default_zone_id`(`default_zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, INDEX `i_account__cleanup_needed`(`cleanup_needed`), - INDEX `i_account__account_name__domain_id__removed`(`account_name`, `domain_id`, `removed`), + INDEX `i_account__account_name__domain_id__removed`(`account_name`, `domain_id`, `removed`), CONSTRAINT `fk_account__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain` (`id`), - INDEX `i_account__domain_id`(`domain_id`), + INDEX `i_account__domain_id`(`domain_id`), CONSTRAINT `uc_account__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1380,7 +1380,7 @@ CREATE TABLE `cloud`.`op_host_capacity` ( INDEX `i_op_host_capacity__host_type`(`host_id`, `capacity_type`), INDEX `i_op_host_capacity__pod_id`(`pod_id`), INDEX `i_op_host_capacity__data_center_id`(`data_center_id`), - INDEX `i_op_host_capacity__cluster_id`(`cluster_id`) + INDEX `i_op_host_capacity__cluster_id`(`cluster_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`alert` ( @@ -1404,7 +1404,7 @@ CREATE TABLE `cloud`.`async_job` ( `user_id` bigint unsigned NOT NULL, `account_id` bigint unsigned NOT NULL, `session_key` varchar(64) COMMENT 'all async-job manage to apply session based security enforcement', - `instance_type` varchar(64) COMMENT 'instance_type and instance_id work together to allow attaching an instance object to a job', + `instance_type` varchar(64) COMMENT 'instance_type and instance_id work together to allow attaching an instance object to a job', `instance_id` bigint unsigned, `job_cmd` varchar(64) NOT NULL COMMENT 'command name', `job_cmd_originator` varchar(64) COMMENT 'command originator', @@ -1437,7 +1437,7 @@ CREATE TABLE `cloud`.`async_job` ( CREATE TABLE `cloud`.`sync_queue` ( `id` bigint unsigned NOT NULL auto_increment, - `sync_objtype` varchar(64) NOT NULL, + `sync_objtype` varchar(64) NOT NULL, `sync_objid` bigint unsigned NOT NULL, `queue_proc_msid` bigint, `queue_proc_number` bigint COMMENT 'process number, increase 1 for each iteration', @@ -1815,7 +1815,7 @@ CREATE TABLE `cloud`.`instance_group` ( `created` datetime COMMENT 'date the group was created', PRIMARY KEY (`id`), INDEX `i_instance_group__removed`(`removed`), - CONSTRAINT `uc_instance_group__uuid` UNIQUE (`uuid`), + CONSTRAINT `uc_instance_group__uuid` UNIQUE (`uuid`), CONSTRAINT `fk_instance_group__account_id` FOREIGN KEY(`account_id`) REFERENCES `account` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; @@ -1850,7 +1850,7 @@ CREATE TABLE `cloud`.`usage_event` ( `resource_name` varchar(255), `offering_id` bigint unsigned, `template_id` bigint unsigned, - `size` bigint unsigned, + `size` bigint unsigned, `resource_type` varchar(32), `processed` tinyint NOT NULL default '0', PRIMARY KEY (`id`), @@ -2055,9 +2055,9 @@ CREATE TABLE `cloud`.`physical_network` ( `name` varchar(255) NOT NULL, `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this physical network belongs to', `vnet` varchar(255), - `speed` varchar(32), + `speed` varchar(32), `domain_id` bigint unsigned COMMENT 'foreign key to domain id', - `broadcast_domain_range` varchar(32) NOT NULL DEFAULT 'POD' COMMENT 'range of broadcast domain : POD/ZONE', + `broadcast_domain_range` varchar(32) NOT NULL DEFAULT 'POD' COMMENT 'range of broadcast domain : POD/ZONE', `state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'what state is this configuration in', `created` datetime COMMENT 'date created', `removed` datetime COMMENT 'date removed if not null', @@ -2065,7 +2065,7 @@ CREATE TABLE `cloud`.`physical_network` ( CONSTRAINT `fk_physical_network__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_physical_network__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), CONSTRAINT `uc_physical_networks__uuid` UNIQUE (`uuid`), - INDEX `i_physical_network__removed`(`removed`) + INDEX `i_physical_network__removed`(`removed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`physical_network_tags` ( @@ -2091,7 +2091,7 @@ CREATE TABLE `cloud`.`physical_network_traffic_types` ( `uuid` varchar(40), `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', - `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host', + `xen_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host', `kvm_network_label` varchar(255) DEFAULT 'cloudbr0' COMMENT 'The network name label of the physical device dedicated to this traffic on a KVM host', `vmware_network_label` varchar(255) DEFAULT 'vSwitch0' COMMENT 'The network name label of the physical device dedicated to this traffic on a VMware host', `simulator_network_label` varchar(255) COMMENT 'The name labels needed for identifying the simulator', @@ -2333,7 +2333,7 @@ CREATE TABLE `cloud`.`vpc` ( PRIMARY KEY (`id`), INDEX `i_vpc__removed`(`removed`), CONSTRAINT `fk_vpc__zone_id` FOREIGN KEY `fk_vpc__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), + CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), CONSTRAINT `fk_vpc__account_id` FOREIGN KEY `fk_vpc__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_vpc__domain_id` FOREIGN KEY `fk_vpc__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -2423,7 +2423,7 @@ CREATE TABLE `cloud`.`static_routes` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', `uuid` varchar(40), `vpc_gateway_id` bigint unsigned COMMENT 'id of the corresponding ip address', - `cidr` varchar(18) COMMENT 'cidr for the static route', + `cidr` varchar(18) COMMENT 'cidr for the static route', `state` char(32) NOT NULL COMMENT 'current state of this rule', `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', `account_id` bigint unsigned NOT NULL COMMENT 'owner id', diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index c88a18afa3..1a019ddf49 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -233,4 +233,4 @@ CREATE VIEW `cloud`.`volume_view` AS and async_job.job_status = 0; /* As part of the separation of Xen and XenServer, update the column for the network labels */ -ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host' +ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host'; From 5a96d8ef5cbc88df366016ae9dd7ee46e4ca417a Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 7 Jul 2014 15:12:36 -0700 Subject: [PATCH 024/819] CLOUDSTACK-7073: Added domainId field to the user table in order to restrict duplicated users creation on the db level --- engine/schema/src/com/cloud/user/UserVO.java | 6 ++++++ .../schema/src/com/cloud/user/dao/UserDaoImpl.java | 13 +++++++++++++ setup/db/db/schema-440to450.sql | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/engine/schema/src/com/cloud/user/UserVO.java b/engine/schema/src/com/cloud/user/UserVO.java index 68879f6f80..8ab450d877 100644 --- a/engine/schema/src/com/cloud/user/UserVO.java +++ b/engine/schema/src/com/cloud/user/UserVO.java @@ -97,6 +97,9 @@ public class UserVO implements User, Identity, InternalIdentity { @Column(name = "default") boolean isDefault; + @Column(name = "domain_id") + private long domainId; + public UserVO() { this.uuid = UUID.randomUUID().toString(); } @@ -270,4 +273,7 @@ public boolean isDefault() { return isDefault; } + public void setDomainId(long domainId) { + this.domainId = domainId; + } } diff --git a/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java index 6ac398d81c..d39177eb67 100644 --- a/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java @@ -19,9 +19,11 @@ import java.util.List; import javax.ejb.Local; +import javax.inject.Inject; import org.springframework.stereotype.Component; +import com.cloud.user.Account; import com.cloud.user.UserVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -40,6 +42,9 @@ public class UserDaoImpl extends GenericDaoBase implements UserDao protected SearchBuilder SecretKeySearch; protected SearchBuilder RegistrationTokenSearch; + @Inject + AccountDao _accountDao; + protected UserDaoImpl() { UsernameSearch = createSearchBuilder(); UsernameSearch.and("username", UsernameSearch.entity().getUsername(), SearchCriteria.Op.EQ); @@ -128,4 +133,12 @@ public List findUsersByName(String username) { return listBy(sc); } + @Override + @DB + public UserVO persist(UserVO user) { + Account account = _accountDao.findById(user.getAccountId()); + user.setDomainId(account.getDomainId()); + return super.persist(user); + } + } diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index 1a019ddf49..5fd62002e8 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -234,3 +234,9 @@ CREATE VIEW `cloud`.`volume_view` AS /* As part of the separation of Xen and XenServer, update the column for the network labels */ ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host'; + +/*Adding domainId field to the user table in order to restrict duplicated users creation on the db level*/ +ALTER TABLE `cloud`.`user` ADD COLUMN domain_id bigint(20) unsigned DEFAULT NULL; +ALTER TABLE `cloud`.`user` ADD CONSTRAINT `fk_user__domain_id` FOREIGN KEY `fk_user__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE; +UPDATE `cloud`.`user` SET `cloud`.`user`.domain_id=(SELECT `cloud`.`account`.domain_id FROM `cloud`.`account` WHERE `cloud`.`account`.id=`cloud`.`user`.account_id) where id > 0; +ALTER TABLE `cloud`.`user` ADD UNIQUE KEY `username_domain_id` (`username`,`domain_id`); From b517156fe337ea209effaf2645e6ad7497540ea7 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 7 Jul 2014 16:44:18 -0700 Subject: [PATCH 025/819] CLOUDSTACK-7039: don't log exception stackTrace when catch sql exception on system/admin user/account insert --- server/src/com/cloud/server/ConfigurationServerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index b66e52dcb0..7c3b5a52e8 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -464,7 +464,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); } catch (SQLException ex) { - s_logger.debug("Caught SQLException when inserting system account ", ex); + s_logger.debug("Caught exception when inserting system account: " + ex.getMessage()); } // insert system user insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)" @@ -474,7 +474,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); } catch (SQLException ex) { - s_logger.debug("Caught SQLException when inserting system user ", ex); + s_logger.debug("Caught SQLException when inserting system user: " + ex.getMessage()); } // insert admin user, but leave the account disabled until we set a @@ -491,7 +491,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); } catch (SQLException ex) { - s_logger.debug("Caught SQLException when creating admin account ", ex); + s_logger.debug("Caught SQLException when creating admin account: " + ex.getMessage()); } // now insert the user @@ -502,7 +502,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); } catch (SQLException ex) { - s_logger.debug("Caught SQLException when inserting user ", ex); + s_logger.debug("Caught SQLException when inserting admin user: " + ex.getMessage()); } try { From 83034907ca460b91850e73ea3ac7fe4d1bee3db9 Mon Sep 17 00:00:00 2001 From: Mike Tutkowski Date: Wed, 2 Jul 2014 10:58:42 -0600 Subject: [PATCH 026/819] Modification to the way SolidFire account info is stored in the DB --- .../SolidFirePrimaryDataStoreDriver.java | 24 +++++++++----- ...idFireSharedPrimaryDataStoreLifeCycle.java | 33 ++++++++++++++++--- .../storage/datastore/util/SolidFireUtil.java | 20 +++++++++-- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java index 124b1172b6..c06a72895a 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java @@ -195,10 +195,7 @@ private long getDefaultBurstIops(long storagePoolId, long maxIops) { return (long)(maxIops * fClusterDefaultBurstIopsPercentOfMaxIops); } - private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo) { - AccountDetailVO accountDetail = _accountDetailsDao.findDetail(volumeInfo.getAccountId(), SolidFireUtil.ACCOUNT_ID); - long sfAccountId = Long.parseLong(accountDetail.getValue()); - + private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo, long sfAccountId) { long storagePoolId = volumeInfo.getDataStore().getId(); final Iops iops; @@ -298,15 +295,26 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet String sfAccountName = SolidFireUtil.getSolidFireAccountName(account.getUuid(), account.getAccountId()); long storagePoolId = dataStore.getId(); + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); - if (SolidFireUtil.getSolidFireAccount(sfConnection, sfAccountName) == null) { - SolidFireUtil.SolidFireAccount sfAccount = createSolidFireAccount(sfConnection, sfAccountName); + AccountDetailVO accountDetail = SolidFireUtil.getAccountDetail(volumeInfo.getAccountId(), storagePoolId, _accountDetailsDao); + + if (accountDetail == null || accountDetail.getValue() == null) { + SolidFireUtil.SolidFireAccount sfAccount = SolidFireUtil.getSolidFireAccount(sfConnection, sfAccountName); - SolidFireUtil.updateCsDbWithSolidFireAccountInfo(account.getId(), sfAccount, _accountDetailsDao); + if (sfAccount == null) { + sfAccount = createSolidFireAccount(sfConnection, sfAccountName); + } + + SolidFireUtil.updateCsDbWithSolidFireAccountInfo(account.getId(), sfAccount, storagePoolId, _accountDetailsDao); + + accountDetail = SolidFireUtil.getAccountDetail(volumeInfo.getAccountId(), storagePoolId, _accountDetailsDao); } - SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, volumeInfo); + long sfAccountId = Long.parseLong(accountDetail.getValue()); + + SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, volumeInfo, sfAccountId); iqn = sfVolume.getIqn(); diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java index b03634b8fc..5065822673 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java @@ -219,7 +219,9 @@ public DataStore initialize(Map dsInfos) { SolidFireUtil.SolidFireConnection sfConnection = new SolidFireUtil.SolidFireConnection(managementVip, managementPort, clusterAdminUsername, clusterAdminPassword); - SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, storagePoolName, capacityBytes, lMinIops, lMaxIops, lBurstIops); + SolidFireCreateVolume sfCreateVolume = createSolidFireVolume(sfConnection, storagePoolName, capacityBytes, lMinIops, lMaxIops, lBurstIops); + + SolidFireUtil.SolidFireVolume sfVolume = sfCreateVolume.getVolume(); String iqn = sfVolume.getIqn(); @@ -255,6 +257,11 @@ public DataStore initialize(Map dsInfos) { List hosts = _hostDao.findByClusterId(clusterId); SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolume.getId(), dataStore.getId(), hosts, _clusterDetailsDao); + + SolidFireUtil.SolidFireAccount sfAccount = sfCreateVolume.getAccount(); + Account csAccount = CallContext.current().getCallingAccount(); + + SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccount.getId(), sfAccount, dataStore.getId(), _accountDetailsDao); } catch (Exception ex) { _primaryDataStoreDao.expunge(dataStore.getId()); @@ -286,7 +293,25 @@ private StoragePoolType getStorageType(HypervisorType hypervisorType) { throw new CloudRuntimeException("The 'hypervisor' parameter must be '" + HypervisorType.XenServer + "' or '" + HypervisorType.VMware + "'."); } - private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, + private class SolidFireCreateVolume { + private final SolidFireUtil.SolidFireVolume _sfVolume; + private final SolidFireUtil.SolidFireAccount _sfAccount; + + public SolidFireCreateVolume(SolidFireUtil.SolidFireVolume sfVolume, SolidFireUtil.SolidFireAccount sfAccount) { + _sfVolume = sfVolume; + _sfAccount = sfAccount; + } + + public SolidFireUtil.SolidFireVolume getVolume() { + return _sfVolume; + } + + public SolidFireUtil.SolidFireAccount getAccount() { + return _sfAccount; + } + } + + private SolidFireCreateVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, String volumeName, long volumeSize, long minIops, long maxIops, long burstIops) { try { Account csAccount = CallContext.current().getCallingAccount(); @@ -301,15 +326,13 @@ private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidF long accountNumber = SolidFireUtil.createSolidFireAccount(sfConnection, sfAccountName); sfAccount = SolidFireUtil.getSolidFireAccountById(sfConnection, accountNumber); - - SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccountId, sfAccount, _accountDetailsDao); } long sfVolumeId = SolidFireUtil.createSolidFireVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeName), sfAccount.getId(), volumeSize, true, null, minIops, maxIops, burstIops); SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getSolidFireVolume(sfConnection, sfVolumeId); - return sfVolume; + return new SolidFireCreateVolume(sfVolume, sfAccount); } catch (Throwable e) { throw new CloudRuntimeException("Failed to create a SolidFire volume: " + e.toString()); } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java index 3f35d71e20..7c09d85493 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java @@ -187,13 +187,14 @@ public static void updateCsDbWithSolidFireIopsInfo(long storagePoolId, PrimaryDa } public static void updateCsDbWithSolidFireAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount, - AccountDetailsDao accountDetailsDao) { + long storagePoolId, AccountDetailsDao accountDetailsDao) { AccountDetailVO accountDetail = new AccountDetailVO(csAccountId, - SolidFireUtil.ACCOUNT_ID, + SolidFireUtil.getAccountKey(storagePoolId), String.valueOf(sfAccount.getId())); accountDetailsDao.persist(accountDetail); + /* accountDetail = new AccountDetailVO(csAccountId, SolidFireUtil.CHAP_INITIATOR_USERNAME, String.valueOf(sfAccount.getName())); @@ -217,6 +218,7 @@ public static void updateCsDbWithSolidFireAccountInfo(long csAccountId, SolidFir sfAccount.getTargetSecret()); accountDetailsDao.persist(accountDetail); + */ } public static SolidFireAccount getSolidFireAccount(SolidFireConnection sfConnection, String sfAccountName) { @@ -358,6 +360,20 @@ public static String getVagKey(long storagePoolId) { return "sfVolumeAccessGroup_" + storagePoolId; } + private static String getAccountKey(long storagePoolId) { + return SolidFireUtil.ACCOUNT_ID + "_" + storagePoolId; + } + + public static AccountDetailVO getAccountDetail(long csAccountId, long storagePoolId, AccountDetailsDao accountDetailsDao) { + AccountDetailVO accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId)); + + if (accountDetail == null || accountDetail.getValue() == null) { + accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.ACCOUNT_ID); + } + + return accountDetail; + } + public static String[] getIqnsFromHosts(List hosts) { if (hosts == null || hosts.size() == 0) { throw new CloudRuntimeException("There do not appear to be any hosts in this cluster."); From 62c18ca3fa332846071da1e59639136efd378a47 Mon Sep 17 00:00:00 2001 From: Mike Tutkowski Date: Mon, 7 Jul 2014 15:38:06 -0600 Subject: [PATCH 027/819] Fixing an issue in the AbstractStoragePoolAllocator's filter method where zone-wide storage of HypervisorType.Any is skipped --- .../storage/allocator/AbstractStoragePoolAllocator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java index 98a6acfcf2..d3df356c72 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -38,6 +38,7 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; @@ -171,7 +172,7 @@ protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, } return false; } - } else if (pool.getHypervisor() != null && !(pool.getHypervisor() == dskCh.getHypervisorType())) { + } else if (pool.getHypervisor() != null && !pool.getHypervisor().equals(HypervisorType.Any) && !(pool.getHypervisor() == dskCh.getHypervisorType())) { if (s_logger.isDebugEnabled()) { s_logger.debug("StoragePool does not have required hypervisorType, skipping this pool"); } From a9b3ab089d6cb0bc1494e10b2be90292f4c79289 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 30 May 2014 11:09:43 +0530 Subject: [PATCH 028/819] CLOUDSTACK-7077. Quickly attaching multiple data disks to a VM fails. [VMware] Synchronize the tasks of disk preparation and reconfiguration of a VM with the disk. This is to avoid attaching a disk with a wrong device number on the controller key. --- .../vmware/mo/VirtualMachineMO.java | 108 +++++++++++------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index b5b9a5ef83..df05f8aa56 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -107,11 +107,13 @@ import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.GlobalLock; import com.cloud.utils.script.Script; public class VirtualMachineMO extends BaseMO { private static final Logger s_logger = Logger.getLogger(VirtualMachineMO.class); private static final ExecutorService MonitorServiceExecutor = Executors.newCachedThreadPool(new NamedThreadFactory("VM-Question-Monitor")); + private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_DISK_ATTACH = 5 * 60; // Wait for a maximum of 5 minutes to prepare a disk while VM is being re-configured with another disk private ManagedObjectReference _vmEnvironmentBrowser = null; public VirtualMachineMO(VmwareContext context, ManagedObjectReference morVm) { @@ -1050,62 +1052,90 @@ public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, Virtu } public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception { + // Add lock to ensure that only one disk is being prepared and attached to the VM at a time + GlobalLock lock = GlobalLock.getInternLock("disk.attach"); + try { + s_logger.trace("Grabbing lock to ensure that only one disk is being prepared and attached to the VM at a time."); + if (lock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_DISK_ATTACH)) { + try { + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) + + ", datastore: " + morDs.getValue()); - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) + - ", datastore: " + morDs.getValue()); - - VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1); - VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); + VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1); + VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - deviceConfigSpec.setDevice(newDisk); - deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); + deviceConfigSpec.setDevice(newDisk); + deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - reConfigSpec.getDeviceChange().add(deviceConfigSpec); + reConfigSpec.getDeviceChange().add(deviceConfigSpec); - ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); - boolean result = _context.getVimClient().waitForTask(morTask); + ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); + boolean result = _context.getVimClient().waitForTask(morTask); - if (!result) { - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(failed)"); - throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } + if (!result) { + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk() done(failed)"); + throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } - _context.waitForTaskProgressDone(morTask); + _context.waitForTaskProgressDone(morTask); - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); + } finally { + lock.unlock(); + } + } else { + s_logger.warn("Couldn't get lock on VM: " + _mor.getValue() + " to attach disk: " + vmdkDatastorePathChain + " ,maybe another disk is being attached to the VM."); + } + } finally { + lock.releaseRef(); + } } public void attachDisk(Pair[] vmdkDatastorePathChain, int controllerKey) throws Exception { + // Add lock to ensure that only one disk is being prepared and attached to the VM at a time + GlobalLock lock = GlobalLock.getInternLock("disk.attach"); + try { + s_logger.trace("Grabbing lock to ensure that only one disk is being prepared and attached to the VM at a time."); + if (lock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_DISK_ATTACH)) { + try { + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain)); - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain)); + VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1); + VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1); - VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); + deviceConfigSpec.setDevice(newDisk); + deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - deviceConfigSpec.setDevice(newDisk); - deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); + reConfigSpec.getDeviceChange().add(deviceConfigSpec); - reConfigSpec.getDeviceChange().add(deviceConfigSpec); + ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); + boolean result = _context.getVimClient().waitForTask(morTask); - ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); - boolean result = _context.getVimClient().waitForTask(morTask); + if (!result) { + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk() done(failed)"); + throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } - if (!result) { - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(failed)"); - throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - - _context.waitForTaskProgressDone(morTask); + _context.waitForTaskProgressDone(morTask); - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); + } finally { + lock.unlock(); + } + } else { + s_logger.warn("Couldn't get lock on VM: " + _mor.getValue() + " to attach disk: " + vmdkDatastorePathChain + " ,maybe another disk is being attached to the VM."); + } + } finally { + lock.releaseRef(); + } } // vmdkDatastorePath: [datastore name] vmdkFilePath From 63ba1ddfb9ddfb47c7e0c564fea3ad8edf2bd19a Mon Sep 17 00:00:00 2001 From: John Dilley Date: Mon, 30 Jun 2014 14:23:50 +0000 Subject: [PATCH 029/819] CLOUDSTACK-7010: Add domain to createZones in marvin --- tools/marvin/marvin/configGenerator.py | 1 + tools/marvin/marvin/deployDataCenter.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index 8daaaa9d59..6055f46723 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -88,6 +88,7 @@ def __init__(self): self.pods = [] self.secondaryStorages = [] self.cacheStorages = [] + self.domain = None class trafficType(object): diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index a2fbd4abbc..ae48839828 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -695,6 +695,7 @@ def createZones(self, zones): zonecmd.securitygroupenabled = zone.securitygroupenabled zonecmd.localstorageenabled = zone.localstorageenabled zonecmd.networktype = zone.networktype + zonecmd.domain = zone.domain if zone.securitygroupenabled != "true": zonecmd.guestcidraddress = zone.guestcidraddress zoneId = self.createZone(zonecmd) From 89a326a878ee6fce098e1a9d198ceb8d44c2eada Mon Sep 17 00:00:00 2001 From: Vania Xu Date: Tue, 8 Jul 2014 14:42:52 -0600 Subject: [PATCH 030/819] Update to retrieve additional properties for testing. Signed-off-by: Mike Tutkowski --- tools/marvin/marvin/lib/base.py | 68 ++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 445fabab1a..fe257f009d 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -618,8 +618,8 @@ def delete(self, apiclient): cmd.id = self.id apiclient.destroyVirtualMachine(cmd) - def expung(self, apiclient): - """Expung an Instance""" + def expunge(self, apiclient): + """Expunge an Instance""" cmd = expungeVirtualMachine.expungeVirtualMachineCmd() cmd.id = self.id apiclient.expungeVirtualMachine(cmd) @@ -1876,6 +1876,15 @@ def create(cls, apiclient, services, domainid=None, **kwargs): if "isvolatile" in services: cmd.isvolatile = services["isvolatile"] + if "miniops" in services: + cmd.miniops = services["miniops"] + + if "maxiops" in services: + cmd.maxiops = services["maxiops"] + + if "customizediops" in services: + cmd.customizediops = services["customizediops"] + if "offerha" in services: cmd.offerha = services["offerha"] @@ -1927,6 +1936,24 @@ def create(cls, apiclient, services, custom=False, domainid=None): if "storagetype" in services: cmd.storagetype = services["storagetype"] + if "customizediops" in services: + cmd.customizediops = services["customizediops"] + + if "disksize" in services: + cmd.disksize = services["disksize"] + + if "maxiops" in services: + cmd.maxiops = services["maxiops"] + + if "miniops" in services: + cmd.miniops = services["miniops"] + + if "storagetype" in services: + cmd.storagetype = services["storagetype"] + + if "tags" in services: + cmd.tags = services["tags"] + return DiskOffering(apiclient.createDiskOffering(cmd).__dict__) def delete(self, apiclient): @@ -2409,8 +2436,9 @@ def __init__(self, items): self.__dict__.update(items) @classmethod - def create(cls, apiclient, services, clusterid=None, - zoneid=None, podid=None): + def create(cls, apiclient, services, scope=None, clusterid=None, + zoneid=None, podid=None, provider=None, tags=None, + capacityiops=None, capacitybytes=None, hypervisor=None): """Create Storage pool (Primary Storage)""" cmd = createStoragePool.createStoragePoolCmd() @@ -2418,7 +2446,7 @@ def create(cls, apiclient, services, clusterid=None, if podid: cmd.podid = podid - else: + elif "podid" in services: cmd.podid = services["podid"] cmd.url = services["url"] @@ -2432,6 +2460,36 @@ def create(cls, apiclient, services, clusterid=None, else: cmd.zoneid = services["zoneid"] + if scope: + cmd.scope = scope + elif "scope" in services: + cmd.scope = services["scope"] + + if provider: + cmd.provider = provider + elif "provider" in services: + cmd.provider = services["provider"] + + if tags: + cmd.tags = tags + elif "tags" in services: + cmd.tags = services["tags"] + + if capacityiops: + cmd.capacityiops = capacityiops + elif "capacityiops" in services: + cmd.capacityiops = services["capacityiops"] + + if capacitybytes: + cmd.capacitybytes = capacitybytes + elif "capacitybytes" in services: + cmd.capacitybytes = services["capacitybytes"] + + if hypervisor: + cmd.hypervisor = hypervisor + elif "hypervisor" in services: + cmd.hypervisor = services["hypervisor"] + return StoragePool(apiclient.createStoragePool(cmd).__dict__) def delete(self, apiclient): From f4d203475535839971d143d4c72a60d3f8b787c0 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 8 Jul 2014 14:02:07 -0700 Subject: [PATCH 031/819] CLOUDSTACK-7081: db upgrade fixes - a) added description for cloud.volumes.iso_id field b) removed duplicated unique key "id_2" from cloud.storage_pool table --- .../com/cloud/upgrade/dao/Upgrade440to450.java | 17 +++++++++++++++++ setup/db/db/schema-440to450.sql | 2 ++ 2 files changed, 19 insertions(+) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java index c1f853e817..caf3b422d2 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java @@ -19,6 +19,9 @@ import java.io.File; import java.sql.Connection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import org.apache.log4j.Logger; @@ -55,6 +58,7 @@ public File[] getPrepareScripts() { @Override public void performDataMigration(Connection conn) { + dropInvalidKeyFromStoragePoolTable(conn); } @@ -67,4 +71,17 @@ public File[] getCleanupScripts() { return new File[] {new File(script)}; } + + private void dropInvalidKeyFromStoragePoolTable(Connection conn) { + HashMap> uniqueKeys = new HashMap>(); + List keys = new ArrayList(); + + keys.add("id_2"); + uniqueKeys.put("storage_pool", keys); + + s_logger.debug("Droping id_2 key from storage_pool table"); + for (String tableName : uniqueKeys.keySet()) { + DbUpgradeUtils.dropKeysIfExist(conn, tableName, uniqueKeys.get(tableName), false); + } + } } diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index 5fd62002e8..d047060d26 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -240,3 +240,5 @@ ALTER TABLE `cloud`.`user` ADD COLUMN domain_id bigint(20) unsigned DEFAULT NULL ALTER TABLE `cloud`.`user` ADD CONSTRAINT `fk_user__domain_id` FOREIGN KEY `fk_user__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE; UPDATE `cloud`.`user` SET `cloud`.`user`.domain_id=(SELECT `cloud`.`account`.domain_id FROM `cloud`.`account` WHERE `cloud`.`account`.id=`cloud`.`user`.account_id) where id > 0; ALTER TABLE `cloud`.`user` ADD UNIQUE KEY `username_domain_id` (`username`,`domain_id`); + +ALTER TABLE `cloud`.`volumes` CHANGE COLUMN `iso_id` `iso_id` bigint(20) unsigned COMMENT 'The id of the iso from which the volume was created'; From cc8fc746df4f6138653ac7b28a0110128664a53c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 21 Apr 2014 17:52:39 -0700 Subject: [PATCH 032/819] CLOUDSTACK-6468:IAM - Templates - Admin user is not allowed to edit template and set isExtractable() paramater. (cherry picked from commit b6617843d258d9437a17d39e698edba430768f9a) Signed-off-by: Nitin Mehta --- server/src/com/cloud/template/TemplateManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 7876a5a56f..f5ad97f81a 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1263,8 +1263,8 @@ public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissions if (isExtractable != null) { // Only Root admins allowed to change it for templates - if (!template.getFormat().equals(ImageFormat.ISO) && _accountMgr.isRootAdmin(caller.getId())) { - throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); + if (!template.getFormat().equals(ImageFormat.ISO) && !_accountMgr.isRootAdmin(caller.getId())) { + throw new InvalidParameterValueException("Only ROOT admins are allowed to modify isExtractable attribute."); } else { // For Isos normal user can change it, as their are no derivatives. updatedTemplate.setExtractable(isExtractable.booleanValue()); From 362f875a3fa814f17a01368ce0c9b76a23d56218 Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Tue, 8 Jul 2014 14:44:16 -0700 Subject: [PATCH 033/819] Detach disks before cleaning up of VMware worker VM. --- .../src/com/cloud/hypervisor/vmware/resource/VmwareResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 08d69e0592..15eeb13bcd 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3982,6 +3982,7 @@ private void gcAndKillHungWorkerVMs() { s_logger.info("Recycle pending worker VM: " + vmMo.getName()); vmMo.powerOff(); + vmMo.detachAllDisks(); vmMo.destroy(); } } From f275eb1ff9c2cb0ec8a74c4a891366d9403e858f Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Wed, 9 Jul 2014 12:07:15 +0530 Subject: [PATCH 034/819] CLOUDSTACK-7029: listCapacity fails when podid argument is specified. --- engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index bcd6fa78a7..df023bfcf7 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -659,12 +659,12 @@ public HashMap countVgpuVMs(Long dcId, Long podId, Long clusterId) finalQuery.append(COUNT_VMS_BASED_ON_VGPU_TYPES1); if (podId != null) { - finalQuery.append(" AND host.pod_id = ?"); + finalQuery.append("AND host.pod_id = ? "); resourceIdList.add(podId); } if (clusterId != null) { - finalQuery.append(" AND host.cluster_id = ?"); + finalQuery.append("AND host.cluster_id = ? "); resourceIdList.add(clusterId); } finalQuery.append(COUNT_VMS_BASED_ON_VGPU_TYPES2); From e85d1f911c4f5b0f4eea32cbec7f42d9f01d630f Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Wed, 9 Jul 2014 12:27:47 +0530 Subject: [PATCH 035/819] Some minor fixes in simulator code --- .../src/com/cloud/agent/manager/MockStorageManagerImpl.java | 6 +++--- .../src/com/cloud/resource/SimulatorDiscoverer.java | 5 ----- .../com/cloud/resource/SimulatorSecondaryDiscoverer.java | 3 --- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index 8e1aaed847..89b79506cd 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -289,11 +289,11 @@ public Answer AttachIso(AttachIsoCommand cmd) { vm = _mockVMDao.findByVmName(vmName); txn.commit(); if (vm == null) { - return new Answer(cmd, false, "can't vm :" + vmName); + return new Answer(cmd, false, "can't find vm :" + vmName); } } catch (Exception ex) { txn.rollback(); - throw new CloudRuntimeException("Error when attaching iso to vm " + vm.getName(), ex); + throw new CloudRuntimeException("Error when attaching iso to vm " + vmName, ex); } finally { txn.close(); txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); @@ -514,8 +514,8 @@ public Answer Destroy(DestroyCommand cmd) { if (cmd.getVmName() != null) { MockVm vm = _mockVMDao.findByVmName(cmd.getVmName()); - vm.setState(State.Expunging); if (vm != null) { + vm.setState(State.Expunging); MockVMVO vmVo = _mockVMDao.createForUpdate(vm.getId()); _mockVMDao.update(vm.getId(), vmVo); } diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java index d1ebfb557f..7c31a9af75 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java @@ -41,7 +41,6 @@ import com.cloud.agent.manager.MockAgentManager; import com.cloud.agent.manager.MockStorageManager; import com.cloud.dc.ClusterVO; -import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; import com.cloud.exception.DiscoveryException; import com.cloud.host.Host; @@ -65,15 +64,11 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L @Inject VMTemplateZoneDao _vmTemplateZoneDao; @Inject - ClusterDao _clusterDao; - @Inject AgentManager _agentMgr = null; @Inject MockAgentManager _mockAgentMgr = null; @Inject MockStorageManager _mockStorageMgr = null; - @Inject - ResourceManager _resourceMgr; /** * Finds ServerResources of an in-process simulator diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index 715e9f37f6..11bf346610 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.storage.resource.SecondaryStorageResource; import org.apache.log4j.Logger; -import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.AgentControlCommand; @@ -52,8 +51,6 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp @Inject MockStorageManager _mockStorageMgr = null; @Inject - AgentManager _agentMgr; - @Inject SnapshotDao _snapshotDao; @Inject ImageStoreDao imageStoreDao; From 73b622c82368f6c58b1a5c8e32dcb1c808d534c5 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 9 Jul 2014 12:43:32 +0530 Subject: [PATCH 036/819] CLOUDSTACK-7068: addIpToNicCmd changed to BaseAsyncCreate --- api/src/com/cloud/event/EventTypes.java | 10 +++ api/src/com/cloud/network/NetworkService.java | 2 + .../api/command/user/vm/AddIpToVmNicCmd.java | 68 ++++++++++--------- .../command/user/vm/RemoveIpFromVmNicCmd.java | 2 +- .../com/cloud/network/NetworkServiceImpl.java | 22 ++++++ .../com/cloud/vpc/MockNetworkManagerImpl.java | 5 ++ 6 files changed, 76 insertions(+), 33 deletions(-) diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index bc8a8c2e73..71bfdb6854 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -31,6 +31,7 @@ import com.cloud.server.ResourceTag; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.vm.ConsoleProxy; +import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.SecondaryStorageVm; import org.apache.cloudstack.config.Configuration; @@ -508,6 +509,11 @@ public class EventTypes { public static final String EVENT_GUEST_OS_MAPPING_REMOVE = "GUEST.OS.MAPPING.REMOVE"; public static final String EVENT_GUEST_OS_MAPPING_UPDATE = "GUEST.OS.MAPPING.UPDATE"; + public static final String EVENT_NIC_SECONDARY_IP_ASSIGN = "NIC.SECONDARY.IP.ASSIGN"; + public static final String EVENT_NIC_SECONDARY_IP_UNASSIGN = "NIC.SECONDARY.IP.UNASSIGN"; + public static final String EVENT_NIC_SECONDARY_IP_CONFIGURE = "NIC.SECONDARY.IP.CONFIGURE"; + + static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking @@ -849,6 +855,10 @@ public class EventTypes { entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class); entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class); entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class); + entityEventDetails.put(EVENT_NIC_SECONDARY_IP_ASSIGN, NicSecondaryIp.class); + entityEventDetails.put(EVENT_NIC_SECONDARY_IP_UNASSIGN, NicSecondaryIp.class); + entityEventDetails.put(EVENT_NIC_SECONDARY_IP_CONFIGURE, NicSecondaryIp.class); + } public static String getEntityForEvent(String eventName) { diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 1e126f52ae..18b59e9ee9 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -178,4 +178,6 @@ Network createPrivateNetwork(String networkName, String displayText, long physic Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service); IpAddress updateIP(Long id, String customId, Boolean displayIp); + + boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled); } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index 870bbbf01e..4b805acc39 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -20,7 +20,7 @@ import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NicResponse; @@ -45,7 +45,7 @@ @APICommand(name = "addIpToNic", description = "Assigns secondary IP to NIC", responseObject = NicSecondaryIpResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class AddIpToVmNicCmd extends BaseAsyncCmd { +public class AddIpToVmNicCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName()); private static final String s_name = "addiptovmnicresponse"; @@ -100,7 +100,7 @@ private boolean isZoneSGEnabled() { @Override public String getEventType() { - return EventTypes.EVENT_NET_IP_ASSIGN; + return EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN; } @Override @@ -125,35 +125,18 @@ public static String getResultObjectName() { public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { CallContext.current().setEventDetails("Nic Id: " + getNicId()); - String ip; - NicSecondaryIp result; - String secondaryIp = null; - if ((ip = getIpaddress()) != null) { - if (!NetUtils.isValidIp(ip)) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); - } - } - - try { - result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress()); - } catch (InsufficientAddressCapacityException e) { - throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage()); - } + NicSecondaryIp result = _entityMgr.findById(NicSecondaryIp.class, getEntityId()); if (result != null) { - secondaryIp = result.getIp4Address(); - if (isZoneSGEnabled()) { - // add security group rules for the secondary ip addresses - boolean success = false; - success = _securityGroupService.securityGroupRulesForVmSecIp(getNicId(), secondaryIp, true); - if (success == false) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); - } + CallContext.current().setEventDetails("secondary Ip Id: " + getEntityId()); + boolean success = false; + success = _networkService.configureNicSecondaryIp(result, isZoneSGEnabled()); + + if (success == false) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); } - s_logger.info("Associated ip address to NIC : " + secondaryIp); - NicSecondaryIpResponse response = new NicSecondaryIpResponse(); - response = _responseGenerator.createSecondaryIPToNicResponse(result); + NicSecondaryIpResponse response = _responseGenerator.createSecondaryIPToNicResponse(result); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { @@ -161,10 +144,6 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc } } - @Override - public String getSyncObjType() { - return BaseAsyncCmd.networkSyncObject; - } @Override public Long getSyncObjId() { @@ -188,4 +167,29 @@ public long getEntityOwnerId() { return vm.getAccountId(); } + @Override + public void create() throws ResourceAllocationException { + String ip; + NicSecondaryIp result; + String secondaryIp = null; + if ((ip = getIpaddress()) != null) { + if (!NetUtils.isValidIp(ip)) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); + } + } + + try { + result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress()); + if (result != null) { + setEntityId(result.getId()); + setEntityUuid(result.getUuid()); + } + } catch (InsufficientAddressCapacityException e) { + throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage()); + } + + if (result == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic"); + } + } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index 70d5b48a16..19da39a597 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -86,7 +86,7 @@ public long getEntityOwnerId() { @Override public String getEventType() { - return EventTypes.EVENT_NET_IP_ASSIGN; + return EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN; } public NicSecondaryIp getIpEntry() { diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index b3de9e313a..c8105e8274 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -40,6 +40,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.network.security.SecurityGroupService; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.ControlledEntity.ACLType; @@ -315,6 +316,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Inject LoadBalancingRulesService _lbService; + @Inject + public SecurityGroupService _securityGroupService; + int _cidrLimit; boolean _allowSubdomainNetworkAccess; @@ -648,6 +652,22 @@ protected NetworkServiceImpl() { } @Override + @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_CONFIGURE, eventDescription = "Configuring secondary ip " + + "rules", async = true) + public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) { + boolean success = false; + + if (isZoneSgEnabled) { + success = _securityGroupService.securityGroupRulesForVmSecIp(secIp.getNicId(), secIp.getIp4Address(), true); + s_logger.info("Associated ip address to NIC : " + secIp.getIp4Address()); + } else { + success = true; + } + return success; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN, eventDescription = "assigning secondary ip to nic", create = true) public NicSecondaryIp allocateSecondaryGuestIP(final long nicId, String requestedIp) throws InsufficientAddressCapacityException { Account caller = CallContext.current().getCallingAccount(); @@ -752,6 +772,8 @@ public Long doInTransaction(TransactionStatus status) { @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN, eventDescription = "Removing secondary ip " + + "from nic", async = true) public boolean releaseSecondaryIpFromNic(long ipAddressId) { Account caller = CallContext.current().getCallingAccount(); boolean success = false; diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 1ed8b6e231..097019d76e 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -862,4 +862,9 @@ public IpAddress updateIP(Long id, String customId, Boolean displayIp) { return null; } + @Override + public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + } From d51e8f44aecd192acb3bb6f2195819e1b4c43dd0 Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Wed, 9 Jul 2014 15:58:43 +0530 Subject: [PATCH 037/819] CLOUDSTACK-7079: Fixed the issue where rollback was called after commit. As well, added few null checks --- .../dao/ManagementServerHostDaoImpl.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 89d7d27825..9136a640b4 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -85,15 +85,17 @@ public void update(long id, long runid, String name, String version, String serv txn.start(); try(PreparedStatement pstmt = txn.prepareStatement("update mshost set name=?, version=?, service_ip=?, service_port=?, last_update=?, removed=null, alert_count=0, runid=?, state=? where id=?");) { - pstmt.setString(1, name); - pstmt.setString(2, version); - pstmt.setString(3, serviceIP); - pstmt.setInt(4, servicePort); - pstmt.setString(5, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); - pstmt.setLong(6, runid); - pstmt.setString(7, ManagementServerHost.State.Up.toString()); - pstmt.setLong(8, id); - pstmt.executeUpdate(); + if (pstmt != null) { + pstmt.setString(1, name); + pstmt.setString(2, version); + pstmt.setString(3, serviceIP); + pstmt.setInt(4, servicePort); + pstmt.setString(5, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); + pstmt.setLong(6, runid); + pstmt.setString(7, ManagementServerHost.State.Up.toString()); + pstmt.setLong(8, id); + pstmt.executeUpdate(); + } }catch(SQLException e) { throw new CloudRuntimeException("update:Exception:"+e.getMessage(),e); @@ -136,19 +138,20 @@ public void update(long id, long runid, Date lastUpdate) { try { txn.start(); try( PreparedStatement pstmt = txn.prepareStatement("update mshost set last_update=?, removed=null, alert_count=0 where id=? and runid=?");) { - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); - pstmt.setLong(2, id); - pstmt.setLong(3, runid); - - int count = pstmt.executeUpdate(); - txn.commit(); - - if (count < 1) { - throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runid + " is no longer valid")); + if (pstmt != null) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); + pstmt.setLong(2, id); + pstmt.setLong(3, runid); + + int count = pstmt.executeUpdate(); + if (count < 1) { + throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runid + " is no longer valid")); + } } }catch (SQLException e) { throw new CloudRuntimeException("update:Exception:"+e.getMessage(), e); } + txn.commit(); } catch (RuntimeException e) { txn.rollback(); s_logger.warn("update:Exception:"+e.getMessage(), e); @@ -183,8 +186,10 @@ public int increaseAlertCount(long id) { try { txn.start(); try(PreparedStatement pstmt = txn.prepareStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0");) { - pstmt.setLong(1, id); - changedRows = pstmt.executeUpdate(); + if (pstmt != null) { + pstmt.setLong(1, id); + changedRows = pstmt.executeUpdate(); + } }catch (SQLException e) { throw new CloudRuntimeException("increaseAlertCount:Exception:"+e.getMessage(),e); From e07d0ddabfedad137856c3c9ae7de3a96fe25feb Mon Sep 17 00:00:00 2001 From: Sujaya Maiyya Date: Tue, 8 Jul 2014 14:42:39 +0530 Subject: [PATCH 038/819] fixed CLOUDSTACK-6261: remove the forceful timeout setting when login to NetScaler. --- .../src/com/cloud/network/resource/NetscalerResource.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index ff51ef9470..87576990e5 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -171,7 +171,6 @@ public class NetscalerResource implements ServerResource { // interface to interact with service VM of the SDX appliance com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService; - Long _timeout = new Long(100000); base_response apiCallResult; public NetscalerResource() { @@ -294,7 +293,6 @@ private void login() throws ExecutionException { if (!_isSdx) { _netscalerService = new nitro_service(_ip, "https"); _netscalerService.set_credential(_username, _password); - _netscalerService.set_timeout(_timeout); _netscalerService.set_certvalidation(false); _netscalerService.set_hostnameverification(false); apiCallResult = _netscalerService.login(); @@ -984,7 +982,6 @@ private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int try { nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https"); _netscalerService.set_credential(username, password); - _netscalerService.set_timeout(_timeout); apiCallResult = _netscalerService.login(); if (apiCallResult.errorcode == 0) { nsServiceUp = true; From 61fe959bb454279cc711a7c7fa5449c7f8881125 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Thu, 10 Jul 2014 12:10:46 +0530 Subject: [PATCH 039/819] Removed invalid assertions from code. Now the MS can be run with assertions enabled (using -ea flag) --- framework/db/src/com/cloud/utils/db/TransactionLegacy.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java index 7cc6343631..7784d2f439 100755 --- a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java +++ b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java @@ -113,9 +113,6 @@ protected static TransactionLegacy currentTxn(boolean check) { TransactionLegacy txn = tls.get(); if (check) { assert txn != null : "No Transaction on stack. Did you mark the method with @DB?"; - - assert checkAnnotation(4, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private. What about @DB? hmmm... could that be it? " + - txn; } return txn; } From e0d4af50626f46dcc84612aff427c6db13cc4270 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 10 Jul 2014 14:54:05 +0530 Subject: [PATCH 040/819] CLOUDSTACK-7092: Disabled icmp redirects in VR --- systemvm/patches/debian/config/etc/sysctl.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/systemvm/patches/debian/config/etc/sysctl.conf b/systemvm/patches/debian/config/etc/sysctl.conf index 961d471dfa..c8f4bfb083 100644 --- a/systemvm/patches/debian/config/etc/sysctl.conf +++ b/systemvm/patches/debian/config/etc/sysctl.conf @@ -24,7 +24,8 @@ net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 - +net.ipv4.conf.all.secure_redirects = 0 +net.ipv4.conf.default.secure_redirects = 0 # Controls the System Request debugging functionality of the kernel kernel.sysrq = 0 From 394be902ebf909c356eef06813f128a2b9a7410c Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Thu, 10 Jul 2014 16:51:28 +0530 Subject: [PATCH 041/819] Some findbugs fixes in cloud-api project --- .../command/admin/region/CreatePortableIpRangeCmd.java | 7 +++---- .../command/admin/region/ListPortableIpRangesCmd.java | 2 +- .../user/firewall/CreatePortForwardingRuleCmd.java | 2 +- .../user/loadbalancer/CreateLoadBalancerRuleCmd.java | 4 ++-- .../user/loadbalancer/ListLoadBalancerRulesCmd.java | 2 +- .../ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java | 4 ---- .../region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java | 9 +++------ 7 files changed, 11 insertions(+), 19 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java index 955bb9c292..403eaf3e39 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java @@ -114,12 +114,11 @@ public long getEntityOwnerId() { @Override public void execute() { PortableIpRange portableIpRange = _entityMgr.findById(PortableIpRange.class, getEntityId()); - PortableIpRangeResponse response = null; if (portableIpRange != null) { - response = _responseGenerator.createPortableIPRangeResponse(portableIpRange); + PortableIpRangeResponse response = _responseGenerator.createPortableIPRangeResponse(portableIpRange); + response.setResponseName(getCommandName()); + this.setResponseObject(response); } - response.setResponseName(getCommandName()); - this.setResponseObject(response); } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java index 100572ef5a..ed0ddd68ac 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java @@ -98,8 +98,8 @@ public void execute() { } responses.add(rangeResponse); } + response.setResponses(responses, portableIpRanges.size()); } - response.setResponses(responses, portableIpRanges.size()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index 865cd1b764..3247af8545 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -184,7 +184,7 @@ private Long getVpcId() { if (ipAddressId != null) { IpAddress ipAddr = _networkService.getIp(ipAddressId); if (ipAddr == null || !ipAddr.readyToUse()) { - throw new InvalidParameterValueException("Unable to create PF rule, invalid IP address id " + ipAddr.getId()); + throw new InvalidParameterValueException("Unable to create PF rule, invalid IP address id " + ipAddressId); } else { return ipAddr.getVpcId(); } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java index 7c371928d9..e33e58487c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java @@ -153,7 +153,7 @@ public Long getSourceIpAddressId() { if (publicIpId != null) { IpAddress ipAddr = _networkService.getIp(publicIpId); if (ipAddr == null || !ipAddr.readyToUse()) { - throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id " + ipAddr.getId()); + throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id " + publicIpId); } } else if (getEntityId() != null) { LoadBalancer rule = _entityMgr.findById(LoadBalancer.class, getEntityId()); @@ -167,7 +167,7 @@ private Long getVpcId() { if (publicIpId != null) { IpAddress ipAddr = _networkService.getIp(publicIpId); if (ipAddr == null || !ipAddr.readyToUse()) { - throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id " + ipAddr.getId()); + throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id " + publicIpId); } else { return ipAddr.getVpcId(); } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java index df6c989464..71d82327a1 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java @@ -130,8 +130,8 @@ public void execute() { lbResponse.setObjectName("loadbalancerrule"); lbResponses.add(lbResponse); } + response.setResponses(lbResponses, loadBalancers.second()); } - response.setResponses(lbResponses, loadBalancers.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java index 177939b232..8e1b4ddf12 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java @@ -45,7 +45,6 @@ import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.Account; import com.cloud.utils.StringUtils; -import com.cloud.utils.db.EntityManager; @APICommand(name = "assignToGlobalLoadBalancerRule", description = "Assign load balancer rule or list of load " + "balancer rules to a global load balancer rules.", @@ -58,9 +57,6 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { private static final String s_name = "assigntogloballoadbalancerruleresponse"; - @Inject - public EntityManager _entityMgr; - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java index 67825761b8..18f5b7683c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java @@ -147,15 +147,12 @@ public String getCommandName() { @Override public void execute() throws ResourceAllocationException, ResourceUnavailableException { - - CallContext callerContext = CallContext.current(); GlobalLoadBalancerRule rule = _entityMgr.findById(GlobalLoadBalancerRule.class, getEntityId()); - GlobalLoadBalancerResponse response = null; if (rule != null) { - response = _responseGenerator.createGlobalLoadBalancerResponse(rule); - setResponseObject(response); + GlobalLoadBalancerResponse response = _responseGenerator.createGlobalLoadBalancerResponse(rule); + response.setResponseName(getCommandName()); + this.setResponseObject(response); } - response.setResponseName(getCommandName()); } @Override From 1f3d02b38acbd269a65e2a9b0a1d0233b69a7598 Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Thu, 10 Jul 2014 23:35:27 +0530 Subject: [PATCH 042/819] Reverting the changes done to this file for coverity fixes --- .../dao/ManagementServerHostDaoImpl.java | 169 ++++++++---------- 1 file changed, 77 insertions(+), 92 deletions(-) diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 9136a640b4..3d0c3f5630 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -53,14 +53,15 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase getInactiveList(Date cutTime) { @DB public int increaseAlertCount(long id) { TransactionLegacy txn = TransactionLegacy.currentTxn(); + PreparedStatement pstmt = null; int changedRows = 0; try { txn.start(); - try(PreparedStatement pstmt = txn.prepareStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0");) { - if (pstmt != null) { - pstmt.setLong(1, id); - changedRows = pstmt.executeUpdate(); - } - }catch (SQLException e) - { - throw new CloudRuntimeException("increaseAlertCount:Exception:"+e.getMessage(),e); - } + + pstmt = txn.prepareAutoCloseStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0"); + pstmt.setLong(1, id); + + changedRows = pstmt.executeUpdate(); txn.commit(); - } catch (RuntimeException e) { - txn.rollback(); - s_logger.warn("increaseAlertCount:Exception:" + e.getMessage(), e); - throw new CloudRuntimeException("increaseAlertCount:Exception:" + e.getMessage(), e); - }finally - { - txn.close(); + } catch (Exception e) { + s_logger.warn("Unexpected exception, ", e); + throw new RuntimeException(e.getMessage(), e); } + return changedRows; } @@ -229,19 +211,21 @@ protected ManagementServerHostDaoImpl() { @Override public void update(long id, long runId, State state, Date lastUpdate) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - try (PreparedStatement pstmt = txn.prepareStatement("update mshost set state=?, last_update=? where id=? and runid=?");){ - if (pstmt != null) { - pstmt.setString(1, state.toString()); - pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); - pstmt.setLong(3, id); - pstmt.setLong(4, runId); - int count = pstmt.executeUpdate(); - if (count < 1) { - throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runId + " is no longer valid")); - } + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement("update mshost set state=?, last_update=? where id=? and runid=?"); + pstmt.setString(1, state.toString()); + pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate)); + pstmt.setLong(3, id); + pstmt.setLong(4, runId); + + int count = pstmt.executeUpdate(); + + if (count < 1) { + throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runId + " is no longer valid")); } } catch (SQLException e) { - throw new CloudRuntimeException("update:Exception:" + e.getMessage(), e); + throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); } } @@ -257,21 +241,22 @@ public List listBy(ManagementServerHost.State... states) @Override public List listOrphanMsids() { List orphanList = new ArrayList(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); - try (PreparedStatement pstmt = - txn.prepareStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)");) - { - try(ResultSet rs = pstmt.executeQuery();) { - while (rs.next()) { - orphanList.add(rs.getLong(1)); - } - }catch (SQLException e) { - throw new CloudRuntimeException("listOrphanMsids:Exception:" + e.getMessage(), e); + PreparedStatement pstmt = null; + try { + pstmt = + txn.prepareAutoCloseStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)"); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + orphanList.add(rs.getLong(1)); } - return orphanList; } catch (SQLException e) { - throw new CloudRuntimeException("listOrphanMsids:Exception:" + e.getMessage(), e); + throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); } + + return orphanList; } @Override From ab8036b76634bbf1fc420277c756fe69c261b595 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 10 Jul 2014 16:43:31 -0700 Subject: [PATCH 043/819] List view: View subselect on infinite scrolling Fixes issue where outdated context is passed to subselect's data provider when infinite scroll event loads more data items. Now, context is derived from DOM data directly instead of in the args. --- ui/scripts/ui/widgets/listView.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 415169a0ea..509c802c4f 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1327,7 +1327,10 @@ if ($(this).is(':checked')) { // Populate data subselect.dataProvider({ - context: $.extend(true, {}, options.context, { + context: $.extend(true, {}, + ($listView && $listView.data('view-args') ? + $.extend(true, {}, $listView.data('view-args').context, options.context) : + options.context), { instances: [$tr.data('json-obj')] }), response: { From 8bd9e780717dad4d2f4451e4b681f701c45f2793 Mon Sep 17 00:00:00 2001 From: Vania Xu Date: Thu, 10 Jul 2014 11:36:26 -0600 Subject: [PATCH 044/819] Adding SolidFire API plug-in --- client/pom.xml | 5 ++ .../findbugsExcludeFilter.xml | 25 ++++++ plugins/api/solidfire-intg-test/pom.xml | 50 +++++++++++ .../solidfire-intg-test/module.properties | 18 ++++ .../spring-solidfire-intg-test-context.xml | 32 +++++++ .../solidfire/GetSolidFireAccountIdCmd.java | 83 +++++++++++++++++++ .../ApiSolidFireAccountIdResponse.java | 37 +++++++++ .../solidfire/ApiSolidFireService.java | 29 +++++++ .../solidfire/ApiSolidFireServiceImpl.java | 76 +++++++++++++++++ plugins/pom.xml | 1 + .../storage/datastore/util/SolidFireUtil.java | 2 +- 11 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 plugins/api/solidfire-intg-test/findbugsExcludeFilter.xml create mode 100644 plugins/api/solidfire-intg-test/pom.xml create mode 100644 plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties create mode 100644 plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml create mode 100644 plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/user/solidfire/GetSolidFireAccountIdCmd.java create mode 100644 plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/ApiSolidFireAccountIdResponse.java create mode 100644 plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireService.java create mode 100644 plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireServiceImpl.java diff --git a/client/pom.xml b/client/pom.xml index 29fef4f335..46933d92c0 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -331,6 +331,11 @@ cloud-plugin-host-anti-affinity ${project.version} + + org.apache.cloudstack + cloud-plugin-api-solidfire-intg-test + ${project.version} + diff --git a/plugins/api/solidfire-intg-test/findbugsExcludeFilter.xml b/plugins/api/solidfire-intg-test/findbugsExcludeFilter.xml new file mode 100644 index 0000000000..d37285017e --- /dev/null +++ b/plugins/api/solidfire-intg-test/findbugsExcludeFilter.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml new file mode 100644 index 0000000000..0707461ce6 --- /dev/null +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + cloud-plugin-api-solidfire-intg-test + Apache CloudStack Plugin - API SolidFire + + org.apache.cloudstack + cloudstack-plugins + 4.5.0-SNAPSHOT + ../../pom.xml + + + + org.apache.cloudstack + cloud-plugin-storage-volume-solidfire + ${project.version} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + -Xmx1024m + + org/apache/cloudstack/solidfire/integration/* + + + + + + diff --git a/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties b/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties new file mode 100644 index 0000000000..a6460b9392 --- /dev/null +++ b/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties @@ -0,0 +1,18 @@ +# 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. +name=solidfire-intg-test +parent=api \ No newline at end of file diff --git a/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml b/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml new file mode 100644 index 0000000000..1bab7349ca --- /dev/null +++ b/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/user/solidfire/GetSolidFireAccountIdCmd.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/user/solidfire/GetSolidFireAccountIdCmd.java new file mode 100644 index 0000000000..f4c0076f86 --- /dev/null +++ b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/user/solidfire/GetSolidFireAccountIdCmd.java @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.user.solidfire; + +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ApiSolidFireAccountIdResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.solidfire.ApiSolidFireService; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + +@APICommand(name = "getSolidFireAccountId", responseObject = ApiSolidFireAccountIdResponse.class, description = "Get SolidFire Account ID", + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class GetSolidFireAccountIdCmd extends BaseCmd { + private static final Logger s_logger = Logger.getLogger(GetSolidFireAccountIdCmd.class.getName()); + private static final String s_name = "getsolidfireaccountidresponse"; + + @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.STRING, description = "CloudStack Account UUID", required = true) + private String accountUuid; + @Parameter(name = ApiConstants.STORAGE_ID, type = CommandType.STRING, description = "Storage Pool UUID", required = true) + private String storagePoolUuid; + + @Inject private ApiSolidFireService _apiSolidFireService; + @Inject private AccountDao _accountDao; + @Inject private PrimaryDataStoreDao _storagePoolDao; + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = CallContext.current().getCallingAccount(); + + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute() { + Account account = _accountDao.findByUuid(accountUuid); + StoragePoolVO storagePool = _storagePoolDao.findByUuid(storagePoolUuid); + + ApiSolidFireAccountIdResponse response = _apiSolidFireService.getSolidFireAccountId(account.getId(), storagePool.getId()); + + response.setResponseName(getCommandName()); + response.setObjectName("apisolidfireaccountid"); + + this.setResponseObject(response); + } +} diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/ApiSolidFireAccountIdResponse.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/ApiSolidFireAccountIdResponse.java new file mode 100644 index 0000000000..ad77c7495d --- /dev/null +++ b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/ApiSolidFireAccountIdResponse.java @@ -0,0 +1,37 @@ +// 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 org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +public class ApiSolidFireAccountIdResponse extends BaseResponse { + @SerializedName("solidFireAccountId") + @Param(description = "SolidFire Account ID") + private long solidFireAccountId; + + public ApiSolidFireAccountIdResponse(long sfAccountId) { + solidFireAccountId = sfAccountId; + } + + public long getSolidFireAccountId() { + return solidFireAccountId; + } +} diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireService.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireService.java new file mode 100644 index 0000000000..2f01cfd046 --- /dev/null +++ b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireService.java @@ -0,0 +1,29 @@ +// 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 org.apache.cloudstack.solidfire; + +import com.cloud.utils.component.PluggableService; + +import org.apache.cloudstack.api.response.ApiSolidFireAccountIdResponse; + +/** + * Provide API for SolidFire integration tests + * + */ +public interface ApiSolidFireService extends PluggableService { + public ApiSolidFireAccountIdResponse getSolidFireAccountId(Long csAccountId, Long storagePoolId); +} diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireServiceImpl.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireServiceImpl.java new file mode 100644 index 0000000000..bbb485c66d --- /dev/null +++ b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/ApiSolidFireServiceImpl.java @@ -0,0 +1,76 @@ +// 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 org.apache.cloudstack.solidfire; + +import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; +import org.apache.cloudstack.acl.APIChecker; +import org.apache.cloudstack.storage.datastore.util.SolidFireUtil; +import org.apache.cloudstack.api.response.ApiSolidFireAccountIdResponse; +import org.apache.cloudstack.api.command.user.solidfire.GetSolidFireAccountIdCmd; +import org.springframework.stereotype.Component; + +import com.cloud.exception.PermissionDeniedException; +import com.cloud.user.AccountDetailsDao; +import com.cloud.user.AccountDetailVO; +import com.cloud.user.User; +import com.cloud.utils.component.AdapterBase; + +@Component +@Local(value = APIChecker.class) +public class ApiSolidFireServiceImpl extends AdapterBase implements APIChecker, ApiSolidFireService { + private static final Logger s_logger = Logger.getLogger(ApiSolidFireServiceImpl.class); + + @Inject + private AccountDetailsDao _accountDetailsDao; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + return true; + } + + @Override + public ApiSolidFireAccountIdResponse getSolidFireAccountId(Long csAccountId, Long storagePoolId) { + AccountDetailVO accountDetail = _accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId)); + String sfAccountId = accountDetail.getValue(); + + return new ApiSolidFireAccountIdResponse(Long.parseLong(sfAccountId)); + } + + @Override + public boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException { + return true; + } + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + + cmdList.add(GetSolidFireAccountIdCmd.class); + + return cmdList; + } +} diff --git a/plugins/pom.xml b/plugins/pom.xml index b5e6a61ea6..802e2ea375 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -38,6 +38,7 @@ api/rate-limit + api/solidfire-intg-test api/discovery acl/static-role-based affinity-group-processors/host-anti-affinity diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java index 7c09d85493..307ddbc3ce 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java @@ -360,7 +360,7 @@ public static String getVagKey(long storagePoolId) { return "sfVolumeAccessGroup_" + storagePoolId; } - private static String getAccountKey(long storagePoolId) { + public static String getAccountKey(long storagePoolId) { return SolidFireUtil.ACCOUNT_ID + "_" + storagePoolId; } From ba389819338a9be23f1cb604b9d586afb5598795 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Fri, 11 Jul 2014 17:04:36 +0530 Subject: [PATCH 045/819] CLOUDSTACK-7062: Enabled back the test as not able to repro --- test/integration/smoke/test_primary_storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 2394239765..66aec59b8a 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -144,7 +144,7 @@ def test_01_primary_storage_nfs(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false", BugId="7062") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") def test_01_primary_storage_iscsi(self): """Test primary storage pools - XEN, KVM, VMWare """ From 00778de96eb9f47a34bac79dc5175d16d71df194 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 11 Jul 2014 14:37:26 +0530 Subject: [PATCH 046/819] CLOUDSTACK-7099. Volume snapshot is not getting backed up. Correctly inject ConfigDao into SnapshotStateListener. --- .../spring-server-storage-context.xml | 3 ++- .../listener/SnapshotStateListener.java | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml b/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml index 8b90200a97..8fe24ffeeb 100644 --- a/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml +++ b/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml @@ -29,6 +29,7 @@ - + diff --git a/server/src/com/cloud/storage/listener/SnapshotStateListener.java b/server/src/com/cloud/storage/listener/SnapshotStateListener.java index d995a8271f..8da71a6793 100644 --- a/server/src/com/cloud/storage/listener/SnapshotStateListener.java +++ b/server/src/com/cloud/storage/listener/SnapshotStateListener.java @@ -22,10 +22,13 @@ import java.util.HashMap; import java.util.Map; +import javax.annotation.PostConstruct; +import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.stereotype.Component; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.events.EventBus; @@ -41,18 +44,27 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.utils.fsm.StateListener; +@Component +@Local(value = {SnapshotStateListener.class}) public class SnapshotStateListener implements StateListener { protected static EventBus s_eventBus = null; + protected static ConfigurationDao s_configDao; + @Inject - private ConfigurationDao _configDao; + private ConfigurationDao configDao; - private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class); + private static final Logger s_logger = Logger.getLogger(SnapshotStateListener.class); public SnapshotStateListener() { } + @PostConstruct + void init() { + s_configDao = configDao; + } + @Override public boolean preStateTransitionEvent(State oldState, Event event, State newState, SnapshotVO vo, boolean status, Object opaque) { pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState); @@ -68,7 +80,7 @@ public boolean postStateTransitionEvent(State oldState, Event event, State newSt private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) { String configKey = Config.PublishResourceStateEvent.key(); - String value = _configDao.getValue(configKey); + String value = s_configDao.getValue(configKey); boolean configValue = Boolean.parseBoolean(value); if(!configValue) return; From aab6e1222fc75a37f8015ba1d2c7bc923c1cf614 Mon Sep 17 00:00:00 2001 From: santhosh Date: Wed, 21 May 2014 00:22:17 +1000 Subject: [PATCH 047/819] Fixed Regression issues mentioned under CLOUDSTACK-6708 Signed-off-by: santhosh Conflicts: test/integration/smoke/test_deploy_vm.py test/integration/smoke/test_network.py test/integration/smoke/test_routers.py test/integration/smoke/test_vm_life_cycle.py --- test/integration/smoke/test_deploy_vm.py | 4 +- test/integration/smoke/test_hosts.py | 25 +++++------ test/integration/smoke/test_network.py | 25 ++++------- test/integration/smoke/test_routers.py | 44 +++++++++----------- test/integration/smoke/test_vm_life_cycle.py | 8 ++-- 5 files changed, 47 insertions(+), 59 deletions(-) diff --git a/test/integration/smoke/test_deploy_vm.py b/test/integration/smoke/test_deploy_vm.py index 0750287c6b..0810752501 100644 --- a/test/integration/smoke/test_deploy_vm.py +++ b/test/integration/smoke/test_deploy_vm.py @@ -42,7 +42,6 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.testdata = self.testClient.getParsedTestDataConfig() - # Get Zone, Domain and Default Built-in template self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) @@ -117,7 +116,7 @@ def test_deploy_vm_multiple(self): """Test Multiple Deploy Virtual Machine # Validate the following: - # 1. deploy 2 virtual machines + # 1. deploy 2 virtual machines # 2. listVirtualMachines using 'ids' parameter returns accurate information """ self.virtual_machine = VirtualMachine.create( @@ -207,6 +206,7 @@ def setUp(self): self.mock_volume_failure ] + @attr(tags = ['advanced'], BugId="CLOUDSTACK-6873", required_hardware="false") def test_deploy_vm_volume_creation_failure(self): """Test Deploy Virtual Machine - volume creation failure and retry diff --git a/test/integration/smoke/test_hosts.py b/test/integration/smoke/test_hosts.py index 02c4ef1a98..952f160094 100644 --- a/test/integration/smoke/test_hosts.py +++ b/test/integration/smoke/test_hosts.py @@ -5,9 +5,9 @@ # 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 @@ -23,6 +23,7 @@ from marvin.lib.utils import * from marvin.lib.base import * from marvin.lib.common import * +from marvin.lib.utils import (random_gen) from nose.plugins.attrib import attr #Import System modules @@ -66,21 +67,22 @@ def test_01_clusters(self): #Create clusters with Hypervisor type Simulator/XEN/KVM/VWare """ for k, v in self.services["clusters"].items(): + v["clustername"] = v["clustername"] + "-" + random_gen() cluster = Cluster.create( self.apiclient, v, zoneid=self.zone.id, podid=self.pod.id, - hypervisor=self.hypervisor + hypervisor=v["hypervisor"].lower() ) self.debug( "Created Cluster for hypervisor type %s & ID: %s" %( v["hypervisor"], - cluster.id + cluster.id )) self.assertEqual( - cluster.hypervisortype, - v["hypervisor"], + cluster.hypervisortype.lower(), + v["hypervisor"].lower(), "Check hypervisor type is " + v["hypervisor"] + " or not" ) self.assertEqual( @@ -103,7 +105,7 @@ def test_01_clusters(self): self.services["hosts"][hypervisor_type], zoneid=self.zone.id, podid=self.pod.id, - hypervisor=self.hypervisor + hypervisor=v["hypervisor"].lower() ) if host == FAILED: self.fail("Host Creation Failed") @@ -112,9 +114,8 @@ def test_01_clusters(self): host.id, cluster.id )) - - #Cleanup Host & Cluster - self.cleanup.append(host) + #Cleanup Host & Cluster + self.cleanup.append(host) self.cleanup.append(cluster) list_hosts_response = list_hosts( @@ -162,8 +163,8 @@ def test_01_clusters(self): "Check cluster ID with list clusters response" ) self.assertEqual( - cluster_response.hypervisortype, - cluster.hypervisortype, + cluster_response.hypervisortype.lower(), + cluster.hypervisortype.lower(), "Check hypervisor type with is " + v["hypervisor"] + " or not" ) return diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index 397d43b63a..08ec0d3fbc 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -5,9 +5,9 @@ # 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 @@ -160,16 +160,10 @@ def test_public_ip_admin_account(self): self.apiclient, id=ip_address.ipaddress.id ) - self.assertEqual( - isinstance(list_pub_ip_addr_resp, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_pub_ip_addr_resp), - 0, - "Check if the list public ip api response is not zero" - ) + if list_pub_ip_addr_resp is None: + return + if (list_pub_ip_addr_resp) and (isinstance(list_pub_ip_addr_resp, list)) and (len(list_pub_ip_addr_resp) > 0): + self.fail("list public ip response is not empty") return @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") @@ -328,7 +322,7 @@ def test_01_port_fwd_on_src_nat(self): 'Running', "VM state should be Running before creating a NAT rule." ) - # Open up firewall port for SSH + # Open up firewall port for SSH fw_rule = FireWallRule.create( self.apiclient, ipaddressid=src_nat_ip_addr.id, @@ -381,7 +375,7 @@ def test_01_port_fwd_on_src_nat(self): ) if vm_response[0].state != 'Running': self.fail("State of VM : %s is not found to be Running" % str(self.virtual_machine.ipaddress)) - + except Exception as e: self.fail( "SSH Access failed for %s: %s" % \ @@ -451,7 +445,7 @@ def test_02_port_fwd_on_non_src_nat(self): 'Running', "VM state should be Running before creating a NAT rule." ) - # Open up firewall port for SSH + # Open up firewall port for SSH fw_rule = FireWallRule.create( self.apiclient, ipaddressid=ip_address.ipaddress.id, @@ -790,7 +784,6 @@ def test_releaseIP(self): retriesCount = 10 isIpAddressDisassociated = False - while retriesCount > 0: listResponse = list_publicIP( self.apiclient, diff --git a/test/integration/smoke/test_routers.py b/test/integration/smoke/test_routers.py index f5cc9a5394..f77d11a06f 100644 --- a/test/integration/smoke/test_routers.py +++ b/test/integration/smoke/test_routers.py @@ -5,9 +5,9 @@ # 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 @@ -183,6 +183,7 @@ def test_01_router_internal_basic(self): return + @attr(tags = ["advanced", "advancedns"], required_hardware="false") def test_02_router_internal_adv(self): """Test router internal advanced zone @@ -203,7 +204,6 @@ def test_02_router_internal_adv(self): True, "Check list response returns a valid list" ) - router = list_router_response[0] hosts = list_hosts( @@ -252,7 +252,6 @@ def test_02_router_internal_adv(self): self.skipTest("Marvin configuration has no host credentials to check router services") res = str(result) self.debug("Dnsmasq process status: %s" % res) - self.assertEqual( res.count("running"), 1, @@ -461,7 +460,6 @@ def test_04_restart_network_wo_cleanup(self): ) except KeyError: self.skipTest("Marvin configuration has no host credentials to check router services") - # res = 12:37:14 up 1 min, 0 users, load average: 0.61, 0.22, 0.08 # Split result to check the uptime result = res[0].split() @@ -653,7 +651,6 @@ def test_07_stop_router(self): "Check list response returns a valid list" ) router = list_router_response[0] - self.debug("Stopping the router with ID: %s" % router.id) #Stop the router cmd = stopRouter.stopRouterCmd() @@ -723,6 +720,13 @@ def test_08_start_router(self): ) return + def verifyRouterResponse(self,router_response,ip): + if (router_response) and (isinstance(router_response, list)) and \ + (router_response[0].state == "Running") and \ + (router_response[0].publicip == ip): + return True + return False + @attr(tags = ["advanced", "advancedns", "smoke"], required_hardware="false") def test_09_reboot_router(self): """Test reboot router @@ -746,32 +750,22 @@ def test_09_reboot_router(self): public_ip = router.publicip self.debug("Rebooting the router with ID: %s" % router.id) - #Reboot the router cmd = rebootRouter.rebootRouterCmd() cmd.id = router.id self.apiclient.rebootRouter(cmd) #List routers to check state of router - router_response = list_routers( + retries_cnt = 6 + while retries_cnt >= 0: + router_response = list_routers( self.apiclient, id=router.id ) - self.assertEqual( - isinstance(router_response, list), - True, - "Check list response returns a valid list" - ) - #List router should have router in running state and same public IP - self.assertEqual( - router_response[0].state, - 'Running', - "Check list router response for router state" - ) - - self.assertEqual( - router_response[0].publicip, - public_ip, - "Check list router response for router public IP" - ) + if self.verifyRouterResponse(router_response,public_ip): + self.debug("Router is running successfully after reboot") + return + time.sleep(10) + retries_cnt = retries_cnt - 1 + self.fail("Router response after reboot is either is invalid or in stopped state") return diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index a787d86ed2..13868301bb 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -498,14 +498,14 @@ def test_08_migrate_vm(self): # For XenServer and VMware, migration is possible between hosts belonging to different clusters # with the help of XenMotion and Vmotion respectively. - if hypervisor == "kvm": + if hypervisor.lower() in ["kvm","simulator"]: #identify suitable host clusters = [h.clusterid for h in hosts] #find hosts withe same clusterid clusters = [cluster for index, cluster in enumerate(clusters) if clusters.count(cluster) > 1] if len(clusters) <= 1: - self.skipTest("In KVM, Live Migration needs two hosts within same cluster") + self.skipTest("In " + hypervisor.lower() + " Live Migration needs two hosts within same cluster") suitable_hosts = [host for host in hosts if host.clusterid == clusters[0]] else: @@ -548,7 +548,7 @@ def test_08_migrate_vm(self): @attr(configuration = "expunge.interval") @attr(configuration = "expunge.delay") - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") + @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"],BugId="CLOUDSTACK-6708", required_hardware="false") def test_09_expunge_vm(self): """Test destroy(expunge) Virtual Machine """ @@ -576,7 +576,7 @@ def test_09_expunge_vm(self): name='expunge.interval' ) expunge_cycle = int(config[0].value) - wait_time = expunge_cycle * 2 + wait_time = expunge_cycle * 4 while wait_time >= 0: list_vm_response = VirtualMachine.list( self.apiclient, From 87effa40ea267d2e334aadb0a201fc031d9c09a8 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 11 Jul 2014 13:46:29 -0700 Subject: [PATCH 048/819] UI > IP Address > hide EnableVPN option on acquired IP. --- ui/scripts/network.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 2039aa047e..3c8107b95e 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -248,6 +248,7 @@ disallowedActions.push('disableStaticNAT'); disallowedActions.push('remove'); } else { //non-sourceNAT IP supports staticNAT + disallowedActions.push('enableVPN'); if (ipObj.isstaticnat) { disallowedActions.push('enableStaticNAT'); } else { From bfb28da9fced01987796efd4cebd5766eb77a06e Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Fri, 11 Jul 2014 14:42:46 -0700 Subject: [PATCH 049/819] Trim postfix appended to the disk name by vCenter after snapshot operation when we are locating disk chain by name --- .../hypervisor/vmware/mo/VirtualMachineMO.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index df05f8aa56..e8d91f6e8a 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -34,6 +34,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.google.gson.Gson; @@ -1939,14 +1940,28 @@ public void ensureScsiDeviceController() throws Exception { } } + private static String trimSnapshotDeltaPostfix(String name) { + String[] tokens = name.split("-"); + if (tokens.length > 1 && tokens[tokens.length - 1].matches("[0-9]{6,}")) { + List trimmedTokens = new ArrayList(); + for (int i = 0; i < tokens.length - 1; i++) + trimmedTokens.add(tokens[i]); + return StringUtils.join(trimmedTokens, "-"); + } + return name; + } + // return pair of VirtualDisk and disk device bus name(ide0:0, etc) public Pair getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception { List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath); DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath); String srcBaseName = dsSrcFile.getFileBaseName(); + srcBaseName = trimSnapshotDeltaPostfix(srcBaseName); + + s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with trimmed base name: " + srcBaseName); + if (devices != null && devices.size() > 0) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { From 7098367dc6d2b245e321546cae47e2c31c88b07a Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 9 Jul 2014 10:50:07 -0700 Subject: [PATCH 050/819] Fixed code causing warnings in ActionEventUtils --- server/src/com/cloud/event/ActionEventUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 2b3cfea4fe..68a328b820 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -204,7 +204,7 @@ private static void publishOnEventBus(long userId, long accountId, String eventC String entityType = null; String entityUuid = null; CallContext context = CallContext.current(); - Class entityKey = getEntityKey(eventType); + Class entityKey = getEntityKey(eventType); if (entityKey != null){ //FIXME - Remove this since it should be covered by the else if condition below. entityUuid = (String)context.getContextParameter(entityKey); @@ -212,7 +212,7 @@ private static void publishOnEventBus(long userId, long accountId, String eventC entityType = entityKey.getName(); }else if (EventTypes.getEntityClassForEvent(eventType) != null){ //Get entity Class(Example - VirtualMachine.class) from the event Type eg. - VM.CREATE - Class entityClass = EventTypes.getEntityClassForEvent(eventType); + Class entityClass = EventTypes.getEntityClassForEvent(eventType); //Get uuid from id if(context.getContextParameter(entityClass.getName()) != null){ @@ -260,7 +260,7 @@ private static void publishOnEventBus(long userId, long accountId, String eventC } } - private static String getEntityUuid(Class entityType, Object entityId){ + private static String getEntityUuid(Class entityType, Object entityId){ // entityId can be internal db id or UUID so accordingly call findbyId or return uuid directly @@ -300,7 +300,7 @@ private static void populateFirstClassEntities(Map eventDescript for(Map.Entry entry : contextMap.entrySet()){ try{ Object key = entry.getKey(); - Class clz = Class.forName((String)key); + Class clz = Class.forName((String)key); if(clz instanceof Class && Identity.class.isAssignableFrom(clz)){ String uuid = getEntityUuid(clz, entry.getValue()); eventDescription.put(ReflectUtil.getEntityName(clz), uuid); @@ -312,7 +312,7 @@ private static void populateFirstClassEntities(Map eventDescript } - private static Class getEntityKey(String eventType) + private static Class getEntityKey(String eventType) { // FIXME - Remove this if (eventType.startsWith("DOMAIN.")) From a6b42fde55b4ce374369d97916f1c83605f308d9 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 11 Jul 2014 14:59:10 -0700 Subject: [PATCH 051/819] Corrected API doc description for listProjectInvitations/deleteProjectInvitation commands --- .../api/command/user/project/DeleteProjectInvitationCmd.java | 2 +- .../api/command/user/project/ListProjectInvitationsCmd.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java b/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java index 9f8baad640..736a800888 100644 --- a/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java @@ -31,7 +31,7 @@ import com.cloud.event.EventTypes; import com.cloud.user.Account; -@APICommand(name = "deleteProjectInvitation", description = "Accepts or declines project invitation", responseObject = SuccessResponse.class, since = "3.0.0", +@APICommand(name = "deleteProjectInvitation", description = "Deletes project invitation", responseObject = SuccessResponse.class, since = "3.0.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DeleteProjectInvitationCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteProjectInvitationCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java b/api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java index dc607e4faf..f34f4226b0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java @@ -27,7 +27,7 @@ import org.apache.cloudstack.api.response.ProjectResponse; @APICommand(name = "listProjectInvitations", - description = "Lists projects and provides detailed information for listed projects", + description = "Lists project invitations and provides detailed information for listed invitations", responseObject = ProjectInvitationResponse.class, since = "3.0.0", requestHasSensitiveInfo = false, From 63b81995f6f85238866fc388d04b16955354099d Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 11 Jul 2014 16:01:34 -0700 Subject: [PATCH 052/819] CLOUDSTACK-7100: update global config - trim leading and trailing whitespaces before global config value update --- .../com/cloud/configuration/ConfigurationManagerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 897f8e1ce9..1940f4839a 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -432,7 +432,6 @@ public boolean stop() { @Override @DB public String updateConfiguration(long userId, String name, String category, String value, String scope, Long resourceId) { - String validationMsg = validateConfigurationValue(name, value, scope); if (validationMsg != null) { @@ -653,7 +652,9 @@ public Configuration updateConfiguration(UpdateCfgCmd cmd) throws InvalidParamet return _configDao.findByName(name); } - if (value.trim().isEmpty() || value.equals("null")) { + value = value.trim(); + + if (value.isEmpty() || value.equals("null")) { value = null; } From 388210c8f91756c42c13ec670387266354cadb1d Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 11 Jul 2014 17:39:40 -0700 Subject: [PATCH 053/819] Add more logs for MS cluster manager --- .../com/cloud/cluster/ClusterManagerImpl.java | 19 +++++++++++-------- .../dao/ManagementServerHostDaoImpl.java | 6 ++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index 4a0987f902..5a70ca5d4b 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -542,7 +542,7 @@ protected void runInContext() { s_logger.trace("Cluster manager heartbeat update, id:" + _mshostId); } - _mshostDao.update(_mshostId, getCurrentRunId(), DateUtil.currentGMTTime()); + _mshostDao.update(_mshostId, _runId, DateUtil.currentGMTTime()); profilerHeartbeatUpdate.stop(); profilerPeerScan.start(); @@ -934,7 +934,7 @@ private static ManagementServerHostVO getInListById(Long id, List() { @@ -948,7 +948,7 @@ public ManagementServerHostVO doInTransaction(TransactionStatus status) { if (mshost == null) { mshost = new ManagementServerHostVO(); mshost.setMsid(_msId); - mshost.setRunid(getCurrentRunId()); + mshost.setRunid(_runId); mshost.setName(NetUtils.getHostName()); mshost.setVersion(version); mshost.setServiceIP(_clusterNodeIP); @@ -960,15 +960,14 @@ public ManagementServerHostVO doInTransaction(TransactionStatus status) { _mshostDao.persist(mshost); if (s_logger.isInfoEnabled()) { - s_logger.info("New instance of management server msid " + _msId + " is being started"); + s_logger.info("New instance of management server msid " + _msId + ", runId " + _runId + " is being started"); } } else { + _mshostDao.update(mshost.getId(), _runId, NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), + DateUtil.currentGMTTime()); if (s_logger.isInfoEnabled()) { - s_logger.info("Management server " + _msId + " is being started"); + s_logger.info("Management server " + _msId + ", runId " + _runId + " is being started"); } - - _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), - DateUtil.currentGMTTime()); } return mshost; @@ -996,6 +995,10 @@ public ManagementServerHostVO doInTransaction(TransactionStatus status) { @Override @DB public boolean stop() { + if (s_logger.isInfoEnabled()) { + s_logger.info("Stopping Cluster manager, msid : " + _msId); + } + if (_mshostId != null) { ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId); mshost.setState(ManagementServerHost.State.Down); diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 3d0c3f5630..97b9a54e00 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -142,7 +142,8 @@ public void update(long id, long runid, Date lastUpdate) { txn.commit(); if (count < 1) { - throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runid + " is no longer valid")); + s_logger.info("Invalid cluster session detected, runId " + runid + " is no longer valid"); + throw new CloudRuntimeException("Invalid cluster session detected, runId " + runid + " is no longer valid", new ClusterInvalidSessionException("runId " + runid + " is no longer valid")); } } catch (Exception e) { s_logger.warn("Unexpected exception, ", e); @@ -222,7 +223,8 @@ public void update(long id, long runId, State state, Date lastUpdate) { int count = pstmt.executeUpdate(); if (count < 1) { - throw new CloudRuntimeException("Invalid cluster session detected", new ClusterInvalidSessionException("runid " + runId + " is no longer valid")); + s_logger.info("Invalid cluster session detected, runId " + runId + " is no longer valid"); + throw new CloudRuntimeException("Invalid cluster session detected, runId " + runId + " is no longer valid", new ClusterInvalidSessionException("runId " + runId + " is no longer valid")); } } catch (SQLException e) { throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); From e7392cdac63f1fb835599ef1545139bf6165a078 Mon Sep 17 00:00:00 2001 From: ynojima Date: Sat, 12 Jul 2014 00:22:06 -0600 Subject: [PATCH 054/819] Remove "--output" option from qemu-img info command call since the option is not supported by qemu-img in CentOS 6.3 --- .../kvm/storage/LibvirtStorageAdaptor.java | 14 ++++---- .../apache/cloudstack/utils/qemu/QemuImg.java | 36 ++++++++++++------- .../cloudstack/utils/qemu/QemuImgTest.java | 16 ++++----- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index ecf3e0851d..e9c588e81f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -674,8 +674,8 @@ private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) { String volPath = pool.getLocalPath() + "/" + name; String volName = name; - long volAllocation = 0; - long volCapacity = 0; + long virtualSize = 0; + long actualSize = 0; final int timeout = 0; @@ -691,8 +691,8 @@ private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool try{ qemu.create(destFile, options); Map info = qemu.info(destFile); - volAllocation = Long.parseLong(info.get(new String("virtual-size"))); - volCapacity = Long.parseLong(info.get(new String("actual-size"))); + virtualSize = Long.parseLong(info.get(new String("virtual_size"))); + actualSize = new File(destFile.getFileName()).length(); } catch (QemuImgException e) { s_logger.error("Failed to create " + volPath + " due to a failed executing of qemu-img: " + e.getMessage()); @@ -700,8 +700,8 @@ private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool); disk.setFormat(format); - disk.setSize(volAllocation); - disk.setVirtualSize(volCapacity); + disk.setSize(actualSize); + disk.setVirtualSize(virtualSize); return disk; } @@ -1189,7 +1189,7 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt srcFile = new QemuImgFile(sourcePath, sourceFormat); try { Map info = qemu.info(srcFile); - String backingFile = info.get(new String("backing-file")); + String backingFile = info.get(new String("backing_file")); // qcow2 templates can just be copied into place if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) { String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout); diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java index 56ed607806..389ac21913 100644 --- a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java +++ b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java @@ -16,16 +16,13 @@ // under the License. package org.apache.cloudstack.utils.qemu; +import java.util.HashMap; import java.util.Map; import com.cloud.storage.Storage; import com.cloud.utils.script.Script; import com.cloud.utils.script.OutputInterpreter; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import org.apache.commons.lang.NotImplementedException; - -import java.lang.reflect.Type; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class QemuImg { @@ -285,9 +282,9 @@ public void commit(QemuImgFile file) throws QemuImgException { * Qemu-img returns human readable output, but this method does it's best * to turn that into machine readeable data. * - * Spaces in keys are replaced by hyphen-minus (-). - * Sizes (virtual-size and disk-size) are returned in bytes - * Paths (image and backing-file) are the absolute path to the file + * Spaces in keys are replaced by underscores (_). + * Sizes (virtual_size and disk_size) are returned in bytes + * Paths (image and backing_file) are the absolute path to the file * * @param file * A QemuImgFile object containing the file to get the information from @@ -296,8 +293,6 @@ public void commit(QemuImgFile file) throws QemuImgException { public Map info(QemuImgFile file) throws QemuImgException { Script s = new Script(_qemuImgPath); s.add("info"); - s.add("--output"); - s.add("json"); s.add(file.getFileName()); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = s.execute(parser); @@ -305,9 +300,24 @@ public Map info(QemuImgFile file) throws QemuImgException { throw new QemuImgException(result); } - Type stringStringMap = new TypeToken>(){}.getType(); - Gson gson = new Gson(); - return gson.fromJson(parser.getLines(), stringStringMap); + HashMap info = new HashMap(); + String[] outputBuffer = parser.getLines().trim().split("\n"); + for (int i = 0; i < outputBuffer.length; i++) { + String[] lineBuffer = outputBuffer[i].split(":", 2); + if (lineBuffer.length == 2) { + String key = lineBuffer[0].trim().replace(" ", "_"); + String value = null; + + if (key.equals("virtual_size")) { + value = lineBuffer[1].trim().replaceAll("^.*\\(([0-9]+).*$", "$1"); + } else { + value = lineBuffer[1].trim(); + } + + info.put(key, value); + } + } + return info; } /* List, apply, create or delete snapshots in image */ diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java index 9059f8cb48..e81890a983 100644 --- a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java +++ b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java @@ -51,7 +51,7 @@ public void testCreateAndInfo() throws QemuImgException { fail("We didn't get any information back from qemu-img"); } - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(size), Long.valueOf(infoSize)); String infoPath = info.get(new String("image")); @@ -78,13 +78,13 @@ public void testCreateAndInfoWithOptions() throws QemuImgException { qemu.create(file, options); Map info = qemu.info(file); - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(size), Long.valueOf(infoSize)); String infoPath = info.get(new String("image")); assertEquals(filename, infoPath); - String infoClusterSize = info.get(new String("cluster-size")); + String infoClusterSize = info.get(new String("cluster_size")); assertEquals(clusterSize, infoClusterSize); File f = new File(filename); @@ -135,7 +135,7 @@ public void testCreateAndResize() throws QemuImgException { fail("We didn't get any information back from qemu-img"); } - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(endSize), Long.valueOf(infoSize)); } catch (QemuImgException e) { fail(e.getMessage()); @@ -164,7 +164,7 @@ public void testCreateAndResizeDeltaPositive() throws QemuImgException { fail("We didn't get any information back from qemu-img"); } - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(startSize + increment), Long.valueOf(infoSize)); } catch (QemuImgException e) { fail(e.getMessage()); @@ -192,7 +192,7 @@ public void testCreateAndResizeDeltaNegative() throws QemuImgException { fail("We didn't get any information back from qemu-img"); } - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(startSize + increment), Long.valueOf(infoSize)); } catch (QemuImgException e) { fail(e.getMessage()); @@ -255,7 +255,7 @@ public void testCreateWithBackingFile() throws QemuImgException { fail("We didn't get any information back from qemu-img"); } - String backingFile = info.get(new String("backing-file")); + String backingFile = info.get(new String("backing_file")); if (backingFile == null) { fail("The second file does not have a property backing_file! Create failed?"); } @@ -306,7 +306,7 @@ public void testConvertAdvanced() throws QemuImgException { PhysicalDiskFormat infoFormat = PhysicalDiskFormat.valueOf(info.get(new String("format")).toUpperCase()); assertEquals(destFormat, infoFormat); - Long infoSize = Long.parseLong(info.get(new String("virtual-size"))); + Long infoSize = Long.parseLong(info.get(new String("virtual_size"))); assertEquals(Long.valueOf(srcSize), Long.valueOf(infoSize)); File sf = new File(srcFileName); From c12767908deb8f038d62827ae30bd3cfa302c8a6 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 11 Jul 2014 09:09:32 +0200 Subject: [PATCH 055/819] Refactor VirtualRoutingResource, put the ConfigItems in separate classes and create a separate ConfigHelper --- .../resource/virtualnetwork/ConfigHelper.java | 691 +++++++++++++ .../resource/virtualnetwork/ConfigItem.java | 16 + .../virtualnetwork/FileConfigItem.java | 56 ++ .../virtualnetwork/ScriptConfigItem.java | 40 + .../resource/virtualnetwork/VRScripts.java | 40 + .../VirtualRoutingResource.java | 915 ++---------------- .../VirtualRoutingResourceTest.java | 341 ++++--- 7 files changed, 1076 insertions(+), 1023 deletions(-) create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java new file mode 100644 index 0000000000..31ddafb5d7 --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java @@ -0,0 +1,691 @@ +package com.cloud.agent.resource.virtualnetwork; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; + +import com.google.gson.Gson; + +import com.cloud.agent.api.BumpUpPriorityCommand; +import com.cloud.agent.api.SetupGuestNetworkCommand; +import com.cloud.agent.api.routing.CreateIpAliasCommand; +import com.cloud.agent.api.routing.DeleteIpAliasCommand; +import com.cloud.agent.api.routing.DhcpEntryCommand; +import com.cloud.agent.api.routing.DnsMasqConfigCommand; +import com.cloud.agent.api.routing.IpAliasTO; +import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; +import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetMonitorServiceCommand; +import com.cloud.agent.api.routing.SetNetworkACLCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.SetStaticRouteCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; +import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.routing.VpnUsersCfgCommand; +import com.cloud.agent.api.to.DhcpTO; +import com.cloud.agent.api.to.FirewallRuleTO; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.network.HAProxyConfigurator; +import com.cloud.network.LoadBalancerConfigurator; +import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.net.NetUtils; + +public class ConfigHelper { + + public static List generateCommandCfg(NetworkElementCommand cmd) { + List cfg; + if (cmd instanceof SetPortForwardingRulesVpcCommand) { + cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd); + } else if (cmd instanceof SetPortForwardingRulesCommand) { + cfg = generateConfig((SetPortForwardingRulesCommand)cmd); + } else if (cmd instanceof SetStaticRouteCommand) { + cfg = generateConfig((SetStaticRouteCommand)cmd); + } else if (cmd instanceof SetStaticNatRulesCommand) { + cfg = generateConfig((SetStaticNatRulesCommand)cmd); + } else if (cmd instanceof LoadBalancerConfigCommand) { + cfg = generateConfig((LoadBalancerConfigCommand)cmd); + } else if (cmd instanceof SavePasswordCommand) { + cfg = generateConfig((SavePasswordCommand)cmd); + } else if (cmd instanceof DhcpEntryCommand) { + cfg = generateConfig((DhcpEntryCommand)cmd); + } else if (cmd instanceof CreateIpAliasCommand) { + cfg = generateConfig((CreateIpAliasCommand)cmd); + } else if (cmd instanceof DnsMasqConfigCommand) { + cfg = generateConfig((DnsMasqConfigCommand)cmd); + } else if (cmd instanceof DeleteIpAliasCommand) { + cfg = generateConfig((DeleteIpAliasCommand)cmd); + } else if (cmd instanceof VmDataCommand) { + cfg = generateConfig((VmDataCommand)cmd); + } else if (cmd instanceof SetFirewallRulesCommand) { + cfg = generateConfig((SetFirewallRulesCommand)cmd); + } else if (cmd instanceof BumpUpPriorityCommand) { + cfg = generateConfig((BumpUpPriorityCommand)cmd); + } else if (cmd instanceof RemoteAccessVpnCfgCommand) { + cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd); + } else if (cmd instanceof VpnUsersCfgCommand) { + cfg = generateConfig((VpnUsersCfgCommand)cmd); + } else if (cmd instanceof Site2SiteVpnCfgCommand) { + cfg = generateConfig((Site2SiteVpnCfgCommand)cmd); + } else if (cmd instanceof SetMonitorServiceCommand) { + cfg = generateConfig((SetMonitorServiceCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + cfg = generateConfig((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + cfg = generateConfig((SetNetworkACLCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + cfg = generateConfig((SetSourceNatCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + cfg = generateConfig((IpAssocCommand)cmd); + } else { + return null; + } + return cfg; + } + + private static List generateConfig(VpnUsersCfgCommand cmd) { + LinkedList cfg = new LinkedList<>(); + for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { + String args = ""; + if (!userpwd.isAdd()) { + args += "-U "; + args += userpwd.getUsername(); + } else { + args += "-u "; + args += userpwd.getUsernamePassword(); + } + cfg.add(new ScriptConfigItem(VRScripts.VPN_L2TP, args)); + } + return cfg; + } + + private static List generateConfig(RemoteAccessVpnCfgCommand cmd) { + LinkedList cfg = new LinkedList<>(); + String args = ""; + if (cmd.isCreate()) { + args += "-r "; + args += cmd.getIpRange(); + args += " -p "; + args += cmd.getPresharedKey(); + args += " -s "; + args += cmd.getVpnServerIp(); + args += " -l "; + args += cmd.getLocalIp(); + args += " -c "; + } else { + args += "-d "; + args += " -s "; + args += cmd.getVpnServerIp(); + } + args += " -C " + cmd.getLocalCidr(); + args += " -i " + cmd.getPublicInterface(); + cfg.add(new ScriptConfigItem(VRScripts.VPN_L2TP, args)); + return cfg; + } + + private static List generateConfig(SetFirewallRulesCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); + + FirewallRuleTO[] allrules = cmd.getRules(); + FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); + + String[][] rules = cmd.generateFwRules(); + String args = " -F"; + + if (trafficType == FirewallRule.TrafficType.Egress) { + args += " -E"; + if (egressDefault.equals("true")) { + args += " -P 1"; + } else if (egressDefault.equals("System")) { + args += " -P 2"; + } else { + args += " -P 0"; + } + } + + StringBuilder sb = new StringBuilder(); + String[] fwRules = rules[0]; + if (fwRules.length > 0) { + for (int i = 0; i < fwRules.length; i++) { + sb.append(fwRules[i]).append(','); + } + args += " -a " + sb.toString(); + } + + if (trafficType == FirewallRule.TrafficType.Egress) { + cfg.add(new ScriptConfigItem(VRScripts.FIREWALL_EGRESS, args)); + } else { + cfg.add(new ScriptConfigItem(VRScripts.FIREWALL_INGRESS, args)); + } + + return cfg; + } + + private static List generateConfig(SetPortForwardingRulesCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + for (PortForwardingRuleTO rule : cmd.getRules()) { + StringBuilder args = new StringBuilder(); + args.append(rule.revoked() ? "-D" : "-A"); + args.append(" -P ").append(rule.getProtocol().toLowerCase()); + args.append(" -l ").append(rule.getSrcIp()); + args.append(" -p ").append(rule.getStringSrcPortRange()); + args.append(" -r ").append(rule.getDstIp()); + args.append(" -d ").append(rule.getStringDstPortRange()); + cfg.add(new ScriptConfigItem(VRScripts.FIREWALL_NAT, args.toString())); + } + + return cfg; + } + + private static List generateConfig(SetStaticNatRulesCommand cmd) { + LinkedList cfg = new LinkedList<>(); + if (cmd.getVpcId() != null) { + for (StaticNatRuleTO rule : cmd.getRules()) { + String args = rule.revoked() ? " -D" : " -A"; + args += " -l " + rule.getSrcIp(); + args += " -r " + rule.getDstIp(); + + cfg.add(new ScriptConfigItem(VRScripts.VPC_STATIC_NAT, args)); + } + } else { + for (StaticNatRuleTO rule : cmd.getRules()) { + //1:1 NAT needs instanceip;publicip;domrip;op + StringBuilder args = new StringBuilder(); + args.append(rule.revoked() ? " -D " : " -A "); + args.append(" -l ").append(rule.getSrcIp()); + args.append(" -r ").append(rule.getDstIp()); + + if (rule.getProtocol() != null) { + args.append(" -P ").append(rule.getProtocol().toLowerCase()); + } + + args.append(" -d ").append(rule.getStringSrcPortRange()); + args.append(" -G "); + + cfg.add(new ScriptConfigItem(VRScripts.FIREWALL_NAT, args.toString())); + } + } + return cfg; + } + + private static List generateConfig(LoadBalancerConfigCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); + + String[] config = cfgtr.generateConfiguration(cmd); + StringBuffer buff = new StringBuffer(); + for (int i = 0; i < config.length; i++) { + buff.append(config[i]); + buff.append("\n"); + } + String tmpCfgFilePath = "/etc/haproxy/"; + String tmpCfgFileName = "haproxy.cfg.new." + String.valueOf(System.currentTimeMillis()); + cfg.add(new FileConfigItem(tmpCfgFilePath, tmpCfgFileName, buff.toString())); + + String[][] rules = cfgtr.generateFwRules(cmd); + + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; + + String args = " -f " + tmpCfgFilePath + tmpCfgFileName; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); + } + args += " -a " + sb.toString(); + } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + if (cmd.getVpcId() == null) { + args = " -i " + routerIp + args; + cfg.add(new ScriptConfigItem(VRScripts.LB, args)); + } else { + args = " -i " + cmd.getNic().getIp() + args; + cfg.add(new ScriptConfigItem(VRScripts.VPC_LB, args)); + } + + return cfg; + } + + private static List generateConfig(VmDataCommand cmd) { + LinkedList cfg = new LinkedList<>(); + Map> data = new HashMap>(); + data.put(cmd.getVmIpAddress(), cmd.getVmData()); + + String json = new Gson().toJson(data); + + json = Base64.encodeBase64String(json.getBytes()); + + String args = "-d " + json; + + cfg.add(new ScriptConfigItem(VRScripts.VMDATA, args)); + return cfg; + } + + private static List generateConfig(SavePasswordCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + final String password = cmd.getPassword(); + final String vmIpAddress = cmd.getVmIpAddress(); + + String args = "-v " + vmIpAddress; + args += " -p " + password; + + cfg.add(new ScriptConfigItem(VRScripts.PASSWORD, args)); + return cfg; + } + + private static List generateConfig(DhcpEntryCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String args = " -m " + cmd.getVmMac(); + if (cmd.getVmIpAddress() != null) { + args += " -4 " + cmd.getVmIpAddress(); + } + args += " -h " + cmd.getVmName(); + + if (cmd.getDefaultRouter() != null) { + args += " -d " + cmd.getDefaultRouter(); + } + + if (cmd.getDefaultDns() != null) { + args += " -n " + cmd.getDefaultDns(); + } + + if (cmd.getStaticRoutes() != null) { + args += " -s " + cmd.getStaticRoutes(); + } + + if (cmd.getVmIp6Address() != null) { + args += " -6 " + cmd.getVmIp6Address(); + args += " -u " + cmd.getDuid(); + } + + if (!cmd.isDefault()) { + args += " -N"; + } + cfg.add(new ScriptConfigItem(VRScripts.DHCP, args)); + + return cfg; + } + + private static List generateConfig(CreateIpAliasCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + List ipAliasTOs = cmd.getIpAliasList(); + String args = ""; + for (IpAliasTO ipaliasto : ipAliasTOs) { + args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; + } + + cfg.add(new ScriptConfigItem(VRScripts.IPALIAS_CREATE, args)); + return cfg; + } + + private static List generateConfig(DeleteIpAliasCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + StringBuffer buff = new StringBuffer(); + List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); + for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { + buff.append(ipAliasTO.getAlias_count()); + buff.append(":"); + buff.append(ipAliasTO.getRouterip()); + buff.append(":"); + buff.append(ipAliasTO.getNetmask()); + buff.append("-"); + } + //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. + buff.append("- "); + List activeIpAliasTOs = cmd.getCreateIpAliasTos(); + for (IpAliasTO ipAliasTO : activeIpAliasTOs) { + buff.append(ipAliasTO.getAlias_count()); + buff.append(":"); + buff.append(ipAliasTO.getRouterip()); + buff.append(":"); + buff.append(ipAliasTO.getNetmask()); + buff.append("-"); + } + cfg.add(new ScriptConfigItem(VRScripts.IPALIAS_DELETE, buff.toString())); + return cfg; + } + + private static List generateConfig(DnsMasqConfigCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + List dhcpTos = cmd.getIps(); + StringBuffer buff = new StringBuffer(); + for (DhcpTO dhcpTo : dhcpTos) { + buff.append(dhcpTo.getRouterIp()); + buff.append(":"); + buff.append(dhcpTo.getGateway()); + buff.append(":"); + buff.append(dhcpTo.getNetmask()); + buff.append(":"); + buff.append(dhcpTo.getStartIpOfSubnet()); + buff.append("-"); + } + cfg.add(new ScriptConfigItem(VRScripts.DNSMASQ_CONFIG, buff.toString())); + return cfg; + } + + private static List generateConfig(BumpUpPriorityCommand cmd) { + LinkedList cfg = new LinkedList<>(); + cfg.add(new ScriptConfigItem(VRScripts.RVR_BUMPUP_PRI, null)); + return cfg; + } + + private static List generateConfig(Site2SiteVpnCfgCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String args = ""; + if (cmd.isCreate()) { + args += "-A"; + args += " -l "; + args += cmd.getLocalPublicIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -g "; + args += cmd.getLocalPublicGateway(); + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + args += " -e "; + args += "\"" + cmd.getEspPolicy() + "\""; + args += " -i "; + args += "\"" + cmd.getIkePolicy() + "\""; + args += " -t "; + args += Long.toString(cmd.getIkeLifetime()); + args += " -T "; + args += Long.toString(cmd.getEspLifetime()); + args += " -s "; + args += "\"" + cmd.getIpsecPsk() + "\""; + args += " -d "; + if (cmd.getDpd()) { + args += "1"; + } else { + args += "0"; + } + if (cmd.isPassive()) { + args += " -p "; + } + } else { + args += "-D"; + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + } + + cfg.add(new ScriptConfigItem(VRScripts.S2SVPN_IPSEC, args)); + return cfg; + } + + private static List generateConfig(SetMonitorServiceCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String config = cmd.getConfiguration(); + String disableMonitoring = cmd.getAccessDetail(NetworkElementCommand.ROUTER_MONITORING_ENABLE); + + String args = " -c " + config; + if (disableMonitoring != null) { + args = args + " -d"; + } + + cfg.add(new ScriptConfigItem(VRScripts.MONITOR_SERVICE, args)); + return cfg; + } + + private static List generateConfig(SetupGuestNetworkCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + NicTO nic = cmd.getNic(); + String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2 = cmd.getDefaultDns2(); + if (dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + String dev = "eth" + nic.getDeviceId(); + String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); + String args = ""; + if (cmd.isAdd() == false) { + //pass the argument to script to delete the network + args += " -D"; + } else { + // pass create option argument if the ip needs to be added to eth device + args += " -C"; + } + args += " -M " + nic.getMac(); + args += " -d " + dev; + args += " -i " + routerGIP; + args += " -g " + gateway; + args += " -m " + cidr; + args += " -n " + netmask; + if (dns != null && !dns.isEmpty()) { + args += " -s " + dns; + } + if (domainName != null && !domainName.isEmpty()) { + args += " -e " + domainName; + } + + cfg.add(new ScriptConfigItem(VRScripts.VPC_GUEST_NETWORK, args)); + return cfg; + } + + private static List generateConfig(SetNetworkACLCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + + String[][] rules = cmd.generateFwRules(); + String[] aclRules = rules[0]; + NicTO nic = cmd.getNic(); + String dev = "eth" + nic.getDeviceId(); + String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + String rule = sb.toString(); + + String args = " -d " + dev; + args += " -M " + nic.getMac(); + if (privateGw != null) { + args += " -a " + rule; + + cfg.add(new ScriptConfigItem(VRScripts.VPC_PRIVATEGW_ACL, args)); + } else { + args += " -i " + nic.getIp(); + args += " -m " + netmask; + args += " -a " + rule; + cfg.add(new ScriptConfigItem(VRScripts.VPC_ACL, args)); + } + + return cfg; + } + + private static List generateConfig(SetSourceNatCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + IpAddressTO pubIP = cmd.getIpAddress(); + String dev = "eth" + pubIP.getNicDevId(); + String args = "-A"; + args += " -l "; + args += pubIP.getPublicIp(); + args += " -c "; + args += dev; + + cfg.add(new ScriptConfigItem(VRScripts.VPC_SOURCE_NAT, args)); + return cfg; + } + + private static List generateConfig(SetPortForwardingRulesVpcCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + for (PortForwardingRuleTO rule : cmd.getRules()) { + String args = rule.revoked() ? "-D" : "-A"; + args += " -P " + rule.getProtocol().toLowerCase(); + args += " -l " + rule.getSrcIp(); + args += " -p " + rule.getStringSrcPortRange(); + args += " -r " + rule.getDstIp(); + args += " -d " + rule.getStringDstPortRange().replace(":", "-"); + + cfg.add(new ScriptConfigItem(VRScripts.VPC_PORTFORWARDING, args)); + } + + return cfg; + } + + private static List generateConfig(SetStaticRouteCommand cmd) { + LinkedList cfg = new LinkedList<>(); + + String[][] rules = cmd.generateSRouteRules(); + StringBuilder sb = new StringBuilder(); + String[] srRules = rules[0]; + + for (int i = 0; i < srRules.length; i++) { + sb.append(srRules[i]).append(','); + } + + String args = " -a " + sb.toString(); + + cfg.add(new ScriptConfigItem(VRScripts.VPC_STATIC_ROUTE, args)); + return cfg; + } + + private static List generateConfig(IpAssocCommand cmd) { + LinkedList cfg = new LinkedList<>(); + ConfigItem c; + + //Gson gson = new Gson(); + //ConfigItem ipAssociationsFile = new FileConfigItem(VRScripts.CONFIG_PERSIST_LOCATION, VRScripts.IP_ASSOCIATION_CONFIG, gson.toJson(cmd.getIpAddresses())); + //cfg.add(ipAssociationsFile); + + if (cmd instanceof IpAssocVpcCommand) { + for (IpAddressTO ip : cmd.getIpAddresses()) { + String args = ""; + String snatArgs = ""; + + if (ip.isAdd()) { + args += " -A "; + snatArgs += " -A "; + } else { + args += " -D "; + snatArgs += " -D "; + } + + args += " -l "; + args += ip.getPublicIp(); + String nicName = "eth" + ip.getNicDevId(); + args += " -c "; + args += nicName; + args += " -g "; + args += ip.getVlanGateway(); + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + c = new ScriptConfigItem(VRScripts.VPC_IPASSOC, args); + c.setInfo(ip.getPublicIp() + " - vpc_ipassoc"); + cfg.add(c); + + if (ip.isSourceNat()) { + snatArgs += " -l " + ip.getPublicIp(); + snatArgs += " -c " + nicName; + + c = new ScriptConfigItem(VRScripts.VPC_PRIVATEGW, snatArgs); + c.setInfo(ip.getPublicIp() + " - vpc_privategateway"); + cfg.add(c); + } + } + } else { + for (IpAddressTO ip : cmd.getIpAddresses()) { + String args = ""; + if (ip.isAdd()) { + args += "-A"; + } else { + args += "-D"; + } + String cidrSize = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + if (ip.isSourceNat()) { + args += " -s"; + } + if (ip.isFirstIP()) { + args += " -f"; + } + args += " -l "; + args += ip.getPublicIp() + "/" + cidrSize; + + String publicNic = "eth" + ip.getNicDevId(); + args += " -c "; + args += publicNic; + + args += " -g "; + args += ip.getVlanGateway(); + + if (ip.isNewNic()) { + args += " -n"; + } + + c = new ScriptConfigItem(VRScripts.IPASSOC, args); + c.setInfo(ip.getPublicIp()); + cfg.add(c); + } + } + return cfg; + } + +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java new file mode 100644 index 0000000000..0d622ce29a --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java @@ -0,0 +1,16 @@ +package com.cloud.agent.resource.virtualnetwork; + +public abstract class ConfigItem { + private String info; + + + public String getInfo() { + return info; + } + + public void setInfo(String info) { + this.info = info; + } + + public abstract String getAggregateCommand(); +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java new file mode 100644 index 0000000000..20a09aa391 --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java @@ -0,0 +1,56 @@ +package com.cloud.agent.resource.virtualnetwork; + +public class FileConfigItem extends ConfigItem { + private String filePath; + private String fileName; + private String fileContents; + + public FileConfigItem(String filePath, String fileName, String fileContents) { + this.filePath = filePath; + this.fileName = fileName; + this.fileContents = fileContents; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFileContents() { + return fileContents; + } + + public void setFileContents(String fileContents) { + this.fileContents = fileContents; + } + + @Override + public String getAggregateCommand() { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + sb.append(filePath); + + // Don't use File.pathSeparator here as the target is the unix based systemvm + if (!filePath.endsWith("/")) { + sb.append('/'); + } + + sb.append(fileName); + sb.append('\n'); + sb.append(fileContents); + sb.append("\n\n"); + return sb.toString(); + } + +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java new file mode 100644 index 0000000000..133d2aaae8 --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java @@ -0,0 +1,40 @@ +package com.cloud.agent.resource.virtualnetwork; + +public class ScriptConfigItem extends ConfigItem { + private String script; + private String args; + + public ScriptConfigItem(String script, String args) { + this.script = script; + this.args = args; + } + + public String getScript() { + return script; + } + + public void setScript(String script) { + this.script = script; + } + + public String getArgs() { + return args; + } + + public void setArgs(String args) { + this.args = args; + } + + @Override + public String getAggregateCommand() { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + return sb.toString(); + } + +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java new file mode 100644 index 0000000000..05ddab0987 --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java @@ -0,0 +1,40 @@ +package com.cloud.agent.resource.virtualnetwork; + +public class VRScripts { + protected final static String CONFIG_PERSIST_LOCATION = "/etc/cloudstack/"; + protected final static String IP_ASSOCIATION_CONFIG = "ip_associations.json"; + protected final static String CONFIG_CACHE_LOCATION = "/var/cache/cloud/"; + protected final static int DEFAULT_EXECUTEINVR_TIMEOUT = 120; //Seconds + + protected static final String S2SVPN_CHECK = "checkbatchs2svpn.sh"; + protected static final String S2SVPN_IPSEC = "ipsectunnel.sh"; + protected static final String DHCP = "edithosts.sh"; + protected static final String DNSMASQ_CONFIG = "dnsmasq.sh"; + protected static final String FIREWALL_EGRESS = "firewall_egress.sh"; + protected static final String FIREWALL_INGRESS = "firewall_ingress.sh"; + protected static final String FIREWALL_NAT = "firewall_nat.sh"; + protected static final String IPALIAS_CREATE = "createipAlias.sh"; + protected static final String IPALIAS_DELETE = "deleteipAlias.sh"; + protected static final String IPASSOC = "ipassoc.sh"; + protected static final String LB = "loadbalancer.sh"; + protected static final String MONITOR_SERVICE = "monitor_service.sh"; + protected static final String ROUTER_ALERTS = "getRouterAlerts.sh"; + protected static final String PASSWORD = "savepassword.sh"; + protected static final String RVR_CHECK = "checkrouter.sh"; + protected static final String RVR_BUMPUP_PRI = "bumpup_priority.sh"; + protected static final String VMDATA = "vmdata.py"; + protected static final String VERSION = "get_template_version.sh"; + protected static final String VPC_ACL = "vpc_acl.sh"; + protected static final String VPC_GUEST_NETWORK = "vpc_guestnw.sh"; + protected static final String VPC_IPASSOC = "vpc_ipassoc.sh"; + protected static final String VPC_LB = "vpc_loadbalancer.sh"; + protected static final String VPC_PRIVATEGW = "vpc_privateGateway.sh"; + protected static final String VPC_PRIVATEGW_ACL = "vpc_privategw_acl.sh"; + protected static final String VPC_PORTFORWARDING = "vpc_portforwarding.sh"; + protected static final String VPC_SOURCE_NAT = "vpc_snat.sh"; + protected static final String VPC_STATIC_NAT = "vpc_staticnat.sh"; + protected static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh"; + protected static final String VPN_L2TP = "vpn_l2tp.sh"; + + protected static final String VR_CFG = "vr_cfg.sh"; +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index de1049b1d3..bb2dac9a0c 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -16,71 +16,39 @@ // under the License. package com.cloud.agent.resource.virtualnetwork; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.UUID; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckRouterAnswer; import com.cloud.agent.api.CheckRouterCommand; import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.SetupGuestNetworkCommand; +import com.cloud.agent.api.GetRouterAlertsAnswer; import com.cloud.agent.api.routing.AggregationControlCommand; import com.cloud.agent.api.routing.AggregationControlCommand.Action; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.GroupAnswer; import com.cloud.agent.api.routing.GetRouterAlertsCommand; -import com.cloud.agent.api.GetRouterAlertsAnswer; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.GroupAnswer; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; -import com.cloud.agent.api.to.DhcpTO; -import com.cloud.agent.api.to.FirewallRuleTO; -import com.cloud.agent.api.to.IpAddressTO; -import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; -import com.cloud.network.rules.FirewallRule; import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.net.NetUtils; -import com.google.gson.Gson; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - -import javax.naming.ConfigurationException; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.channels.SocketChannel; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.UUID; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; +import com.cloud.utils.exception.CloudRuntimeException; /** * VirtualNetworkResource controls and configures virtual networking @@ -91,43 +59,10 @@ * } **/ public class VirtualRoutingResource { - protected class VRScripts { - protected static final String S2SVPN_CHECK = "checkbatchs2svpn.sh"; - protected static final String S2SVPN_IPSEC = "ipsectunnel.sh"; - protected static final String DHCP = "edithosts.sh"; - protected static final String DNSMASQ_CONFIG = "dnsmasq.sh"; - protected static final String FIREWALL_EGRESS = "firewall_egress.sh"; - protected static final String FIREWALL_INGRESS = "firewall_ingress.sh"; - protected static final String FIREWALL_NAT = "firewall_nat.sh"; - protected static final String IPALIAS_CREATE = "createipAlias.sh"; - protected static final String IPALIAS_DELETE = "deleteipAlias.sh"; - protected static final String IPASSOC = "ipassoc.sh"; - protected static final String LB = "loadbalancer.sh"; - protected static final String MONITOR_SERVICE = "monitor_service.sh"; - protected static final String ROUTER_ALERTS = "getRouterAlerts.sh"; - protected static final String PASSWORD = "savepassword.sh"; - protected static final String RVR_CHECK = "checkrouter.sh"; - protected static final String RVR_BUMPUP_PRI = "bumpup_priority.sh"; - protected static final String VMDATA = "vmdata.py"; - protected static final String VERSION = "get_template_version.sh"; - protected static final String VPC_ACL = "vpc_acl.sh"; - protected static final String VPC_GUEST_NETWORK = "vpc_guestnw.sh"; - protected static final String VPC_IPASSOC = "vpc_ipassoc.sh"; - protected static final String VPC_LB = "vpc_loadbalancer.sh"; - protected static final String VPC_PRIVATEGW = "vpc_privateGateway.sh"; - protected static final String VPC_PRIVATEGW_ACL = "vpc_privategw_acl.sh"; - protected static final String VPC_PORTFORWARDING = "vpc_portforwarding.sh"; - protected static final String VPC_SOURCE_NAT = "vpc_snat.sh"; - protected static final String VPC_STATIC_NAT = "vpc_staticnat.sh"; - protected static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh"; - protected static final String VPN_L2TP = "vpn_l2tp.sh"; - - protected static final String VR_CFG = "vr_cfg.sh"; - } private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); private VirtualRouterDeployer _vrDeployer; - private Map _vrAggregateCommandsSet; + private Map> _vrAggregateCommandsSet; protected Map _vrLockMap = new HashMap(); private String _name; @@ -139,7 +74,7 @@ protected class VRScripts { private String _cfgVersion = "1.0"; public VirtualRoutingResource(VirtualRouterDeployer deployer) { - this._vrDeployer = deployer; + _vrDeployer = deployer; } public Answer executeRequest(final NetworkElementCommand cmd) { @@ -198,81 +133,6 @@ public Answer executeRequest(final NetworkElementCommand cmd) { } } - protected class ConfigItem { - private String script; - private String args; - private String info; - private String filePath; - private String fileName; - private String fileContents; - private boolean isFile; - - public ConfigItem(String script, String args) { - this.script = script; - this.args = args; - this.isFile = false; - } - - public ConfigItem(String filePath, String fileName, String fileContents) { - this.filePath = filePath; - this.fileName = fileName; - this.fileContents = fileContents; - this.isFile = true; - } - - public String getScript() { - return script; - } - - public void setScript(String script) { - this.script = script; - } - - public String getArgs() { - return args; - } - - public void setArgs(String args) { - this.args = args; - } - - public String getInfo() { - return info; - } - - public void setInfo(String info) { - this.info = info; - } - - public String getFilePath() { - return filePath; - } - - public void setFilePath(String filePath) { - this.filePath = filePath; - } - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public String getFileContents() { - return fileContents; - } - - public void setFileContents(String fileContents) { - this.fileContents = fileContents; - } - - public boolean isFile() { - return isFile; - } - } - private Answer executeQueryCommand(NetworkElementCommand cmd) { if (cmd instanceof CheckRouterCommand) { return execute((CheckRouterCommand)cmd); @@ -288,370 +148,48 @@ private Answer executeQueryCommand(NetworkElementCommand cmd) { } } - private ExecutionResult applyConfigToVR(NetworkElementCommand cmd, ConfigItem c) { - if (c.isFile()) { - return _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), c.getFilePath(), c.getFileName(), c.getFileContents()); - } else { - return _vrDeployer.executeInVR(cmd.getRouterAccessIp(), c.getScript(), c.getArgs()); - } - } - - private Answer applyConfig(NetworkElementCommand cmd, List cfg) { - int answersCount = cmd.getAnswersCount(); - - // Use the last answer as final answer - if (answersCount == 1) { - ExecutionResult result = new ExecutionResult(true, "No configure to be applied"); - for (ConfigItem c : cfg) { - result = applyConfigToVR(cmd, c); - if (!result.isSuccess()) { - break; - } - } - return new Answer(cmd, result.isSuccess(), result.getDetails()); - } - - ExecutionResult[] results = new ExecutionResult[answersCount]; - String[] resultsString = new String[answersCount]; - boolean finalResult = true; - int i = 0, j; - for (ConfigItem c : cfg) { - results[i] = applyConfigToVR(cmd, c); - if (c.getInfo() != null) { - if (results[i].isSuccess()) { - results[i].setDetails(c.getInfo() + " - success: " + results[i].getDetails()); - } else { - results[i].setDetails(c.getInfo() + " - failed: " + results[i].getDetails()); - } - } - i ++; - } - i = 0; j = 0; - while (j < answersCount) { - resultsString[j] = results[i].getDetails(); - if (!results[i].isSuccess()) { - finalResult = false; - } - // Fill the resultsString with the last result of execution, mostly in 1:n - if (i < cfg.size() - 1) { - i ++; - } - j ++; - } - return new GroupAnswer(cmd, finalResult, answersCount, resultsString); - } - - private List generateConfig(VpnUsersCfgCommand cmd) { - LinkedList cfg = new LinkedList<>(); - for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { - String args = ""; - if (!userpwd.isAdd()) { - args += "-U "; - args += userpwd.getUsername(); - } else { - args += "-u "; - args += userpwd.getUsernamePassword(); - } - cfg.add(new ConfigItem(VRScripts.VPN_L2TP, args)); - } - return cfg; + private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c) { + return applyConfigToVR(routerAccessIp, c, VRScripts.DEFAULT_EXECUTEINVR_TIMEOUT); } - private List generateConfig(RemoteAccessVpnCfgCommand cmd) { - LinkedList cfg = new LinkedList<>(); - String args = ""; - if (cmd.isCreate()) { - args += "-r "; - args += cmd.getIpRange(); - args += " -p "; - args += cmd.getPresharedKey(); - args += " -s "; - args += cmd.getVpnServerIp(); - args += " -l "; - args += cmd.getLocalIp(); - args += " -c "; - } else { - args += "-d "; - args += " -s "; - args += cmd.getVpnServerIp(); + private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, int timeout) { + if (c instanceof FileConfigItem) { + FileConfigItem configItem = (FileConfigItem)c; + return _vrDeployer.createFileInVR(routerAccessIp, configItem.getFilePath(), configItem.getFileName(), configItem.getFileContents()); + } else if (c instanceof ScriptConfigItem) { + ScriptConfigItem configItem = (ScriptConfigItem)c; + return _vrDeployer.executeInVR(routerAccessIp, configItem.getScript(), configItem.getArgs(), timeout); } - args += " -C " + cmd.getLocalCidr(); - args += " -i " + cmd.getPublicInterface(); - cfg.add(new ConfigItem(VRScripts.VPN_L2TP, args)); - return cfg; + throw new CloudRuntimeException("Unable to apply unknown configitem of type " + c.getClass().getSimpleName()); } - private List generateConfig(SetFirewallRulesCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - - String[][] rules = cmd.generateFwRules(); - String args = " -F"; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E"; - if (egressDefault.equals("true")) { - args += " -P 1"; - } else if (egressDefault.equals("System")) { - args += " -P 2"; - } else { - args += " -P 0"; - } - } - - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - if (trafficType == FirewallRule.TrafficType.Egress) { - cfg.add(new ConfigItem(VRScripts.FIREWALL_EGRESS, args)); - } else { - cfg.add(new ConfigItem(VRScripts.FIREWALL_INGRESS, args)); - } - - return cfg; - } - - private List generateConfig(SetPortForwardingRulesCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - for (PortForwardingRuleTO rule : cmd.getRules()) { - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? "-D" : "-A"); - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -p ").append(rule.getStringSrcPortRange()); - args.append(" -r ").append(rule.getDstIp()); - args.append(" -d ").append(rule.getStringDstPortRange()); - cfg.add(new ConfigItem(VRScripts.FIREWALL_NAT, args.toString())); - } - - return cfg; - } - - private List generateConfig(SetStaticNatRulesCommand cmd) { - LinkedList cfg = new LinkedList<>(); - if (cmd.getVpcId() != null) { - for (StaticNatRuleTO rule : cmd.getRules()) { - String args = rule.revoked() ? " -D" : " -A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - cfg.add(new ConfigItem(VRScripts.VPC_STATIC_NAT, args)); - } - } else { - for (StaticNatRuleTO rule : cmd.getRules()) { - //1:1 NAT needs instanceip;publicip;domrip;op - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -r ").append(rule.getDstIp()); - - if (rule.getProtocol() != null) { - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - } - - args.append(" -d ").append(rule.getStringSrcPortRange()); - args.append(" -G "); - - cfg.add(new ConfigItem(VRScripts.FIREWALL_NAT, args.toString())); - } - } - return cfg; - } - - private List generateConfig(LoadBalancerConfigCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - - String[] config = cfgtr.generateConfiguration(cmd); - StringBuffer buff = new StringBuffer(); - for (int i = 0; i < config.length; i++) { - buff.append(config[i]); - buff.append("\n"); - } - String tmpCfgFilePath = "/etc/haproxy/"; - String tmpCfgFileName = "haproxy.cfg.new." + String.valueOf(System.currentTimeMillis()); - cfg.add(new ConfigItem(tmpCfgFilePath, tmpCfgFileName, buff.toString())); - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = " -f " + tmpCfgFilePath + tmpCfgFileName; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); + private Answer applyConfig(NetworkElementCommand cmd, List cfg) { + List results = new ArrayList(); + List details = new ArrayList(); + boolean finalResult = false; + for (ConfigItem configItem : cfg) { + ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), configItem); + if (result == null) { + result = new ExecutionResult(false, "null execution result"); } - - args += " -d " + sb.toString(); + results.add(result); + details.add(configItem.getInfo() + (result.isSuccess() ? " - success: " : " - failed: ") + result.getDetails()); + finalResult = result.isSuccess(); } - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); + // Not sure why this matters, but log it anyway + if (cmd.getAnswersCount() != results.size()) { + s_logger.warn("Expected " + cmd.getAnswersCount() + " answers while executing " + cmd.getClass().getSimpleName() + " but received " + results.size()); } - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - cfg.add(new ConfigItem(VRScripts.LB, args)); + if (results.size() == 1) { + return new Answer(cmd, finalResult, results.get(0).getDetails()); } else { - args = " -i " + cmd.getNic().getIp() + args; - cfg.add(new ConfigItem(VRScripts.VPC_LB, args)); - } - - return cfg; - } - - private List generateConfig(VmDataCommand cmd) { - LinkedList cfg = new LinkedList<>(); - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - - String json = new Gson().toJson(data); - s_logger.debug("JSON IS:" + json); - - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; - - cfg.add(new ConfigItem(VRScripts.VMDATA, args)); - return cfg; - } - - private List generateConfig(SavePasswordCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - String args = "-v " + vmIpAddress; - args += " -p " + password; - - cfg.add(new ConfigItem(VRScripts.PASSWORD, args)); - return cfg; - } - - private List generateConfig(DhcpEntryCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); + return new GroupAnswer(cmd, finalResult, results.size(), details.toArray(new String[details.size()])); } - args += " -h " + cmd.getVmName(); - - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } - - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - cfg.add(new ConfigItem(VRScripts.DHCP, args)); - - return cfg; - } - - private List generateConfig(CreateIpAliasCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - - cfg.add(new ConfigItem(VRScripts.IPALIAS_CREATE, args)); - return cfg; } - private List generateConfig(DeleteIpAliasCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String args = ""; - StringBuffer buff = new StringBuffer(); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - buff.append(ipAliasTO.getAlias_count()); - buff.append(":"); - buff.append(ipAliasTO.getRouterip()); - buff.append(":"); - buff.append(ipAliasTO.getNetmask()); - buff.append("-"); - } - //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. - buff.append("- "); - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - buff.append(ipAliasTO.getAlias_count()); - buff.append(":"); - buff.append(ipAliasTO.getRouterip()); - buff.append(":"); - buff.append(ipAliasTO.getNetmask()); - buff.append("-"); - } - cfg.add(new ConfigItem(VRScripts.IPALIAS_DELETE, buff.toString())); - return cfg; - } - - private List generateConfig(DnsMasqConfigCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - List dhcpTos = cmd.getIps(); - StringBuffer buff = new StringBuffer(); - for (DhcpTO dhcpTo : dhcpTos) { - buff.append(dhcpTo.getRouterIp()); - buff.append(":"); - buff.append(dhcpTo.getGateway()); - buff.append(":"); - buff.append(dhcpTo.getNetmask()); - buff.append(":"); - buff.append(dhcpTo.getStartIpOfSubnet()); - buff.append("-"); - } - cfg.add(new ConfigItem(VRScripts.DNSMASQ_CONFIG, buff.toString())); - return cfg; - } private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { @@ -693,12 +231,6 @@ protected Answer execute(CheckRouterCommand cmd) { return new CheckRouterAnswer(cmd, result.getDetails(), true); } - private List generateConfig(BumpUpPriorityCommand cmd) { - LinkedList cfg = new LinkedList<>(); - cfg.add(new ConfigItem(VRScripts.RVR_BUMPUP_PRI, null)); - return cfg; - } - protected Answer execute(GetDomRVersionCmd cmd) { final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VERSION, null); if (!result.isSuccess()) { @@ -711,277 +243,6 @@ protected Answer execute(GetDomRVersionCmd cmd) { return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } - private List generateConfig(Site2SiteVpnCfgCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String args = ""; - if (cmd.isCreate()) { - args += "-A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += "-D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - - cfg.add(new ConfigItem(VRScripts.S2SVPN_IPSEC, args)); - return cfg; - } - - protected List generateConfig(SetMonitorServiceCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String config = cmd.getConfiguration(); - String disableMonitoring = cmd.getAccessDetail(NetworkElementCommand.ROUTER_MONITORING_ENABLE); - - String args = " -c " + config; - if (disableMonitoring != null) { - args = args + " -d"; - } - - cfg.add(new ConfigItem(VRScripts.MONITOR_SERVICE, args)); - return cfg; - } - - protected List generateConfig(SetupGuestNetworkCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - NicTO nic = cmd.getNic(); - String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); - String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } - - String dev = "eth" + nic.getDeviceId(); - String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); - String args = ""; - if(cmd.isAdd() == false) { - //pass the argument to script to delete the network - args +=" -D"; - } else { - // pass create option argument if the ip needs to be added to eth device - args +=" -C"; - } - args += " -M " + nic.getMac(); - args += " -d " + dev; - args += " -i " + routerGIP; - args += " -g " + gateway; - args += " -m " + cidr; - args += " -n " + netmask; - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - - cfg.add(new ConfigItem(VRScripts.VPC_GUEST_NETWORK, args)); - return cfg; - } - - protected List generateConfig(SetNetworkACLCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); - - String[][] rules = cmd.generateFwRules(); - String[] aclRules = rules[0]; - NicTO nic = cmd.getNic(); - String dev = "eth" + nic.getDeviceId(); - String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - String rule = sb.toString(); - - String args = " -d " + dev; - args += " -M " + nic.getMac(); - if (privateGw != null) { - args += " -a " + rule; - - cfg.add(new ConfigItem(VRScripts.VPC_PRIVATEGW_ACL, args)); - } else { - args += " -i " + nic.getIp(); - args += " -m " + netmask; - args += " -a " + rule; - cfg.add(new ConfigItem(VRScripts.VPC_ACL, args)); - } - - return cfg; - } - - protected List generateConfig(SetSourceNatCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - IpAddressTO pubIP = cmd.getIpAddress(); - String dev = "eth" + pubIP.getNicDevId(); - String args = "-A"; - args += " -l "; - args += pubIP.getPublicIp(); - args += " -c "; - args += dev; - - cfg.add(new ConfigItem(VRScripts.VPC_SOURCE_NAT, args)); - return cfg; - } - - protected List generateConfig(SetPortForwardingRulesVpcCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = rule.revoked() ? "-D" : "-A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - cfg.add(new ConfigItem(VRScripts.VPC_PORTFORWARDING, args)); - } - - return cfg; - } - - protected List generateConfig(SetStaticRouteCommand cmd) { - LinkedList cfg = new LinkedList<>(); - - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - - for (int i = 0; i < srRules.length; i++) { - sb.append(srRules[i]).append(','); - } - - String args = " -a " + sb.toString(); - - cfg.add(new ConfigItem(VRScripts.VPC_STATIC_ROUTE, args)); - return cfg; - } - - protected List generateConfig(IpAssocCommand cmd) { - LinkedList cfg = new LinkedList<>(); - ConfigItem c; - - if (cmd instanceof IpAssocVpcCommand) { - for (IpAddressTO ip : cmd.getIpAddresses()) { - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - String nicName = "eth" + ip.getNicDevId(); - args += " -c "; - args += nicName; - args += " -g "; - args += ip.getVlanGateway(); - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - c = new ConfigItem(VRScripts.VPC_IPASSOC, args); - c.setInfo(ip.getPublicIp() + " - vpc_ipassoc"); - cfg.add(c); - - if (ip.isSourceNat()) { - snatArgs += " -l " + ip.getPublicIp(); - snatArgs += " -c " + nicName; - - c = new ConfigItem(VRScripts.VPC_PRIVATEGW, snatArgs); - c.setInfo(ip.getPublicIp() + " - vpc_privategateway"); - cfg.add(c); - } - } - } else { - for (IpAddressTO ip: cmd.getIpAddresses()) { - String args = ""; - if (ip.isAdd()) { - args += "-A"; - } else { - args += "-D"; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - if (ip.isSourceNat()) { - args += " -s"; - } - if (ip.isFirstIP()) { - args += " -f"; - } - args += " -l "; - args += ip.getPublicIp() + "/" + cidrSize; - - String publicNic = "eth" + ip.getNicDevId(); - args += " -c "; - args += publicNic; - - args += " -g "; - args += ip.getVlanGateway(); - - if (ip.isNewNic()) { - args += " -n"; - } - - c = new ConfigItem(VRScripts.IPASSOC, args); - c.setInfo(ip.getPublicIp()); - cfg.add(c); - } - } - return cfg; - } public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; @@ -1083,53 +344,7 @@ public boolean connect(final String ipAddress, int retry, int sleep) { } private List generateCommandCfg(NetworkElementCommand cmd) { - List cfg; - if (cmd instanceof SetPortForwardingRulesVpcCommand) { - cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd); - } else if (cmd instanceof SetPortForwardingRulesCommand) { - cfg = generateConfig((SetPortForwardingRulesCommand)cmd); - } else if (cmd instanceof SetStaticRouteCommand) { - cfg = generateConfig((SetStaticRouteCommand)cmd); - } else if (cmd instanceof SetStaticNatRulesCommand) { - cfg = generateConfig((SetStaticNatRulesCommand)cmd); - } else if (cmd instanceof LoadBalancerConfigCommand) { - cfg = generateConfig((LoadBalancerConfigCommand)cmd); - } else if (cmd instanceof SavePasswordCommand) { - cfg = generateConfig((SavePasswordCommand)cmd); - } else if (cmd instanceof DhcpEntryCommand) { - cfg = generateConfig((DhcpEntryCommand)cmd); - } else if (cmd instanceof CreateIpAliasCommand) { - cfg = generateConfig((CreateIpAliasCommand)cmd); - } else if (cmd instanceof DnsMasqConfigCommand) { - cfg = generateConfig((DnsMasqConfigCommand)cmd); - } else if (cmd instanceof DeleteIpAliasCommand) { - cfg = generateConfig((DeleteIpAliasCommand)cmd); - } else if (cmd instanceof VmDataCommand) { - cfg = generateConfig((VmDataCommand)cmd); - } else if (cmd instanceof SetFirewallRulesCommand) { - cfg = generateConfig((SetFirewallRulesCommand)cmd); - } else if (cmd instanceof BumpUpPriorityCommand) { - cfg = generateConfig((BumpUpPriorityCommand)cmd); - } else if (cmd instanceof RemoteAccessVpnCfgCommand) { - cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd); - } else if (cmd instanceof VpnUsersCfgCommand) { - cfg = generateConfig((VpnUsersCfgCommand)cmd); - } else if (cmd instanceof Site2SiteVpnCfgCommand) { - cfg = generateConfig((Site2SiteVpnCfgCommand)cmd); - } else if (cmd instanceof SetMonitorServiceCommand) { - cfg = generateConfig((SetMonitorServiceCommand)cmd); - } else if (cmd instanceof SetupGuestNetworkCommand) { - cfg = generateConfig((SetupGuestNetworkCommand)cmd); - } else if (cmd instanceof SetNetworkACLCommand) { - cfg = generateConfig((SetNetworkACLCommand)cmd); - } else if (cmd instanceof SetSourceNatCommand) { - cfg = generateConfig((SetSourceNatCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - cfg = generateConfig((IpAssocCommand)cmd); - } else { - return null; - } - return cfg; + return ConfigHelper.generateCommandCfg(cmd); } private Answer execute(AggregationControlCommand cmd) { @@ -1160,34 +375,30 @@ private Answer execute(AggregationControlCommand cmd) { } for (ConfigItem c : cfg) { - if (c.isFile()) { - sb.append("\n"); - sb.append(c.getFilePath() + c.getFileName() + "\n"); - sb.append(c.getFileContents() + "\n"); - sb.append("\n"); - } else { - sb.append("\n"); - } + sb.append(c.getAggregateCommand()); } } - String cfgFilePath = "/var/cache/cloud/"; - String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg"; - ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), cfgFilePath, cfgFileName, sb.toString()); - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } + // TODO replace with applyConfig with a stop on fail + String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg"; + FileConfigItem fileConfigItem = new FileConfigItem(VRScripts.CONFIG_CACHE_LOCATION, cfgFileName, sb.toString()); + ScriptConfigItem scriptConfigItem = new ScriptConfigItem(VRScripts.VR_CFG, "-c " + VRScripts.CONFIG_CACHE_LOCATION + cfgFileName); // 120s is the minimal timeout int timeout = answerCounts * _eachTimeout; if (timeout < 120) { timeout = 120; } - result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName, timeout); + + ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), fileConfigItem); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); + } + + result = applyConfigToVR(cmd.getRouterAccessIp(), scriptConfigItem, timeout); if (!result.isSuccess()) { return new Answer(cmd, false, result.getDetails()); } + return new Answer(cmd); } finally { queue.clear(); diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java index 531c71854d..908af45cbf 100644 --- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java +++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java @@ -16,6 +16,25 @@ // under the License. package com.cloud.agent.resource.virtualnetwork; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import javax.naming.ConfigurationException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; @@ -52,30 +71,12 @@ import com.cloud.agent.api.to.NetworkACLTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource.VRScripts; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.vpc.NetworkACLItem.TrafficType; import com.cloud.network.vpc.VpcGateway; import com.cloud.utils.ExecutionResult; import com.cloud.utils.net.NetUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; - -import javax.naming.ConfigurationException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -250,14 +251,14 @@ private void verifyArgs(SetPortForwardingRulesVpcCommand cmd, String script, Str assertTrue(script.equals(VRScripts.VPC_PORTFORWARDING)); _count ++; switch (_count) { - case 1: - assertEquals(args, "-A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22-80"); - break; - case 2: - assertEquals(args, "-D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080-8080"); - break; - default: - fail("Failed to recongize the match!"); + case 1: + assertEquals(args, "-A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22-80"); + break; + case 2: + assertEquals(args, "-D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080-8080"); + break; + default: + fail("Failed to recongize the match!"); } } @@ -287,14 +288,14 @@ private void verifyArgs(SetPortForwardingRulesCommand cmd, String script, String assertTrue(script.equals(VRScripts.FIREWALL_NAT)); _count ++; switch (_count) { - case 1: - assertEquals(args, "-A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22:80"); - break; - case 2: - assertEquals(args, "-D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080:8080"); - break; - default: - fail("Failed to recongize the match!"); + case 1: + assertEquals(args, "-A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22:80"); + break; + case 2: + assertEquals(args, "-D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080:8080"); + break; + default: + fail("Failed to recongize the match!"); } } @@ -338,7 +339,7 @@ public void testIpAssocVpcCommand() { Answer answer = _resource.executeRequest(cmd); assertTrue(answer instanceof GroupAnswer); - assertEquals(((GroupAnswer) answer).getResults().length, 6); + assertEquals(5, ((GroupAnswer)answer).getResults().length); assertTrue(answer.getResult()); } @@ -359,7 +360,7 @@ protected IpAssocVpcCommand generateIpAssocVpcCommand() { IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]); IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME); - assertEquals(cmd.getAnswersCount(), 6); + assertEquals(6, cmd.getAnswersCount()); // AnswersCount is clearly wrong as it doesn't know enough to tell return cmd; } @@ -368,44 +369,44 @@ private void verifyArgs(IpAssocCommand cmd, String script, String args) { if (cmd instanceof IpAssocVpcCommand) { _count ++; switch (_count) { - case 1: - assertEquals(script, VRScripts.VPC_IPASSOC); - assertEquals(args, " -A -l 64.1.1.10 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0"); - break; - case 2: - assertEquals(script, VRScripts.VPC_PRIVATEGW); - assertEquals(args, " -A -l 64.1.1.10 -c eth2"); - break; - case 3: - assertEquals(script, VRScripts.VPC_IPASSOC); - assertEquals(args, " -D -l 64.1.1.11 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0"); - break; - case 4: - assertEquals(script, VRScripts.VPC_PRIVATEGW); - assertEquals(args, " -D -l 64.1.1.11 -c eth2"); - break; - case 5: - assertEquals(script, VRScripts.VPC_IPASSOC); - assertEquals(args, " -A -l 65.1.1.11 -c eth2 -g 65.1.1.1 -m 24 -n 65.1.1.0"); - break; - default: - fail("Failed to recongize the match!"); + case 1: + assertEquals(script, VRScripts.VPC_IPASSOC); + assertEquals(args, " -A -l 64.1.1.10 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0"); + break; + case 2: + assertEquals(script, VRScripts.VPC_PRIVATEGW); + assertEquals(args, " -A -l 64.1.1.10 -c eth2"); + break; + case 3: + assertEquals(script, VRScripts.VPC_IPASSOC); + assertEquals(args, " -D -l 64.1.1.11 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0"); + break; + case 4: + assertEquals(script, VRScripts.VPC_PRIVATEGW); + assertEquals(args, " -D -l 64.1.1.11 -c eth2"); + break; + case 5: + assertEquals(script, VRScripts.VPC_IPASSOC); + assertEquals(args, " -A -l 65.1.1.11 -c eth2 -g 65.1.1.1 -m 24 -n 65.1.1.0"); + break; + default: + fail("Failed to recongize the match!"); } } else { assertEquals(script, VRScripts.IPASSOC); _count ++; switch (_count) { - case 1: - assertEquals(args, "-A -s -f -l 64.1.1.10/24 -c eth2 -g 64.1.1.1"); - break; - case 2: - assertEquals(args, "-D -l 64.1.1.11/24 -c eth2 -g 64.1.1.1"); - break; - case 3: - assertEquals(args, "-A -l 65.1.1.11/24 -c eth2 -g 65.1.1.1"); - break; - default: - fail("Failed to recongize the match!"); + case 1: + assertEquals(args, "-A -s -f -l 64.1.1.10/24 -c eth2 -g 64.1.1.1"); + break; + case 2: + assertEquals(args, "-D -l 64.1.1.11/24 -c eth2 -g 64.1.1.1"); + break; + case 3: + assertEquals(args, "-A -l 65.1.1.11/24 -c eth2 -g 65.1.1.1"); + break; + default: + fail("Failed to recongize the match!"); } } } @@ -469,18 +470,18 @@ protected SetNetworkACLCommand generateSetNetworkACLCommand() { private void verifyArgs(SetNetworkACLCommand cmd, String script, String args) { _count ++; switch (_count) { - case 1: - assertEquals(script, VRScripts.VPC_ACL); - assertEquals(args, " -d eth3 -M 01:23:45:67:89:AB -i 192.168.1.1 -m 24 -a Egress:ALL:0:0:192.168.0.1/24-192.168.0.2/24:ACCEPT:," + - "Ingress:ICMP:0:0:192.168.0.1/24-192.168.0.2/24:DROP:,Ingress:TCP:20:80:192.168.0.1/24-192.168.0.2/24:ACCEPT:,"); - break; - case 2: - assertEquals(script, VRScripts.VPC_PRIVATEGW_ACL); - assertEquals(args, " -d eth3 -M 01:23:45:67:89:AB -a Egress:ALL:0:0:192.168.0.1/24-192.168.0.2/24:ACCEPT:," + - "Ingress:ICMP:0:0:192.168.0.1/24-192.168.0.2/24:DROP:,Ingress:TCP:20:80:192.168.0.1/24-192.168.0.2/24:ACCEPT:,"); - break; - default: - fail(); + case 1: + assertEquals(script, VRScripts.VPC_ACL); + assertEquals(args, " -d eth3 -M 01:23:45:67:89:AB -i 192.168.1.1 -m 24 -a Egress:ALL:0:0:192.168.0.1/24-192.168.0.2/24:ACCEPT:," + + "Ingress:ICMP:0:0:192.168.0.1/24-192.168.0.2/24:DROP:,Ingress:TCP:20:80:192.168.0.1/24-192.168.0.2/24:ACCEPT:,"); + break; + case 2: + assertEquals(script, VRScripts.VPC_PRIVATEGW_ACL); + assertEquals(args, " -d eth3 -M 01:23:45:67:89:AB -a Egress:ALL:0:0:192.168.0.1/24-192.168.0.2/24:ACCEPT:," + + "Ingress:ICMP:0:0:192.168.0.1/24-192.168.0.2/24:DROP:,Ingress:TCP:20:80:192.168.0.1/24-192.168.0.2/24:ACCEPT:,"); + break; + default: + fail(); } } @@ -570,17 +571,17 @@ private void verifyArgs(Site2SiteVpnCfgCommand cmd, String script, String args) assertEquals(script, VRScripts.S2SVPN_IPSEC); switch (_count) { - case 1: - assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 1"); - break; - case 2: - assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 0 -p "); - break; - case 3: - assertEquals(args, "-D -r 124.10.1.10 -n 192.168.1.1/16 -N 192.168.100.1/24"); - break; - default: - fail(); + case 1: + assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 1"); + break; + case 2: + assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 0 -p "); + break; + case 3: + assertEquals(args, "-D -r 124.10.1.10 -n 192.168.1.1/16 -N 192.168.100.1/24"); + break; + default: + fail(); } } @@ -624,17 +625,17 @@ private void verifyArgs(RemoteAccessVpnCfgCommand cmd, String script, String arg assertEquals(script, VRScripts.VPN_L2TP); switch (_count) { - case 1: - assertEquals(args, "-r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c -C 10.1.1.1/24 -i eth2"); - break; - case 2: - assertEquals(args, "-d -s 124.10.10.10 -C 10.1.1.1/24 -i eth2"); - break; - case 3: - assertEquals(args, "-r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c -C 10.1.1.1/24 -i eth1"); - break; - default: - fail(); + case 1: + assertEquals(args, "-r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c -C 10.1.1.1/24 -i eth2"); + break; + case 2: + assertEquals(args, "-d -s 124.10.10.10 -C 10.1.1.1/24 -i eth2"); + break; + case 3: + assertEquals(args, "-r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c -C 10.1.1.1/24 -i eth1"); + break; + default: + fail(); } } @@ -645,8 +646,6 @@ public void testFirewallRulesCommand() { Answer answer = _resource.executeRequest(generateSetFirewallRulesCommand()); assertTrue(answer.getResult()); - assertTrue(answer instanceof GroupAnswer); - assertEquals(((GroupAnswer) answer).getResults().length, 3); //TODO Didn't test egress rule because not able to generate FirewallRuleVO object } @@ -760,17 +759,17 @@ private void verifyArgs(DhcpEntryCommand cmd, String script, String args) { _count ++; assertEquals(script, VRScripts.DHCP); switch (_count) { - case 1: - assertEquals(args, " -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1"); - break; - case 2: - assertEquals(args, " -m 12:34:56:78:90:AB -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB"); - break; - case 3: - assertEquals(args, " -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB"); - break; - default: - fail(); + case 1: + assertEquals(args, " -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1"); + break; + case 2: + assertEquals(args, " -m 12:34:56:78:90:AB -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB"); + break; + case 3: + assertEquals(args, " -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB"); + break; + default: + fail(); } } @@ -883,67 +882,67 @@ protected LoadBalancerConfigCommand generateLoadBalancerConfigCommand2() { protected void verifyFile(LoadBalancerConfigCommand cmd, String path, String filename, String content) { _count ++; switch (_count) { - case 1: - case 3: - _file = path + filename; - assertEquals(path, "/etc/haproxy/"); - assertTrue(filename.startsWith("haproxy.cfg.new")); - assertEquals(content, "global\n" + - "\tlog 127.0.0.1:3914 local0 warning\n" + - "\tmaxconn 1000\n" + - "\tmaxpipes 250\n" + - "\tchroot /var/lib/haproxy\n" + - "\tuser haproxy\n" + - "\tgroup haproxy\n" + - "\tdaemon\n" + - "\t \n" + - "defaults\n" + - "\tlog global\n" + - "\tmode tcp\n" + - "\toption dontlognull\n" + - "\tretries 3\n" + - "\toption redispatch\n" + - "\toption forwardfor\n" + - "\toption forceclose\n" + - "\ttimeout connect 5000\n" + - "\ttimeout client 50000\n" + - "\ttimeout server 50000\n" + - "\n" + - "listen stats_on_guest 10.1.10.2:8081\n" + - "\tmode http\n" + - "\toption httpclose\n" + - "\tstats enable\n" + - "\tstats uri /admin?stats\n" + - "\tstats realm Haproxy\\ Statistics\n" + - "\tstats auth admin1:AdMiN123\n" + - "\n" + - "\t \n" + - "listen 64_10_1_10-80 64.10.1.10:80\n" + - "\tbalance algo\n" + - "\tserver 64_10_1_10-80_0 10.1.10.2:80 check\n" + - "\tmode http\n" + - "\toption httpclose\n" + - "\t \n" + - "\t \n"); - break; - default: - fail(); + case 1: + case 3: + _file = path + filename; + assertEquals(path, "/etc/haproxy/"); + assertTrue(filename.startsWith("haproxy.cfg.new")); + assertEquals(content, "global\n" + + "\tlog 127.0.0.1:3914 local0 warning\n" + + "\tmaxconn 1000\n" + + "\tmaxpipes 250\n" + + "\tchroot /var/lib/haproxy\n" + + "\tuser haproxy\n" + + "\tgroup haproxy\n" + + "\tdaemon\n" + + "\t \n" + + "defaults\n" + + "\tlog global\n" + + "\tmode tcp\n" + + "\toption dontlognull\n" + + "\tretries 3\n" + + "\toption redispatch\n" + + "\toption forwardfor\n" + + "\toption forceclose\n" + + "\ttimeout connect 5000\n" + + "\ttimeout client 50000\n" + + "\ttimeout server 50000\n" + + "\n" + + "listen stats_on_guest 10.1.10.2:8081\n" + + "\tmode http\n" + + "\toption httpclose\n" + + "\tstats enable\n" + + "\tstats uri /admin?stats\n" + + "\tstats realm Haproxy\\ Statistics\n" + + "\tstats auth admin1:AdMiN123\n" + + "\n" + + "\t \n" + + "listen 64_10_1_10-80 64.10.1.10:80\n" + + "\tbalance algo\n" + + "\tserver 64_10_1_10-80_0 10.1.10.2:80 check\n" + + "\tmode http\n" + + "\toption httpclose\n" + + "\t \n" + + "\t \n"); + break; + default: + fail(); } } private void verifyArgs(LoadBalancerConfigCommand cmd, String script, String args) { _count ++; switch (_count) { - case 2: - assertEquals(script, VRScripts.LB); - assertEquals(args, " -i 10.1.10.2 -f " + _file + " -a 64.10.1.10:80:, -s 10.1.10.2:8081:0/0:,,"); - break; - case 4: - assertEquals(script, VRScripts.VPC_LB); - assertEquals(args, " -i 10.1.10.2 -f " + _file + " -a 64.10.1.10:80:, -s 10.1.10.2:8081:0/0:,,"); - break; - default: - fail(); + case 2: + assertEquals(script, VRScripts.LB); + assertEquals(args, " -i 10.1.10.2 -f " + _file + " -a 64.10.1.10:80:, -s 10.1.10.2:8081:0/0:,,"); + break; + case 4: + assertEquals(script, VRScripts.VPC_LB); + assertEquals(args, " -i 10.1.10.2 -f " + _file + " -a 64.10.1.10:80:, -s 10.1.10.2:8081:0/0:,,"); + break; + default: + fail(); } } From 1ad1883b74962cd6b6341fead3256e12b105f1c6 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 11 Jul 2014 17:49:51 +0200 Subject: [PATCH 056/819] Add virtualbox support to cloud-early-config so we can use virtualbox for testing --- .../patches/debian/config/etc/init.d/cloud-early-config | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index bbf1998a21..f36d8cbaf0 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -140,6 +140,15 @@ get_boot_params() { cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline cat /dev/null > /var/opt/hyperv/.kvp_pool_0 ;; + virtualbox) + # Virtualbox is used to test the virtual router + # get the commandline from a dmistring (yes, hacky!) + dmidecode | grep cmdline | sed 's/^.*cmdline://' > /var/cache/cloud/cmdline + RV=$? + if [ $RV -ne 0 ] ; then + log_it "Failed to get cmdline from a virtualbox dmi property" + fi + ;; esac } From 1ed554650c24a319baa200177c0ef0602b09cfe9 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Mon, 14 Jul 2014 16:04:29 +0200 Subject: [PATCH 057/819] One day i'll remember to put the licenses in right away. --- .../resource/virtualnetwork/ConfigHelper.java | 16 ++++++++++++++++ .../resource/virtualnetwork/ConfigItem.java | 16 ++++++++++++++++ .../resource/virtualnetwork/FileConfigItem.java | 16 ++++++++++++++++ .../virtualnetwork/ScriptConfigItem.java | 16 ++++++++++++++++ .../agent/resource/virtualnetwork/VRScripts.java | 16 ++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java index 31ddafb5d7..358fa2cb40 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.agent.resource.virtualnetwork; import java.util.HashMap; diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java index 0d622ce29a..a57eb79390 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.agent.resource.virtualnetwork; public abstract class ConfigItem { diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java index 20a09aa391..e54c4f0bf1 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.agent.resource.virtualnetwork; public class FileConfigItem extends ConfigItem { diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java index 133d2aaae8..1e0bcbc9f9 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.agent.resource.virtualnetwork; public class ScriptConfigItem extends ConfigItem { diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java index 05ddab0987..7acad14e1a 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.agent.resource.virtualnetwork; public class VRScripts { From 778e04cb7754c770d64fa76c8f330fa47e28ed65 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Mon, 14 Jul 2014 17:35:59 +0530 Subject: [PATCH 058/819] CLOUDSTACK-7104: perform ipassoc for ip when network is implemented after the gc --- server/src/com/cloud/network/IpAddressManagerImpl.java | 5 +++++ .../com/cloud/network/lb/LoadBalancingRulesManagerImpl.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 9906e0635a..c45496879f 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -420,6 +420,11 @@ private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) thr // 1.there is at least one public IP associated with the network on which first rule (PF/static NAT/LB) is being applied. // 2.last rule (PF/static NAT/LB) on the public IP has been revoked. So the public IP should not be associated with any provider boolean checkIfIpAssocRequired(Network network, boolean postApplyRules, List publicIps) { + + if (network.getState() == Network.State.Implementing) { + return true; + } + for (PublicIp ip : publicIps) { if (ip.isSourceNat()) { continue; diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 227a72c494..9238f50f19 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -1137,7 +1137,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { loadBalancer.setState(backupState); _lbDao.persist(loadBalancer); CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " - + instanceIds); + + vmInstanceIds); ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId"); // TBD: Also pack in the instanceIds in the exception using the // right VO object or table name. From 109d1290960d6215c32db8a241d027f82a0eb908 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Mon, 14 Jul 2014 16:22:53 +0200 Subject: [PATCH 059/819] Enforce licenses and license format in cloud-core --- core/pom.xml | 44 +++++++++++++------ .../StorageSubsystemCommandHandlerBase.java | 37 ++++++++-------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 4adf996ab0..429e1313e1 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -1,20 +1,22 @@ 4.0.0 @@ -53,7 +55,21 @@ org.apache.maven.plugins maven-pmd-plugin + + com.mycila + license-maven-plugin + + + cloudstack-checklicence + process-classes + + check + + + + + diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java index 61af4d947f..16fb153604 100644 --- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -1,21 +1,22 @@ -/* - * 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. - */ +// +// 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.storage.resource; import org.apache.log4j.Logger; From a49bb7e8e3a3f6e7dd7dbc4ac3d8cf55fd696819 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Mon, 14 Jul 2014 16:24:22 +0200 Subject: [PATCH 060/819] Cleanup licenses in core with com.mycila:license-maven-plugin:format --- .../cloudstack/allocator/module.properties | 3 ++ .../spring-core-allocator-context.xml | 30 +++++++------ ...ifecycle-allocator-context-inheritable.xml | 30 +++++++------ .../META-INF/cloudstack/api/module.properties | 3 ++ ...core-lifecycle-api-context-inheritable.xml | 34 ++++++++------- .../cloudstack/backend/module.properties | 3 ++ .../cloudstack/bootstrap/module.properties | 3 ++ .../spring-bootstrap-context-inheritable.xml | 30 +++++++------ .../bootstrap/spring-bootstrap-context.xml | 30 +++++++------ .../cloudstack/compute/module.properties | 3 ++ ...-lifecycle-compute-context-inheritable.xml | 34 ++++++++------- .../cloudstack/core/module.properties | 3 ++ .../cloudstack/core/spring-core-context.xml | 30 +++++++------ ...ore-lifecycle-core-context-inheritable.xml | 30 +++++++------ .../spring-core-registry-core-context.xml | 34 ++++++++------- .../cloudstack/discoverer/module.properties | 3 ++ ...fecycle-discoverer-context-inheritable.xml | 30 +++++++------ .../cloudstack/network/module.properties | 3 ++ ...-lifecycle-network-context-inheritable.xml | 34 ++++++++------- .../cloudstack/planner/module.properties | 3 ++ ...-lifecycle-planner-context-inheritable.xml | 34 ++++++++------- .../cloudstack/storage/module.properties | 3 ++ ...-lifecycle-storage-context-inheritable.xml | 30 +++++++------ .../cloudstack/system/module.properties | 3 ++ ...spring-core-system-context-inheritable.xml | 30 +++++++------ .../system/spring-core-system-context.xml | 30 +++++++------ core/src/com/cloud/agent/IAgentControl.java | 3 ++ .../cloud/agent/IAgentControlListener.java | 3 ++ .../cloud/agent/StartupCommandProcessor.java | 3 ++ .../cloud/agent/api/AgentControlAnswer.java | 3 ++ .../cloud/agent/api/AgentControlCommand.java | 3 ++ .../com/cloud/agent/api/AttachIsoCommand.java | 3 ++ .../cloud/agent/api/AttachVolumeAnswer.java | 3 ++ .../cloud/agent/api/AttachVolumeCommand.java | 3 ++ .../cloud/agent/api/BackupSnapshotAnswer.java | 3 ++ .../agent/api/BackupSnapshotCommand.java | 3 ++ .../agent/api/BumpUpPriorityCommand.java | 3 ++ .../com/cloud/agent/api/CancelCommand.java | 3 ++ .../cloud/agent/api/ChangeAgentAnswer.java | 3 ++ .../cloud/agent/api/ChangeAgentCommand.java | 3 ++ .../cloud/agent/api/CheckHealthAnswer.java | 3 ++ .../cloud/agent/api/CheckHealthCommand.java | 3 ++ .../cloud/agent/api/CheckNetworkAnswer.java | 3 ++ .../cloud/agent/api/CheckNetworkCommand.java | 3 ++ .../cloud/agent/api/CheckOnHostAnswer.java | 3 ++ .../cloud/agent/api/CheckOnHostCommand.java | 3 ++ .../cloud/agent/api/CheckRouterAnswer.java | 3 ++ .../cloud/agent/api/CheckRouterCommand.java | 3 ++ .../api/CheckS2SVpnConnectionsAnswer.java | 3 ++ .../api/CheckS2SVpnConnectionsCommand.java | 3 ++ .../com/cloud/agent/api/CheckStateAnswer.java | 3 ++ .../cloud/agent/api/CheckStateCommand.java | 3 ++ .../agent/api/CheckVirtualMachineAnswer.java | 3 ++ .../agent/api/CheckVirtualMachineCommand.java | 3 ++ .../agent/api/CleanupNetworkRulesCmd.java | 3 ++ .../api/ClusterVMMetaDataSyncAnswer.java | 3 ++ .../api/ClusterVMMetaDataSyncCommand.java | 3 ++ .../agent/api/ComputeChecksumCommand.java | 3 ++ .../ConsoleAccessAuthenticationAnswer.java | 3 ++ .../ConsoleAccessAuthenticationCommand.java | 3 ++ .../api/ConsoleProxyLoadReportCommand.java | 3 ++ ...atePrivateTemplateFromSnapshotCommand.java | 3 ++ ...reatePrivateTemplateFromVolumeCommand.java | 3 ++ .../agent/api/CreateStoragePoolCommand.java | 3 ++ .../agent/api/CreateVMSnapshotAnswer.java | 2 + .../agent/api/CreateVMSnapshotCommand.java | 3 ++ .../api/CreateVolumeFromSnapshotAnswer.java | 3 ++ .../api/CreateVolumeFromSnapshotCommand.java | 3 ++ .../api/CreateVolumeFromVMSnapshotAnswer.java | 2 + .../CreateVolumeFromVMSnapshotCommand.java | 3 ++ core/src/com/cloud/agent/api/CronCommand.java | 3 ++ .../agent/api/DeleteSnapshotsDirCommand.java | 3 ++ .../agent/api/DeleteStoragePoolCommand.java | 3 ++ .../agent/api/DeleteVMSnapshotAnswer.java | 3 ++ .../agent/api/DeleteVMSnapshotCommand.java | 5 ++- .../agent/api/DirectNetworkUsageAnswer.java | 3 ++ .../agent/api/DirectNetworkUsageCommand.java | 3 ++ .../ExternalNetworkResourceUsageAnswer.java | 3 ++ .../ExternalNetworkResourceUsageCommand.java | 3 ++ core/src/com/cloud/agent/api/FenceAnswer.java | 3 ++ .../src/com/cloud/agent/api/FenceCommand.java | 3 ++ .../cloud/agent/api/GetDomRVersionAnswer.java | 3 ++ .../cloud/agent/api/GetDomRVersionCmd.java | 3 ++ .../cloud/agent/api/GetFileStatsAnswer.java | 3 ++ .../cloud/agent/api/GetFileStatsCommand.java | 3 ++ .../cloud/agent/api/GetGPUStatsAnswer.java | 31 +++++++------ .../cloud/agent/api/GetGPUStatsCommand.java | 31 +++++++------ .../cloud/agent/api/GetHostStatsAnswer.java | 3 ++ .../cloud/agent/api/GetHostStatsCommand.java | 3 ++ .../agent/api/GetRouterAlertsAnswer.java | 2 + .../agent/api/GetStorageStatsAnswer.java | 3 ++ .../agent/api/GetStorageStatsCommand.java | 3 ++ .../cloud/agent/api/GetVmConfigAnswer.java | 3 ++ .../cloud/agent/api/GetVmConfigCommand.java | 3 ++ .../cloud/agent/api/GetVmDiskStatsAnswer.java | 3 ++ .../agent/api/GetVmDiskStatsCommand.java | 3 ++ .../com/cloud/agent/api/GetVmStatsAnswer.java | 3 ++ .../cloud/agent/api/GetVmStatsCommand.java | 3 ++ .../com/cloud/agent/api/GetVncPortAnswer.java | 3 ++ .../cloud/agent/api/GetVncPortCommand.java | 3 ++ .../com/cloud/agent/api/HostStatsEntry.java | 3 ++ .../com/cloud/agent/api/MaintainAnswer.java | 3 ++ .../com/cloud/agent/api/MaintainCommand.java | 3 ++ .../cloud/agent/api/ManageSnapshotAnswer.java | 3 ++ .../agent/api/ManageSnapshotCommand.java | 3 ++ .../com/cloud/agent/api/MigrateAnswer.java | 3 ++ .../com/cloud/agent/api/MigrateCommand.java | 3 ++ .../agent/api/MigrateWithStorageAnswer.java | 3 ++ .../agent/api/MigrateWithStorageCommand.java | 3 ++ .../api/MigrateWithStorageCompleteAnswer.java | 3 ++ .../MigrateWithStorageCompleteCommand.java | 3 ++ .../api/MigrateWithStorageReceiveAnswer.java | 3 ++ .../api/MigrateWithStorageReceiveCommand.java | 3 ++ .../api/MigrateWithStorageSendAnswer.java | 3 ++ .../api/MigrateWithStorageSendCommand.java | 3 ++ .../cloud/agent/api/ModifySshKeysCommand.java | 3 ++ .../agent/api/ModifyStoragePoolAnswer.java | 3 ++ .../agent/api/ModifyStoragePoolCommand.java | 3 ++ .../agent/api/ModifyVmNicConfigAnswer.java | 3 ++ .../agent/api/ModifyVmNicConfigCommand.java | 3 ++ .../api/NetworkRulesSystemVmCommand.java | 3 ++ .../api/NetworkRulesVmSecondaryIpCommand.java | 3 ++ .../cloud/agent/api/NetworkUsageAnswer.java | 3 ++ .../cloud/agent/api/NetworkUsageCommand.java | 3 ++ .../agent/api/PerformanceMonitorAnswer.java | 3 ++ .../agent/api/PerformanceMonitorCommand.java | 3 ++ core/src/com/cloud/agent/api/PingAnswer.java | 3 ++ core/src/com/cloud/agent/api/PingCommand.java | 3 ++ .../cloud/agent/api/PingRoutingCommand.java | 3 ++ .../api/PingRoutingWithNwGroupsCommand.java | 3 ++ .../agent/api/PingRoutingWithOvsCommand.java | 3 ++ .../cloud/agent/api/PingStorageCommand.java | 3 ++ .../com/cloud/agent/api/PingTestCommand.java | 3 ++ .../com/cloud/agent/api/PlugNicAnswer.java | 3 ++ .../com/cloud/agent/api/PlugNicCommand.java | 3 ++ .../agent/api/PrepareForMigrationAnswer.java | 3 ++ .../agent/api/PrepareForMigrationCommand.java | 3 ++ .../agent/api/PrepareOCFS2NodesCommand.java | 3 ++ .../api/PropagateResourceEventCommand.java | 3 ++ core/src/com/cloud/agent/api/ReadyAnswer.java | 3 ++ .../src/com/cloud/agent/api/ReadyCommand.java | 3 ++ .../src/com/cloud/agent/api/RebootAnswer.java | 3 ++ .../com/cloud/agent/api/RebootCommand.java | 3 ++ .../cloud/agent/api/RebootRouterCommand.java | 3 ++ .../api/RecurringNetworkUsageAnswer.java | 3 ++ .../api/RecurringNetworkUsageCommand.java | 3 ++ .../agent/api/RevertToVMSnapshotAnswer.java | 2 + .../agent/api/RevertToVMSnapshotCommand.java | 3 ++ .../com/cloud/agent/api/ScaleVmAnswer.java | 3 ++ .../com/cloud/agent/api/ScaleVmCommand.java | 3 ++ .../api/ScheduleHostScanTaskCommand.java | 3 ++ .../api/SecStorageFirewallCfgCommand.java | 3 ++ .../agent/api/SecStorageSetupAnswer.java | 3 ++ .../agent/api/SecStorageSetupCommand.java | 3 ++ .../agent/api/SecStorageVMSetupCommand.java | 3 ++ .../agent/api/SecurityGroupRuleAnswer.java | 3 ++ .../agent/api/SecurityGroupRulesCmd.java | 3 ++ core/src/com/cloud/agent/api/SetupAnswer.java | 3 ++ .../src/com/cloud/agent/api/SetupCommand.java | 3 ++ .../agent/api/SetupGuestNetworkCommand.java | 3 ++ .../com/cloud/agent/api/ShutdownCommand.java | 3 ++ .../com/cloud/agent/api/SnapshotCommand.java | 3 ++ core/src/com/cloud/agent/api/StartAnswer.java | 3 ++ .../src/com/cloud/agent/api/StartCommand.java | 3 ++ .../com/cloud/agent/api/StartupAnswer.java | 3 ++ .../com/cloud/agent/api/StartupCommand.java | 3 ++ .../agent/api/StartupExternalDhcpCommand.java | 3 ++ .../api/StartupExternalFirewallCommand.java | 3 ++ .../StartupExternalLoadBalancerCommand.java | 3 ++ .../cloud/agent/api/StartupProxyCommand.java | 3 ++ .../agent/api/StartupPxeServerCommand.java | 3 ++ .../agent/api/StartupRoutingCommand.java | 3 ++ .../api/StartupSecondaryStorageCommand.java | 3 ++ .../agent/api/StartupStorageCommand.java | 3 ++ .../api/StartupTrafficMonitorCommand.java | 3 ++ .../agent/api/StartupVMMAgentCommand.java | 3 ++ core/src/com/cloud/agent/api/StopAnswer.java | 3 ++ core/src/com/cloud/agent/api/StopCommand.java | 3 ++ .../cloud/agent/api/TransferAgentCommand.java | 3 ++ .../com/cloud/agent/api/UnPlugNicAnswer.java | 3 ++ .../com/cloud/agent/api/UnPlugNicCommand.java | 3 ++ .../cloud/agent/api/UnregisterNicCommand.java | 3 ++ .../cloud/agent/api/UnregisterVMCommand.java | 3 ++ .../agent/api/UpdateHostPasswordCommand.java | 3 ++ .../agent/api/UpgradeSnapshotCommand.java | 3 ++ .../agent/api/VMSnapshotBaseCommand.java | 2 + .../src/com/cloud/agent/api/VMSnapshotTO.java | 3 ++ .../agent/api/ValidateSnapshotAnswer.java | 3 ++ .../agent/api/ValidateSnapshotCommand.java | 3 ++ .../com/cloud/agent/api/VmDiskStatsEntry.java | 3 ++ .../src/com/cloud/agent/api/VmStatsEntry.java | 3 ++ .../api/baremetal/IpmISetBootDevCommand.java | 3 ++ .../api/baremetal/IpmiBootorResetCommand.java | 3 ++ .../PrepareCreateTemplateCommand.java | 3 ++ .../api/baremetal/PreparePxeServerAnswer.java | 3 ++ .../baremetal/PreparePxeServerCommand.java | 3 ++ .../cloud/agent/api/check/CheckSshAnswer.java | 3 ++ .../agent/api/check/CheckSshCommand.java | 3 ++ .../proxy/CheckConsoleProxyLoadCommand.java | 3 ++ .../api/proxy/ConsoleProxyLoadAnswer.java | 3 ++ .../cloud/agent/api/proxy/ProxyCommand.java | 3 ++ ...rtConsoleProxyAgentHttpHandlerCommand.java | 3 ++ .../proxy/WatchConsoleProxyLoadCommand.java | 3 ++ .../routing/AggregationControlCommand.java | 2 + .../api/routing/CreateIpAliasCommand.java | 3 ++ .../CreateLoadBalancerApplianceCommand.java | 3 ++ .../api/routing/DeleteIpAliasCommand.java | 3 ++ .../DestroyLoadBalancerApplianceCommand.java | 3 ++ .../agent/api/routing/DhcpEntryCommand.java | 3 ++ .../api/routing/DnsMasqConfigCommand.java | 3 ++ .../api/routing/GetRouterAlertsCommand.java | 2 + .../GlobalLoadBalancerConfigAnswer.java | 3 ++ .../GlobalLoadBalancerConfigCommand.java | 2 + .../cloud/agent/api/routing/GroupAnswer.java | 2 + .../routing/HealthCheckLBConfigAnswer.java | 3 ++ .../routing/HealthCheckLBConfigCommand.java | 3 ++ .../cloud/agent/api/routing/IpAliasTO.java | 3 ++ .../agent/api/routing/IpAssocAnswer.java | 3 ++ .../agent/api/routing/IpAssocCommand.java | 3 ++ .../agent/api/routing/IpAssocVpcCommand.java | 3 ++ .../routing/LoadBalancerConfigCommand.java | 3 ++ .../api/routing/NetworkElementCommand.java | 3 ++ .../routing/RemoteAccessVpnCfgCommand.java | 3 ++ .../api/routing/SavePasswordCommand.java | 3 ++ .../api/routing/SetFirewallRulesAnswer.java | 3 ++ .../api/routing/SetFirewallRulesCommand.java | 3 ++ .../api/routing/SetMonitorServiceCommand.java | 3 ++ .../api/routing/SetNetworkACLAnswer.java | 3 ++ .../api/routing/SetNetworkACLCommand.java | 2 + .../routing/SetPortForwardingRulesAnswer.java | 3 ++ .../SetPortForwardingRulesCommand.java | 3 ++ .../SetPortForwardingRulesVpcCommand.java | 3 ++ .../agent/api/routing/SetSourceNatAnswer.java | 3 ++ .../api/routing/SetSourceNatCommand.java | 3 ++ .../api/routing/SetStaticNatRulesAnswer.java | 3 ++ .../api/routing/SetStaticNatRulesCommand.java | 3 ++ .../api/routing/SetStaticRouteAnswer.java | 3 ++ .../api/routing/SetStaticRouteCommand.java | 2 + .../api/routing/Site2SiteVpnCfgCommand.java | 3 ++ .../api/routing/SiteLoadBalancerConfig.java | 2 + .../agent/api/routing/UserDataCommand.java | 3 ++ .../agent/api/routing/VmDataCommand.java | 3 ++ .../agent/api/routing/VpnUsersCfgCommand.java | 3 ++ .../api/storage/AbstractDownloadCommand.java | 3 ++ .../api/storage/AbstractUploadCommand.java | 3 ++ .../agent/api/storage/CopyVolumeAnswer.java | 3 ++ .../agent/api/storage/CopyVolumeCommand.java | 3 ++ .../cloud/agent/api/storage/CreateAnswer.java | 3 ++ .../agent/api/storage/CreateCommand.java | 3 ++ .../CreateEntityDownloadURLAnswer.java | 3 ++ .../CreateEntityDownloadURLCommand.java | 3 ++ .../storage/CreatePrivateTemplateAnswer.java | 3 ++ .../storage/CreatePrivateTemplateCommand.java | 3 ++ .../DeleteEntityDownloadURLCommand.java | 3 ++ .../agent/api/storage/DestroyAnswer.java | 3 ++ .../agent/api/storage/DestroyCommand.java | 3 ++ .../agent/api/storage/DownloadAnswer.java | 3 ++ .../agent/api/storage/ListTemplateAnswer.java | 3 ++ .../api/storage/ListTemplateCommand.java | 3 ++ .../agent/api/storage/ListVolumeAnswer.java | 3 ++ .../agent/api/storage/ListVolumeCommand.java | 3 ++ .../ManageVolumeAvailabilityAnswer.java | 3 ++ .../ManageVolumeAvailabilityCommand.java | 3 ++ .../api/storage/MigrateVolumeAnswer.java | 3 ++ .../api/storage/MigrateVolumeCommand.java | 3 ++ .../storage/PrimaryStorageDownloadAnswer.java | 3 ++ .../PrimaryStorageDownloadCommand.java | 3 ++ .../agent/api/storage/ResizeVolumeAnswer.java | 3 ++ .../api/storage/ResizeVolumeCommand.java | 3 ++ .../cloud/agent/api/storage/SsCommand.java | 3 ++ .../agent/api/storage/StorageCommand.java | 3 ++ .../agent/api/storage/UpgradeDiskAnswer.java | 3 ++ .../agent/api/storage/UpgradeDiskCommand.java | 3 ++ .../cloud/agent/api/storage/UploadAnswer.java | 3 ++ .../agent/api/storage/UploadCommand.java | 3 ++ .../api/storage/UploadProgressCommand.java | 3 ++ .../resource/virtualnetwork/ConfigHelper.java | 3 ++ .../resource/virtualnetwork/ConfigItem.java | 3 ++ .../virtualnetwork/FileConfigItem.java | 3 ++ .../virtualnetwork/ScriptConfigItem.java | 3 ++ .../resource/virtualnetwork/VRScripts.java | 3 ++ .../virtualnetwork/VirtualRouterDeployer.java | 3 ++ .../VirtualRoutingResource.java | 3 ++ .../agent/transport/ArrayTypeAdaptor.java | 3 ++ .../agent/transport/InterfaceTypeAdaptor.java | 3 ++ .../transport/LoggingExclusionStrategy.java | 3 ++ .../com/cloud/agent/transport/Request.java | 3 ++ .../com/cloud/agent/transport/Response.java | 3 ++ .../UnsupportedVersionException.java | 3 ++ .../cloud/exception/UsageServerException.java | 3 ++ core/src/com/cloud/host/HostInfo.java | 3 ++ .../resource/HypervDummyResourceBase.java | 3 ++ .../info/ConsoleProxyConnectionInfo.java | 3 ++ core/src/com/cloud/info/ConsoleProxyInfo.java | 3 ++ .../com/cloud/info/ConsoleProxyStatus.java | 3 ++ .../cloud/info/RunningHostInfoAgregator.java | 3 ++ .../com/cloud/info/SecStorageVmLoadInfo.java | 3 ++ .../cloud/network/HAProxyConfigurator.java | 3 ++ .../network/LoadBalancerConfigurator.java | 3 ++ .../cloud/network/LoadBalancerValidator.java | 3 ++ .../CreateLoadBalancerApplianceAnswer.java | 3 ++ .../DestroyLoadBalancerApplianceAnswer.java | 3 ++ .../resource/TrafficSentinelResource.java | 3 ++ .../com/cloud/resource/ResourceListener.java | 3 ++ .../com/cloud/resource/ServerResource.java | 3 ++ .../cloud/resource/ServerResourceBase.java | 3 ++ .../hypervisor/HypervisorResource.java | 3 ++ core/src/com/cloud/serializer/GsonHelper.java | 3 ++ .../cloud/serializer/SerializerHelper.java | 3 ++ .../com/cloud/storage/JavaStorageLayer.java | 3 ++ core/src/com/cloud/storage/StorageLayer.java | 3 ++ .../storage/resource/StoragePoolResource.java | 3 ++ .../storage/resource/StorageProcessor.java | 37 ++++++++-------- .../StorageSubsystemCommandHandler.java | 37 ++++++++-------- .../storage/template/FtpTemplateUploader.java | 3 ++ .../template/HttpTemplateDownloader.java | 3 ++ .../cloud/storage/template/IsoProcessor.java | 3 ++ .../template/LocalTemplateDownloader.java | 3 ++ .../cloud/storage/template/OVAProcessor.java | 3 ++ .../com/cloud/storage/template/Processor.java | 3 ++ .../storage/template/QCOW2Processor.java | 3 ++ .../storage/template/RawImageProcessor.java | 3 ++ .../template/S3TemplateDownloader.java | 3 ++ .../template/ScpTemplateDownloader.java | 3 ++ .../storage/template/TemplateConstants.java | 3 ++ .../storage/template/TemplateDownloader.java | 3 ++ .../template/TemplateDownloaderBase.java | 3 ++ .../storage/template/TemplateLocation.java | 3 ++ .../storage/template/TemplateUploader.java | 3 ++ .../cloud/storage/template/VhdProcessor.java | 3 ++ .../cloud/storage/template/VmdkProcessor.java | 3 ++ .../storage/command/AttachAnswer.java | 39 +++++++++-------- .../storage/command/AttachCommand.java | 37 ++++++++-------- .../command/AttachPrimaryDataStoreAnswer.java | 43 ++++++++++--------- .../command/AttachPrimaryDataStoreCmd.java | 41 +++++++++--------- .../storage/command/CopyCmdAnswer.java | 3 ++ .../storage/command/CopyCommand.java | 3 ++ .../storage/command/CreateObjectAnswer.java | 39 +++++++++-------- .../storage/command/CreateObjectCommand.java | 41 +++++++++--------- .../command/CreatePrimaryDataStoreCmd.java | 3 ++ .../storage/command/DeleteCommand.java | 39 +++++++++-------- .../storage/command/DettachAnswer.java | 39 +++++++++-------- .../storage/command/DettachCommand.java | 37 ++++++++-------- .../storage/command/DownloadCommand.java | 3 ++ .../command/DownloadProgressCommand.java | 3 ++ .../storage/command/ForgetObjectCmd.java | 41 +++++++++--------- .../command/IntroduceObjectAnswer.java | 39 +++++++++-------- .../storage/command/IntroduceObjectCmd.java | 39 +++++++++-------- .../command/StorageSubSystemCommand.java | 37 ++++++++-------- .../cloudstack/storage/to/ImageStoreTO.java | 3 ++ .../storage/to/PrimaryDataStoreTO.java | 3 ++ .../storage/to/SnapshotObjectTO.java | 3 ++ .../storage/to/TemplateObjectTO.java | 3 ++ .../cloudstack/storage/to/VolumeObjectTO.java | 3 ++ .../VirtualRoutingResourceTest.java | 3 ++ .../cloud/agent/transport/RequestTest.java | 3 ++ .../network/HAProxyConfiguratorTest.java | 3 ++ .../agent/test/AgentControlAnswerTest.java | 3 ++ .../agent/test/AgentControlCommandTest.java | 3 ++ .../cloudstack/api/agent/test/AnswerTest.java | 3 ++ .../api/agent/test/AttachIsoCommandTest.java | 3 ++ .../agent/test/AttachVolumeAnswerTest.java | 3 ++ .../agent/test/AttachVolumeCommandTest.java | 3 ++ .../agent/test/BackupSnapshotAnswerTest.java | 3 ++ .../agent/test/BackupSnapshotCommandTest.java | 3 ++ .../agent/test/BumpUpPriorityCommandTest.java | 3 ++ .../api/agent/test/CancelCommandTest.java | 3 ++ .../api/agent/test/ChangeAgentAnswerTest.java | 3 ++ .../agent/test/ChangeAgentCommandTest.java | 3 ++ .../api/agent/test/CheckHealthAnswerTest.java | 3 ++ .../agent/test/CheckHealthCommandTest.java | 3 ++ .../agent/test/CheckNetworkAnswerTest.java | 3 ++ .../agent/test/CheckNetworkCommandTest.java | 3 ++ .../agent/test/CheckOnHostCommandTest.java | 3 ++ .../api/agent/test/SnapshotCommandTest.java | 3 ++ 375 files changed, 1602 insertions(+), 534 deletions(-) diff --git a/core/resources/META-INF/cloudstack/allocator/module.properties b/core/resources/META-INF/cloudstack/allocator/module.properties index 7866be06f3..b99b9af5dc 100644 --- a/core/resources/META-INF/cloudstack/allocator/module.properties +++ b/core/resources/META-INF/cloudstack/allocator/module.properties @@ -1,3 +1,4 @@ +# # 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 @@ -14,5 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# + name=allocator parent=core diff --git a/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml b/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml index 65ebc70440..700b9060d5 100644 --- a/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml +++ b/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml @@ -1,20 +1,22 @@ Date: Mon, 14 Jul 2014 14:10:16 -0700 Subject: [PATCH 061/819] revert the change made by commit: a600d840 --- .../com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index 839cbaa35e..e684b8de5f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -101,10 +101,6 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) { throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver"); } - if ((vNetId == null)||(protocol == null)) - { - throw new InternalErrorException("plug: protocol or vNetId value is null"); - } String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0; From 4f0640dac4036d92bcda745c8fa80afcae5eae55 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 14 Jul 2014 14:02:41 -0700 Subject: [PATCH 062/819] CLOUDSTACK-6595: allow to expunge the vm when its in Error state, in addition to Expunging/Destroyed states --- server/src/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 3df05e04c4..dac4acf182 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3683,7 +3683,7 @@ public UserVm expungeVm(long vmId) throws ResourceUnavailableException, Concurre return vm; } - if ((vm.getState() != State.Destroyed) && (vm.getState() != State.Expunging)) { + if (!(vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getState() == State.Error)) { CloudRuntimeException ex = new CloudRuntimeException("Please destroy vm with specified vmId before expunge"); ex.addProxyObject(String.valueOf(vmId), "vmId"); throw ex; From 5143fe404bc82dfe42b832c661b4e98a0d9ebfa8 Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Mon, 14 Jul 2014 14:45:21 -0700 Subject: [PATCH 063/819] When instance.name.flag is set to true, append user-supplied name with legacy prefix to VM name appears in vCenter. --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 15eeb13bcd..f1f307bc8c 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1829,8 +1829,10 @@ private Pair composeVmNames(VirtualMachineTO vmSpec) { String vmNameOnVcenter = null; if (vmSpec.getHostName() != null) { vmInternalCSName = vmSpec.getName(); - if (_instanceNameFlag == true) - vmNameOnVcenter = vmSpec.getHostName(); + if (_instanceNameFlag == true) { + String[] tokens = vmInternalCSName.split("-"); + vmNameOnVcenter = String.format("%s-%s-%s", tokens[0], tokens[1], vmSpec.getHostName()); + } else vmNameOnVcenter = vmSpec.getName(); } else { From 6831ed4026c47870b40d1dea0b0f9d0e71d9d37d Mon Sep 17 00:00:00 2001 From: amoghvk Date: Mon, 14 Jul 2014 15:17:58 -0700 Subject: [PATCH 064/819] CLOUDSTACK-6358: Missing patches in master branch --- .../cloud/agent/api/to/VirtualMachineTO.java | 17 ++++-- .../agent/api/VMSnapshotBaseCommand.java | 11 +++- .../vmsnapshot/DefaultVMSnapshotStrategy.java | 14 +++++ .../test/src/VMSnapshotStrategyTest.java | 52 +++++++++++++++++++ .../storage/helper/HypervisorHelperImpl.java | 11 ++++ .../com/cloud/hypervisor/XenServerGuru.java | 27 ++++++---- .../resource/CitrixResourceBase.java | 17 +++--- .../xenserver/resource/XcpOssResource.java | 26 ++++++---- .../resource/XcpServer16Resource.java | 11 +++- .../xenserver/resource/XcpServerResource.java | 8 ++- .../resource/XenServer56FP1Resource.java | 13 ++++- .../resource/XenServer56Resource.java | 48 ++++++++++------- .../resource/XenServer56SP2Resource.java | 13 ++++- .../resource/XenServer600Resource.java | 13 ++++- .../resource/XenServer602Resource.java | 15 +++++- .../resource/XenServer610Resource.java | 13 ++++- .../resource/XenServer620Resource.java | 26 +++++++--- .../resource/XenServer620SP1Resource.java | 32 ++++++++---- .../resource/Xenserver625Resource.java | 15 ++++-- 19 files changed, 297 insertions(+), 85 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index bbd83852ab..a1d945243f 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -47,6 +47,7 @@ public class VirtualMachineTO { String hostName; String arch; String os; + String platformEmulator; String bootArgs; String[] bootupScripts; boolean rebootOnCrash; @@ -65,7 +66,7 @@ public class VirtualMachineTO { public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) { this.id = id; - this.name = instanceName; + name = instanceName; this.type = type; this.cpus = cpus; this.speed = speed; @@ -81,7 +82,7 @@ public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) { this.id = id; - this.name = instanceName; + name = instanceName; this.type = type; this.cpus = cpus; this.minSpeed = minSpeed; @@ -236,7 +237,7 @@ public void setNics(NicTO[] nics) { } public String getVncPassword() { - return this.vncPassword; + return vncPassword; } public void setVncPassword(String vncPassword) { @@ -244,7 +245,7 @@ public void setVncPassword(String vncPassword) { } public String getVncAddr() { - return this.vncAddr; + return vncAddr; } public void setVncAddr(String vncAddr) { @@ -275,4 +276,12 @@ public void setGpuDevice(GPUDeviceTO gpuDevice) { this.gpuDevice = gpuDevice; } + public String getPlatformEmulator() { + return platformEmulator; + } + + public void setPlatformEmulator(String platformEmulator) { + this.platformEmulator = platformEmulator; + } + } diff --git a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java index 3625dc93df..8b9f0211fb 100644 --- a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java +++ b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java @@ -28,10 +28,11 @@ public class VMSnapshotBaseCommand extends Command { protected VMSnapshotTO target; protected String vmName; protected String guestOSType; + protected String platformEmulator; public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List volumeTOs, String guestOSType) { this.vmName = vmName; - this.target = snapshot; + target = snapshot; this.volumeTOs = volumeTOs; this.guestOSType = guestOSType; } @@ -72,4 +73,12 @@ public String getGuestOSType() { public void setGuestOSType(String guestOSType) { this.guestOSType = guestOSType; } + + public String getPlatformEmulator() { + return platformEmulator; + } + + public void setPlatformEmulator(String platformEmulator) { + this.platformEmulator = platformEmulator; + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java index e86bd23b05..9154b347fc 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java @@ -45,11 +45,15 @@ import com.cloud.event.UsageEventUtils; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; @@ -73,6 +77,8 @@ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshot @Inject GuestOSDao guestOSDao; @Inject + GuestOSHypervisorDao guestOsHypervisorDao; + @Inject UserVmDao userVmDao; @Inject VMSnapshotDao vmSnapshotDao; @@ -85,6 +91,8 @@ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshot VolumeDao volumeDao; @Inject DiskOfferingDao diskOfferingDao; + @Inject + HostDao hostDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -126,7 +134,11 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) { else vmSnapshotVO.setParent(current.getId()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); + CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(), target, volumeTOs, guestOS.getDisplayName(), userVm.getState()); + ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); ccmd.setWait(_wait); answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd); @@ -335,6 +347,8 @@ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) { Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId()); GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId()); RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer)agentMgr.send(hostId, revertToSnapshotCommand); if (answer != null && answer.getResult()) { diff --git a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java index 9eaa7e19c1..22cf9c1d52 100644 --- a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java +++ b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java @@ -58,9 +58,14 @@ import com.cloud.agent.api.VMSnapshotTO; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; @@ -83,9 +88,13 @@ public class VMSnapshotStrategyTest extends TestCase { @Inject GuestOSDao guestOSDao; @Inject + GuestOSHypervisorDao guestOsHypervisorDao; + @Inject AgentManager agentMgr; @Inject VMSnapshotDao vmSnapshotDao; + @Inject + HostDao hostDao; @Override @Before @@ -98,6 +107,9 @@ public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTi Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -108,7 +120,15 @@ public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTi Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { vmSnapshotStrategy.takeVMSnapshot(vmSnapshot); @@ -131,6 +151,9 @@ public void testRevertSnapshot() throws AgentUnavailableException, OperationTime Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -141,12 +164,20 @@ public void testRevertSnapshot() throws AgentUnavailableException, OperationTime Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class); Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO); Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot); Mockito.when(vmSnapshot.getId()).thenReturn(1L); Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date()); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { vmSnapshotStrategy.revertVMSnapshot(vmSnapshot); @@ -168,6 +199,9 @@ public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTi Long hostId = 1L; Long vmId = 1L; Long guestOsId = 1L; + HypervisorType hypervisorType = HypervisorType.Any; + String hypervisorVersion = "default"; + String guestOsName = "Other"; List volumeObjectTOs = new ArrayList(); VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class); UserVmVO userVmVO = Mockito.mock(UserVmVO.class); @@ -178,12 +212,20 @@ public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTi Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO); GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class); Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO); + GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class); + Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName); + Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO); + Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO); VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class); Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO); Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot); Mockito.when(vmSnapshot.getId()).thenReturn(1L); Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date()); Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null); + HostVO hostVO = Mockito.mock(HostVO.class); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO); + Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType); + Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion); Exception e = null; try { @@ -227,6 +269,11 @@ public GuestOSDao guestOSDao() { return Mockito.mock(GuestOSDao.class); } + @Bean + public GuestOSHypervisorDao guestOsHypervisorDao() { + return Mockito.mock(GuestOSHypervisorDao.class); + } + @Bean public UserVmDao userVmDao() { return Mockito.mock(UserVmDao.class); @@ -256,5 +303,10 @@ public VolumeDao volumeDao() { public DiskOfferingDao diskOfferingDao() { return Mockito.mock(DiskOfferingDao.class); } + + @Bean + public HostDao hostDao() { + return Mockito.mock(HostDao.class); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java b/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java index b41c1fa14a..ff62fb8680 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java @@ -44,8 +44,12 @@ import com.cloud.agent.api.to.DataTO; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; @@ -60,9 +64,13 @@ public class HypervisorHelperImpl implements HypervisorHelper { @Inject GuestOSDao guestOSDao; @Inject + GuestOSHypervisorDao guestOsHypervisorDao; + @Inject ConfigurationDao configurationDao; @Inject AgentManager agentMgr; + @Inject + HostDao hostDao; @Override public DataTO introduceObject(DataTO object, Scope scope, Long storeId) { @@ -117,6 +125,9 @@ public VMSnapshotTO quiesceVm(VirtualMachine virtualMachine) { List volumeTOs = vmSnapshotHelper.getVolumeTOList(virtualMachine.getId()); CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(virtualMachine.getInstanceName(), vmSnapshotTO, volumeTOs, guestOS.getDisplayName(), virtualMachine.getState()); + HostVO host = hostDao.findById(hostId); + GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); + ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); ccmd.setWait(wait); try { Answer answer = agentMgr.send(hostId, ccmd); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java index 89e4ab5d94..620d7113f4 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java @@ -22,6 +22,16 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DettachCommand; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; @@ -32,30 +42,24 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.storage.command.CopyCommand; -import org.apache.cloudstack.storage.command.DettachCommand; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; - @Local(value = HypervisorGuru.class) public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject GuestOSDao _guestOsDao; @Inject + GuestOSHypervisorDao _guestOsHypervisorDao; + @Inject EndPointSelector endPointSelector; @Inject HostDao hostDao; @@ -87,6 +91,9 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); + HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId()); + GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); return to; } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index a9840bdc09..0f42df3cc1 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -805,7 +805,7 @@ private Answer execute(RevertToVMSnapshotCommand cmd) { try { vm = getVM(conn, vmName); } catch (Exception e) { - vm = createWorkingVM(conn, vmName, cmd.getGuestOSType(), listVolumeTo); + vm = createWorkingVM(conn, vmName, cmd.getGuestOSType(), cmd.getPlatformEmulator(), listVolumeTo); } if (vm == null) { @@ -1289,7 +1289,7 @@ protected void createVGPU(Connection conn, StartCommand cmd, VM vm, GPUDeviceTO } protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException { - String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD); + String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getPlatformEmulator(), vmSpec.getBootloader() == BootloaderType.CD); Set templates = VM.getByNameLabel(conn, guestOsTypeName); assert templates.size() == 1 : "Should only have 1 template but found " + templates.size(); VM template = templates.iterator().next(); @@ -1386,7 +1386,7 @@ protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); String osType = iso.getGuestOsType(); if (osType != null) { - String isoGuestOsName = getGuestOsType(osType, vmSpec.getBootloader() == BootloaderType.CD); + String isoGuestOsName = getGuestOsType(osType, vmSpec.getPlatformEmulator(), vmSpec.getBootloader() == BootloaderType.CD); if (!isoGuestOsName.equals(guestOsTypeName)) { vmSpec.setBootloader(BootloaderType.PyGrub); } @@ -6389,6 +6389,7 @@ protected Answer execute(final CreateVMSnapshotCommand cmd) { List listVolumeTo = cmd.getVolumeTOs(); VirtualMachine.State vmState = cmd.getVmState(); String guestOSType = cmd.getGuestOSType(); + String platformEmulator = cmd.getPlatformEmulator(); boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory; long timeout = cmd.getWait(); @@ -6423,7 +6424,7 @@ protected Answer execute(final CreateVMSnapshotCommand cmd) { vm = getVM(conn, vmName); } catch (Exception e) { if (!snapshotMemory) { - vm = createWorkingVM(conn, vmName, guestOSType, listVolumeTo); + vm = createWorkingVM(conn, vmName, guestOSType, platformEmulator, listVolumeTo); } } @@ -6511,9 +6512,11 @@ protected Answer execute(final CreateVMSnapshotCommand cmd) { } } - private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List listVolumeTo) throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, + private VM createWorkingVM(Connection conn, String vmName, String guestOSType, String platformEmulator, List listVolumeTo) throws BadServerResponse, + Types.VmBadPowerState, Types.SrFull, Types.OperationNotAllowed, XenAPIException, XmlRpcException { - String guestOsTypeName = getGuestOsType(guestOSType, false); + //below is redundant but keeping for consistency and code readabilty + String guestOsTypeName = platformEmulator; if (guestOsTypeName == null) { String msg = " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; @@ -7098,7 +7101,7 @@ public String toString() { } /*Override by subclass*/ - protected String getGuestOsType(String stdType, boolean bootFromCD) { + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { return stdType; } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java index 170730e9fe..1c49a5b049 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java @@ -27,6 +27,15 @@ import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.NetworkUsageAnswer; @@ -40,14 +49,6 @@ import com.cloud.storage.Storage; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VM; @Local(value = ServerResource.class) public class XcpOssResource extends CitrixResourceBase { @@ -78,6 +79,7 @@ protected boolean launchHeartBeat(Connection conn) { return true; } + @Override protected StartupStorageCommand initializeLocalSR(Connection conn) { SR extsr = getLocalEXTSR(conn); if (extsr != null) { @@ -111,13 +113,17 @@ protected StartupStorageCommand initializeLocalSR(Connection conn) { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { if (stdType.equalsIgnoreCase("Debian GNU/Linux 6(64-bit)")) { return "Debian Squeeze 6.0 (64-bit)"; } else if (stdType.equalsIgnoreCase("CentOS 5.6 (64-bit)")) { return "CentOS 5 (64-bit)"; } else { - return CitrixHelper.getXcpGuestOsType(stdType); + if (platformEmulator == null || platformEmulator.isEmpty()) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XCP's guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } + return platformEmulator; } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServer16Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServer16Resource.java index f5bede815a..3fcbcc463c 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServer16Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServer16Resource.java @@ -19,14 +19,21 @@ package com.cloud.hypervisor.xenserver.resource; +import org.apache.log4j.Logger; + public class XcpServer16Resource extends XcpServerResource { + private final static Logger s_logger = Logger.getLogger(XcpServer16Resource.class); public XcpServer16Resource() { super(); } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXcp160GuestOsType(stdType); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XCP's guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } + return platformEmulator; } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java index 28250084df..b4cc59b0c8 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java @@ -71,8 +71,12 @@ protected List getPatchFiles() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXcpGuestOsType(stdType); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XCP's guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } + return platformEmulator; } protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java index ddedaf5fcd..e1669a58cd 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java @@ -52,8 +52,17 @@ public XenServer56FP1Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer56FP1GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 5.6 FP1 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 5.6 FP1 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java index 4ce8648c8b..d3e17bdedd 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java @@ -16,6 +16,25 @@ // under the License. package com.cloud.hypervisor.xenserver.resource; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.IpConfigurationMode; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; @@ -30,22 +49,6 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SSHCmdHelper; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Types.IpConfigurationMode; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; - -import javax.ejb.Local; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { @@ -63,8 +66,17 @@ public Answer executeRequest(Command cmd) { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServerGuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 5.6 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 5.6 doesn't support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java index cfe6f15918..563f9c3075 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java @@ -39,8 +39,17 @@ public XenServer56SP2Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer56SP2GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 5.6 SP2 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 5.6 SP2 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java index c5f762ca42..4d7fc8bc11 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java @@ -37,8 +37,17 @@ public XenServer600Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer600GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.0.0 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.0.0 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer602Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer602Resource.java index f180adb4aa..042599af1c 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer602Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer602Resource.java @@ -16,7 +16,9 @@ // under the License. package com.cloud.hypervisor.xenserver.resource; import javax.ejb.Local; + import org.apache.log4j.Logger; + import com.cloud.resource.ServerResource; @Local(value = ServerResource.class) @@ -28,8 +30,17 @@ public XenServer602Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer602GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.0.2 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.0.2 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java index 7807f9311f..b099c99e45 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java @@ -73,8 +73,17 @@ public XenServer610Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer610GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.1.0 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.1.0 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java index 0c8cc0beeb..4b43023f36 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java @@ -15,11 +15,6 @@ // specific language governing permissions and limitations // under the License. package com.cloud.hypervisor.xenserver.resource; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.HostPatch; -import com.xensource.xenapi.PoolPatch; -import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; import java.util.Map; import java.util.Set; @@ -27,6 +22,13 @@ import org.apache.log4j.Logger; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.HostPatch; +import com.xensource.xenapi.PoolPatch; + +import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; + import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.resource.ServerResource; @@ -39,8 +41,17 @@ public XenServer620Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer620GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.2.0 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.2.0 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override @@ -91,6 +102,7 @@ protected boolean hostHasHotFix(Connection conn, String hotFixUuid) { return false; } + @Override protected void fillHostInfo(Connection conn, StartupRoutingCommand cmd) { super.fillHostInfo(conn, cmd); Map details = cmd.getHostDetails(); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java index 3584ff2910..8e2376409c 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java @@ -28,15 +28,6 @@ import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.GetGPUStatsAnswer; -import com.cloud.agent.api.GetGPUStatsCommand; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StartupRoutingCommand; -import com.cloud.agent.api.VgpuTypesInfo; -import com.cloud.agent.api.to.GPUDeviceTO; -import com.cloud.resource.ServerResource; import com.xensource.xenapi.Connection; import com.xensource.xenapi.GPUGroup; import com.xensource.xenapi.Host; @@ -47,6 +38,16 @@ import com.xensource.xenapi.VGPUType.Record; import com.xensource.xenapi.VM; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetGPUStatsAnswer; +import com.cloud.agent.api.GetGPUStatsCommand; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.VgpuTypesInfo; +import com.cloud.agent.api.to.GPUDeviceTO; +import com.cloud.resource.ServerResource; + @Local(value=ServerResource.class) public class XenServer620SP1Resource extends XenServer620Resource { private static final Logger s_logger = Logger.getLogger(XenServer620SP1Resource.class); @@ -164,8 +165,17 @@ protected void createVGPU(Connection conn, StartCommand cmd, VM vm, GPUDeviceTO } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer620SP1GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.2.0 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.2.0 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java index 546f32c04f..de108e46d9 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java @@ -28,9 +28,9 @@ import org.apache.xmlrpc.XmlRpcException; import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; import com.xensource.xenapi.Types; import com.xensource.xenapi.VM; -import com.xensource.xenapi.Host; import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase; @@ -50,8 +50,17 @@ public Xenserver625Resource() { } @Override - protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer625GuestOsType(stdType, bootFromCD); + protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + if (platformEmulator == null) { + if (!bootFromCD) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XenServer 6.2.5 guestOS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } else { + String msg = "XenServer 6.2.5 DOES NOT support Guest OS type " + stdType; + s_logger.warn(msg); + } + } + return platformEmulator; } @Override From 36e5cc2b6a87d7d142edac9574e3faa13afb1253 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 14 Jul 2014 15:48:09 -0700 Subject: [PATCH 065/819] Fix for non-grouped detail view Fix issue where non-grouped detail page (i.e., instances stats page) doesn't load due to the fields being passed as an object, not an array. --- ui/scripts/ui/widgets/detailView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index 8824adc224..0fa3fd0718 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -910,7 +910,7 @@ var isOddRow = false; // Even/odd row coloring var $header; var detailViewArgs = $detailView.data('view-args'); - var fields = tabData.fields.slice(); + var fields = $.isArray(tabData.fields) ? tabData.fields.slice() : tabData.fields; var hiddenFields; var context = $.extend(true, {}, detailViewArgs ? detailViewArgs.context : cloudStack.context); var isMultiple = tabData.multiple || tabData.isMultiple; From 09069fcc87e1b595cafea726fb0d3c49313cd8da Mon Sep 17 00:00:00 2001 From: Amogh Vasekar Date: Wed, 7 May 2014 15:16:55 -0700 Subject: [PATCH 066/819] CLOUDSTACK-6358: Add missing patches in master for KVM --- .../storage/dao/GuestOSHypervisorDaoImpl.java | 6 +- .../resource/LibvirtComputingResource.java | 157 +++++++++--------- .../hypervisor/kvm/resource/LibvirtVMDef.java | 9 + .../kvm/resource/VifDriverBase.java | 4 +- server/src/com/cloud/hypervisor/KVMGuru.java | 14 +- 5 files changed, 108 insertions(+), 82 deletions(-) diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java index 05188296f5..5a855b29f1 100644 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java @@ -66,9 +66,13 @@ public HypervisorType findHypervisorTypeByGuestOsId(long guestOsId) { @Override public GuestOSHypervisorVO findByOsIdAndHypervisor(long guestOsId, String hypervisorType, String hypervisorVersion) { SearchCriteria sc = mappingSearch.create(); + String version = "default"; + if (!(hypervisorVersion == null || hypervisorVersion.isEmpty())) { + version = hypervisorVersion; + } sc.setParameters("guest_os_id", guestOsId); sc.setParameters("hypervisor_type", hypervisorType); - sc.setParameters("hypervisor_version", hypervisorVersion); + sc.setParameters("hypervisor_version", version); return findOneBy(sc); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 4065188cf1..d4d663c94b 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -16,12 +16,79 @@ // under the License. package com.cloud.hypervisor.kvm.resource; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainBlockStats; +import org.libvirt.DomainInfo; +import org.libvirt.DomainInterfaceStats; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; +import org.libvirt.NodeInfo; +import org.libvirt.StorageVol; + import com.ceph.rados.IoCTX; import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -202,71 +269,6 @@ import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.log4j.Logger; -import org.libvirt.Connect; -import org.libvirt.Domain; -import org.libvirt.DomainBlockStats; -import org.libvirt.DomainInfo; -import org.libvirt.DomainInterfaceStats; -import org.libvirt.DomainSnapshot; -import org.libvirt.LibvirtException; -import org.libvirt.NodeInfo; -import org.libvirt.StorageVol; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * LibvirtComputingResource execute requests on the computing/routing host using * the libvirt API @@ -2013,7 +2015,7 @@ private void VifHotPlug(Connect conn, String vmName, String broadcastUri, String } Domain vm = getDomain(conn, vmName); - vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV (32-bit)", "").toString()); + vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV", "").toString()); } @@ -2050,7 +2052,7 @@ private PlugNicAnswer execute(PlugNicCommand cmd) { } nicnum++; } - vm.attachDevice(getVifDriver(nic.getType()).plug(nic, "Other PV (32-bit)", "").toString()); + vm.attachDevice(getVifDriver(nic.getType()).plug(nic, "Other PV", "").toString()); return new PlugNicAnswer(cmd, true, "success"); } catch (LibvirtException e) { String msg = " Plug Nic failed due to " + e.toString(); @@ -3648,6 +3650,7 @@ protected LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) { uuid = getUuid(uuid); vm.setDomUUID(uuid); vm.setDomDescription(vmTO.getOs()); + vm.setPlatformEmulator(vmTO.getPlatformEmulator()); GuestDef guest = new GuestDef(); @@ -3961,9 +3964,8 @@ public int compare(DiskTO arg0, DiskTO arg1) { } if (diskBusType == null) { - diskBusType = getGuestDiskModel(vmSpec.getOs()); + diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator()); } - DiskDef disk = new DiskDef(); if (volume.getType() == Volume.Type.ISO) { if (volPath == null) { @@ -4043,7 +4045,7 @@ public int compare(DiskTO arg0, DiskTO arg1) { } private void createVif(LibvirtVMDef vm, NicTO nic, String nicAdapter) throws InternalErrorException, LibvirtException { - vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getGuestOSType(), nicAdapter).toString()); + vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getPlatformEmulator().toString(), nicAdapter).toString()); } protected CheckSshAnswer execute(CheckSshCommand cmd) { @@ -4977,16 +4979,15 @@ private String getGuestType(Connect conn, String vmName) { } } - boolean isGuestPVEnabled(String guestOS) { - if (guestOS == null) { + boolean isGuestPVEnabled(String guestOSName) { + if (guestOSName == null) { return false; } - String guestOSName = KVMGuestOsMapper.getGuestOsName(guestOS); - if (guestOS.startsWith("Ubuntu") || guestOSName.startsWith("Fedora 13") || guestOSName.startsWith("Fedora 12") || guestOSName.startsWith("Fedora 11") || + if (guestOSName.startsWith("Ubuntu") || guestOSName.startsWith("Fedora 13") || guestOSName.startsWith("Fedora 12") || guestOSName.startsWith("Fedora 11") || guestOSName.startsWith("Fedora 10") || guestOSName.startsWith("Fedora 9") || guestOSName.startsWith("CentOS 5.3") || guestOSName.startsWith("CentOS 5.4") || - guestOSName.startsWith("CentOS 5.5") || guestOS.startsWith("CentOS") || guestOS.startsWith("Fedora") || + guestOSName.startsWith("CentOS 5.5") || guestOSName.startsWith("CentOS") || guestOSName.startsWith("Fedora") || guestOSName.startsWith("Red Hat Enterprise Linux 5.3") || guestOSName.startsWith("Red Hat Enterprise Linux 5.4") || - guestOSName.startsWith("Red Hat Enterprise Linux 5.5") || guestOSName.startsWith("Red Hat Enterprise Linux 6") || guestOS.startsWith("Debian GNU/Linux") || + guestOSName.startsWith("Red Hat Enterprise Linux 5.5") || guestOSName.startsWith("Red Hat Enterprise Linux 6") || guestOSName.startsWith("Debian GNU/Linux") || guestOSName.startsWith("FreeBSD 10") || guestOSName.startsWith("Other PV")) { return true; } else { @@ -5002,8 +5003,8 @@ public boolean isCentosHost() { } } - private DiskDef.diskBus getGuestDiskModel(String guestOSType) { - if (isGuestPVEnabled(guestOSType)) { + private DiskDef.diskBus getGuestDiskModel(String platformEmulator) { + if (isGuestPVEnabled(platformEmulator)) { return DiskDef.diskBus.VIRTIO; } else { return DiskDef.diskBus.IDE; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 4ab794bdd2..8084035d84 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -28,6 +28,7 @@ public class LibvirtVMDef { private String _domName; private String _domUUID; private String _desc; + private String _platformEmulator; private final Map components = new HashMap(); public static class GuestDef { @@ -1197,6 +1198,14 @@ public String getGuestOSType() { return _desc; } + public void setPlatformEmulator(String platformEmulator) { + _platformEmulator = platformEmulator; + } + + public String getPlatformEmulator() { + return _platformEmulator; + } + public void addComp(Object comp) { components.put(comp.getClass().toString(), comp); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java index f41dc5655d..92ab623c68 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java @@ -47,7 +47,7 @@ public void configure(Map params) throws ConfigurationException @Override public abstract void unplug(LibvirtVMDef.InterfaceDef iface); - protected LibvirtVMDef.InterfaceDef.nicModel getGuestNicModel(String guestOSType, String nicAdapter) { + protected LibvirtVMDef.InterfaceDef.nicModel getGuestNicModel(String platformEmulator, String nicAdapter) { // if nicAdapter is found in ENUM, use it. Otherwise, match guest OS type as before if (nicAdapter != null && !nicAdapter.isEmpty()) { for (LibvirtVMDef.InterfaceDef.nicModel model : LibvirtVMDef.InterfaceDef.nicModel.values()) { @@ -57,7 +57,7 @@ protected LibvirtVMDef.InterfaceDef.nicModel getGuestNicModel(String guestOSType } } - if (_libvirtComputingResource.isGuestPVEnabled(guestOSType)) { + if (_libvirtComputingResource.isGuestPVEnabled(platformEmulator)) { return LibvirtVMDef.InterfaceDef.nicModel.VIRTIO; } else { return LibvirtVMDef.InterfaceDef.nicModel.E1000; diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/com/cloud/hypervisor/KVMGuru.java index 174b32db57..4225232064 100644 --- a/server/src/com/cloud/hypervisor/KVMGuru.java +++ b/server/src/com/cloud/hypervisor/KVMGuru.java @@ -19,19 +19,28 @@ import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; + import com.cloud.agent.api.Command; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; @Local(value = HypervisorGuru.class) public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject GuestOSDao _guestOsDao; + @Inject + GuestOSHypervisorDao _guestOsHypervisorDao; + @Inject + HostDao _hostDao; @Override public HypervisorType getHypervisorType() { @@ -50,6 +59,9 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); + HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId()); + GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); return to; } From 62e63a1bf7b9f3326523fd30278847f4dcf794a4 Mon Sep 17 00:00:00 2001 From: amoghvk Date: Mon, 9 Jun 2014 17:06:26 -0700 Subject: [PATCH 067/819] CLOUDSTACK-6358: Missing patches in master for VMware --- .../vmsnapshot/DefaultVMSnapshotStrategy.java | 12 +++++++++- .../com/cloud/hypervisor/guru/VMwareGuru.java | 11 +++++++++ .../vmware/resource/VmwareResource.java | 24 ++++++++++++++----- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java index 9154b347fc..c5c54df4a9 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java @@ -138,7 +138,11 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) { GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(), target, volumeTOs, guestOS.getDisplayName(), userVm.getState()); - ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); + if (guestOsMapping == null) { + ccmd.setPlatformEmulator(null); + } else { + ccmd.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } ccmd.setWait(_wait); answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd); @@ -349,6 +353,12 @@ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) { RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); HostVO host = hostDao.findById(hostId); GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); + RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); + if (guestOsMapping == null) { + revertToSnapshotCommand.setPlatformEmulator(null); + } else { + revertToSnapshotCommand.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer)agentMgr.send(hostId, revertToSnapshotCommand); if (answer != null && answer.getResult()) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 77c45b26b7..08d12f2eb7 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -81,11 +81,13 @@ import com.cloud.secstorage.CommandExecLogDao; import com.cloud.secstorage.CommandExecLogVO; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.Storage; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.template.VirtualMachineTemplate.BootloaderType; @@ -112,6 +114,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co @Inject private GuestOSDao _guestOsDao; @Inject + GuestOSHypervisorDao _guestOsHypervisorDao; + @Inject private HostDao _hostDao; @Inject private HostDetailsDao _hostDetailsDao; @@ -309,6 +313,13 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); to.setHostName(vm.getHostName()); + HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId()); + GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); + if (guestOsMapping == null) { + to.setPlatformEmulator(null); + } else { + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } return to; } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 15eeb13bcd..494cf66ec6 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.TimeZone; import java.util.UUID; + import javax.naming.ConfigurationException; import org.apache.log4j.Logger; @@ -238,7 +239,6 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostNetworkSummary; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; -import com.cloud.hypervisor.vmware.util.VmwareGuestOsMapper; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; @@ -1408,7 +1408,7 @@ protected StartAnswer execute(StartCommand cmd) { tearDownVm(vmMo); }else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), - translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) { + translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value(), rootDiskDataStoreDetails.first(), false)) { throw new Exception("Failed to create VM. vmName: " + vmInternalCSName); } } @@ -1432,7 +1432,7 @@ protected StartAnswer execute(StartCommand cmd) { } VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); - String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(); + String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value(); VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), @@ -4426,13 +4426,25 @@ protected OptionValue[] configureVnc(OptionValue[] optionsToMerge, VmwareHypervi } } - private VirtualMachineGuestOsIdentifier translateGuestOsIdentifier(String cpuArchitecture, String cloudGuestOs) { + private VirtualMachineGuestOsIdentifier translateGuestOsIdentifier(String cpuArchitecture, String guestOs, String cloudGuestOs) { if (cpuArchitecture == null) { - s_logger.warn("CPU arch is not set, default to i386. guest os: " + cloudGuestOs); + s_logger.warn("CPU arch is not set, default to i386. guest os: " + guestOs); cpuArchitecture = "i386"; } - VirtualMachineGuestOsIdentifier identifier = VmwareGuestOsMapper.getGuestOsIdentifier(cloudGuestOs); + if(cloudGuestOs == null) { + s_logger.warn("Guest OS mapping name is not set for guest os: " + guestOs); + } + + VirtualMachineGuestOsIdentifier identifier = null; + try { + if (cloudGuestOs != null) { + identifier = VirtualMachineGuestOsIdentifier.fromValue(cloudGuestOs); + s_logger.debug("Using mapping name : " + identifier.toString()); + } + } catch (IllegalArgumentException e) { + s_logger.warn("Unable to find Guest OS Identifier in VMware for mapping name: " + cloudGuestOs + ". Continuing with defaults."); + } if (identifier != null) { return identifier; } From c30821f7039966ce9d87a1bb092d6a94e20dad68 Mon Sep 17 00:00:00 2001 From: Amogh Vasekar Date: Wed, 21 May 2014 08:26:15 -0700 Subject: [PATCH 068/819] CLOUDSTACK-6671: Missing patch in master --- .../com/cloud/hypervisor/XenServerGuru.java | 6 +++++- server/src/com/cloud/hypervisor/KVMGuru.java | 6 +++++- setup/db/db/schema-430to440.sql | 21 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java index 620d7113f4..c10f4a0ba1 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java @@ -93,7 +93,11 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { to.setOs(guestOS.getDisplayName()); HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId()); GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); - to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + if (guestOsMapping == null) { + to.setPlatformEmulator(null); + } else { + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } return to; } diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/com/cloud/hypervisor/KVMGuru.java index 4225232064..287b0d2f1e 100644 --- a/server/src/com/cloud/hypervisor/KVMGuru.java +++ b/server/src/com/cloud/hypervisor/KVMGuru.java @@ -61,7 +61,11 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { to.setOs(guestOS.getDisplayName()); HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId()); GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); - to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + if (guestOsMapping == null) { + to.setPlatformEmulator(null); + } else { + to.setPlatformEmulator(guestOsMapping.getGuestOsName()); + } return to; } diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index d89e32f883..c669283345 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -1733,3 +1733,24 @@ CREATE TABLE `cloud`.`snapshot_policy_details` ( CONSTRAINT `fk_snapshot_policy_details__snapshot_policy_id` FOREIGN KEY `fk_snapshot_policy_details__snapshot_policy_id`(`policy_id`) REFERENCES `snapshot_policy`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5 (64-bit)', 140, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 12.04', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows Server 2008', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 2000', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows NT', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 3.1', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 160, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 225, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 226, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 140, now(), 0); From 33d6bc278f9645e7ab9942f508971669414538f0 Mon Sep 17 00:00:00 2001 From: amoghvk Date: Mon, 14 Jul 2014 17:42:27 -0700 Subject: [PATCH 069/819] Adding missing modified file --- .../cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java index c5c54df4a9..17a9f790d2 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java @@ -353,7 +353,6 @@ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) { RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); HostVO host = hostDao.findById(hostId); GuestOSHypervisorVO guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion()); - RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName()); if (guestOsMapping == null) { revertToSnapshotCommand.setPlatformEmulator(null); } else { From aacf8ef77b9859329be5199dad195f7ebcd8dbf6 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Tue, 15 Jul 2014 14:23:17 +0530 Subject: [PATCH 070/819] Findbugs fixes in cloud-utils project and a few other places --- api/src/com/cloud/agent/api/to/NicTO.java | 6 ++-- .../orchestration/VolumeOrchestrator.java | 2 +- .../cloud/usage/dao/UsageVolumeDaoImpl.java | 2 +- .../dao/ManagementServerHostDaoImpl.java | 6 ++-- utils/src/com/cloud/utils/NumbersUtil.java | 34 +++++++++++-------- utils/src/com/cloud/utils/SwiftUtil.java | 2 +- utils/src/com/cloud/utils/UriUtils.java | 4 +-- utils/src/com/cloud/utils/net/NetUtils.java | 4 +-- .../com/cloud/utils/ssh/SSHKeysHelper.java | 5 ++- .../storage/encoding/DecodedDataObject.java | 1 + 10 files changed, 37 insertions(+), 29 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java index 0cbc2d8ec9..bd681f282c 100644 --- a/api/src/com/cloud/agent/api/to/NicTO.java +++ b/api/src/com/cloud/agent/api/to/NicTO.java @@ -24,7 +24,7 @@ public class NicTO extends NetworkTO { Integer networkRateMulticastMbps; boolean defaultNic; boolean pxeDisable; - String uuid; + String nicUuid; List nicSecIps; public NicTO() { @@ -69,12 +69,12 @@ public boolean getPxeDisable() { @Override public String getUuid() { - return uuid; + return nicUuid; } @Override public void setUuid(String uuid) { - this.uuid = uuid; + this.nicUuid = uuid; } @Override diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 9ba3451731..098f976bf0 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -756,7 +756,7 @@ public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo vol ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId()); DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId()); - Long clusterId = (storagePool == null ? null : storagePool.getClusterId()); + Long clusterId = storagePool.getClusterId(); VolumeInfo vol = null; if (volume.getState() == Volume.State.Allocated) { diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java index 5beafa6039..7ef4222f92 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java @@ -88,8 +88,8 @@ public void update(UsageVolumeVO usage) { pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); pstmt.setLong(2, usage.getAccountId()); pstmt.setLong(3, usage.getId()); + pstmt.executeUpdate(); } - pstmt.executeUpdate(); txn.commit(); } catch (Exception e) { txn.rollback(); diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 97b9a54e00..ce4667ecc0 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -61,7 +61,7 @@ public void invalidateRunSession(long id, long runid) { pstmt.executeUpdate(); } catch (SQLException e) { - throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); + throw new CloudRuntimeException("DB exception: ", e); } } @@ -227,7 +227,7 @@ public void update(long id, long runId, State state, Date lastUpdate) { throw new CloudRuntimeException("Invalid cluster session detected, runId " + runId + " is no longer valid", new ClusterInvalidSessionException("runId " + runId + " is no longer valid")); } } catch (SQLException e) { - throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); + throw new CloudRuntimeException("DB exception: ", e); } } @@ -255,7 +255,7 @@ public List listOrphanMsids() { orphanList.add(rs.getLong(1)); } } catch (SQLException e) { - throw new CloudRuntimeException("DB exception on " + pstmt.toString(), e); + throw new CloudRuntimeException("DB exception: ", e); } return orphanList; diff --git a/utils/src/com/cloud/utils/NumbersUtil.java b/utils/src/com/cloud/utils/NumbersUtil.java index fd5c77f89f..8b93a40e9c 100755 --- a/utils/src/com/cloud/utils/NumbersUtil.java +++ b/utils/src/com/cloud/utils/NumbersUtil.java @@ -101,24 +101,28 @@ public static String toReadableSize(long bytes) { * @return interval in ms */ public static long parseInterval(String str, long defaultValue) { - SimpleDateFormat sdf = null; - if (str.contains("D")) { - sdf = new SimpleDateFormat("dd'D'HH'h'mm'M'ss'S'SSS'ms'"); - } else if (str.contains("h")) { - sdf = new SimpleDateFormat("HH'h'mm'M'ss'S'SSS'ms'"); - } else if (str.contains("M")) { - sdf = new SimpleDateFormat("mm'M'ss'S'SSS'ms'"); - } else if (str.contains("S")) { - sdf = new SimpleDateFormat("ss'S'SSS'ms'"); - } else if (str.contains("ms")) { - sdf = new SimpleDateFormat("SSS'ms'"); - } - Date date; try { - if (str == null || sdf == null) { + if (str == null) { + throw new ParseException("String is wrong", 0); + } + + SimpleDateFormat sdf = null; + if (str.contains("D")) { + sdf = new SimpleDateFormat("dd'D'HH'h'mm'M'ss'S'SSS'ms'"); + } else if (str.contains("h")) { + sdf = new SimpleDateFormat("HH'h'mm'M'ss'S'SSS'ms'"); + } else if (str.contains("M")) { + sdf = new SimpleDateFormat("mm'M'ss'S'SSS'ms'"); + } else if (str.contains("S")) { + sdf = new SimpleDateFormat("ss'S'SSS'ms'"); + } else if (str.contains("ms")) { + sdf = new SimpleDateFormat("SSS'ms'"); + } + if (sdf == null) { throw new ParseException("String is wrong", 0); } - date = sdf.parse(str); + + Date date = sdf.parse(str); return date.getTime(); } catch (ParseException e) { if (defaultValue != -1) { diff --git a/utils/src/com/cloud/utils/SwiftUtil.java b/utils/src/com/cloud/utils/SwiftUtil.java index 07a7292be6..1136818dee 100644 --- a/utils/src/com/cloud/utils/SwiftUtil.java +++ b/utils/src/com/cloud/utils/SwiftUtil.java @@ -100,7 +100,7 @@ public static String putObject(SwiftClientCfg cfg, File srcFile, String containe String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed") || line.contains("not found")) { - throw new CloudRuntimeException("Failed to upload file: " + lines.toString()); + throw new CloudRuntimeException("Failed to upload file: " + Arrays.toString(lines)); } } } diff --git a/utils/src/com/cloud/utils/UriUtils.java b/utils/src/com/cloud/utils/UriUtils.java index a329503220..6b28afb2ea 100644 --- a/utils/src/com/cloud/utils/UriUtils.java +++ b/utils/src/com/cloud/utils/UriUtils.java @@ -205,9 +205,9 @@ public static Long getRemoteSize(String url) { URI uri = new URI(url); if (uri.getScheme().equalsIgnoreCase("http")) { httpConn = (HttpURLConnection)uri.toURL().openConnection(); - httpConn.setConnectTimeout(2000); - httpConn.setReadTimeout(5000); if (httpConn != null) { + httpConn.setConnectTimeout(2000); + httpConn.setReadTimeout(5000); String contentLength = httpConn.getHeaderField("content-length"); if (contentLength != null) { remoteSize = Long.parseLong(contentLength); diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index cde97d47c0..1b2c0e8642 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -1420,10 +1420,10 @@ public static boolean isValidVlan(String vlan) { public static boolean isSameIsolationId(String one, String other) { // check nulls // check empty strings - if ((one == null || one.equals("")) && (other == null || other.equals(""))) { + if ((one == null || one.isEmpty()) && (other == null || other.isEmpty())) { return true; } - if ((one == null || other == null) && !(one == null && other == null)) { + if (one == null || other == null) { return false; } // check 'untagged' diff --git a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java index ab54c2c204..39db5c46c1 100644 --- a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java +++ b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java @@ -69,8 +69,11 @@ public static String getPublicKeyFingerprint(String publicKey) { e.printStackTrace(); } - String sumString = toHexString(md5.digest(keyBytes)); String rString = ""; + String sumString = ""; + if (md5 != null) { + sumString = toHexString(md5.digest(keyBytes)); + } for (int i = 2; i <= sumString.length(); i += 2) { rString += sumString.substring(i - 2, i); diff --git a/utils/src/com/cloud/utils/storage/encoding/DecodedDataObject.java b/utils/src/com/cloud/utils/storage/encoding/DecodedDataObject.java index d8d354d6a2..56be69936b 100644 --- a/utils/src/com/cloud/utils/storage/encoding/DecodedDataObject.java +++ b/utils/src/com/cloud/utils/storage/encoding/DecodedDataObject.java @@ -29,6 +29,7 @@ public class DecodedDataObject { public DecodedDataObject(String objType, Long size, String name, String path, DecodedDataStore store) { this.objType = objType; this.size = size; + this.name = name; this.path = path; this.store = store; } From e8c32c7f5b21edda8cb67b2d477cf34e1faeb677 Mon Sep 17 00:00:00 2001 From: Joris van Lieshout Date: Mon, 14 Jul 2014 11:09:41 +0200 Subject: [PATCH 071/819] Disable inband management of openvswitch on the link local network. You don't want instances connected to this network to be able to talk to the openvswitch management interface. Signed-off-by: Daan Hoogland --- .../hypervisor/xenserver/resource/CitrixResourceBase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 0f42df3cc1..5881d6809a 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -4455,11 +4455,14 @@ private void setupLinkLocalNetwork(Connection conn) { configs.put("ip_begin", NetUtils.getLinkLocalGateway()); configs.put("ip_end", NetUtils.getLinkLocalIpEnd()); configs.put("netmask", NetUtils.getLinkLocalNetMask()); + configs.put("vswitch-disable-in-band", "true"); rec.otherConfig = configs; linkLocal = Network.create(conn, rec); - } else { linkLocal = networks.iterator().next(); + if (!linkLocal.getOtherConfig(conn).containsKey("vswitch-disable-in-band")) { + linkLocal.addToOtherConfig(conn, "vswitch-disable-in-band", "true"); + } } /* Make sure there is a physical bridge on this network */ From 733102c742aff81f2a781b2884a2d22172ea9018 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Tue, 15 Jul 2014 11:04:37 -0700 Subject: [PATCH 072/819] change XS log file name from vmops.log to cloud.log --- scripts/vm/hypervisor/xenserver/cloudlog | 2 +- scripts/vm/hypervisor/xenserver/vmops | 6 +++--- scripts/vm/hypervisor/xenserver/vmopsSnapshot | 6 +++--- scripts/vm/hypervisor/xenserver/vmopspremium | 6 +++--- .../hypervisor/xenserver/xenserver62/cloud-plugin-storage | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/cloudlog b/scripts/vm/hypervisor/xenserver/cloudlog index 14e0cdd0c5..bc78596efe 100644 --- a/scripts/vm/hypervisor/xenserver/cloudlog +++ b/scripts/vm/hypervisor/xenserver/cloudlog @@ -23,7 +23,7 @@ -/var/log/cloud/vmops.log { +/var/log/cloud/cloud.log { daily size 1M rotate 20 diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 3f25a2e7f9..2fd0619536 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -37,14 +37,14 @@ import cloudstack_pluginlib as lib import logging from util import CommandException -lib.setup_logging("/var/log/cloud/vmops.log") +lib.setup_logging("/var/log/cloud/cloud.log") def echo(fn): def wrapped(*v, **k): name = fn.__name__ - logging.debug("#### VMOPS enter %s ####" % name ) + logging.debug("#### CLOUD enter %s ####" % name ) res = fn(*v, **k) - logging.debug("#### VMOPS exit %s ####" % name ) + logging.debug("#### CLOUD exit %s ####" % name ) return res return wrapped diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot index 5fd69a633f..3aeafa53b1 100755 --- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot +++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot @@ -41,7 +41,7 @@ import random import cloudstack_pluginlib as lib import logging -lib.setup_logging("/var/log/cloud/vmops.log") +lib.setup_logging("/var/log/cloud/cloud.log") VHDUTIL = "vhd-util" VHD_PREFIX = 'VHD-' @@ -50,9 +50,9 @@ CLOUD_DIR = '/var/run/cloud_mount' def echo(fn): def wrapped(*v, **k): name = fn.__name__ - logging.debug("#### VMOPS enter %s ####" % name ) + logging.debug("#### CLOUD enter %s ####" % name ) res = fn(*v, **k) - logging.debug("#### VMOPS exit %s ####" % name ) + logging.debug("#### CLOUD exit %s ####" % name ) return res return wrapped diff --git a/scripts/vm/hypervisor/xenserver/vmopspremium b/scripts/vm/hypervisor/xenserver/vmopspremium index 2887436670..461e4059b2 100755 --- a/scripts/vm/hypervisor/xenserver/vmopspremium +++ b/scripts/vm/hypervisor/xenserver/vmopspremium @@ -31,14 +31,14 @@ import socket import cloudstack_pluginlib as lib import logging -lib.setup_logging("/var/log/cloud/vmops.log") +lib.setup_logging("/var/log/cloud/cloud.log") def echo(fn): def wrapped(*v, **k): name = fn.__name__ - logging.debug("#### VMOPS enter %s ####" % name ) + logging.debug("#### CLOUD enter %s ####" % name ) res = fn(*v, **k) - logging.debug("#### VMOPS exit %s ####" % name ) + logging.debug("#### CLOUD exit %s ####" % name ) return res return wrapped diff --git a/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage b/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage index 03a05b7548..207d4f4800 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage +++ b/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage @@ -41,7 +41,7 @@ import random import cloudstack_pluginlib as lib import logging -lib.setup_logging("/var/log/cloud/vmops.log") +lib.setup_logging("/var/log/cloud/cloud.log") VHDUTIL = "vhd-util" VHD_PREFIX = 'VHD-' @@ -50,9 +50,9 @@ CLOUD_DIR = '/var/run/cloud_mount' def echo(fn): def wrapped(*v, **k): name = fn.__name__ - logging.debug("#### VMOPS enter %s ####" % name ) + logging.debug("#### CLOUD enter %s ####" % name ) res = fn(*v, **k) - logging.debug("#### VMOPS exit %s ####" % name ) + logging.debug("#### CLOUD exit %s ####" % name ) return res return wrapped From b58371e5204feb431395f383a36c5d99d11d002e Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 15 Jul 2014 13:30:56 -0700 Subject: [PATCH 073/819] List view: Fix action pre-filter for multiselect actions Evaluates pre-filter for individual actions (i.e., when action.preFilter is specified) every time a multi-select row is checked orunchecked. This allows multi-select actions to be shown/hidden on a per-row basis. --- ui/scripts/ui/widgets/listView.js | 48 +++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 509c802c4f..9626a64667 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1748,12 +1748,21 @@ // List view header actions if (listViewData.actions) { $.each(listViewData.actions, function(actionName, action) { - if (!action.isHeader || ( - action.preFilter && !action.preFilter({ + var preFilter = function(extendContext) { + var context = $.extend(true, {}, + $listView.data('view-args').context ? $listView.data('view-args').context : cloudStack.context); + + if (extendContext) { + $.extend(context, extendContext); + } + + return action.preFilter ? action.preFilter({ id: listViewData.id, - context: $listView.data('view-args').context ? $listView.data('view-args').context : cloudStack.context - }) - )) return true; + context: context + }) : null; + } + + if (!action.isHeader || (action.preFilter && !preFilter())) return true; var $action = $('

') .addClass('button action main-action reduced-hide').addClass(actionName) @@ -1764,6 +1773,10 @@ if (action.isMultiSelectAction) { $action.addClass('multiSelectAction'); $action.hide(); + + if (action.preFilter) { + $action.data('list-view-action-prefilter', preFilter); + } } $toolbar.append($action) @@ -2234,9 +2247,32 @@ }; var toggleMultiSelectActions = function($listView, enabled) { + var $multiSelectActions = $listView.find('div.main-action.multiSelectAction'); + $listView.find('div.action.add')[enabled ? 'hide' : 'show'](); $listView.find('div.main-action:not(.multiSelectAction)')[enabled ? 'hide' : 'show'](); - $listView.find('div.main-action.multiSelectAction')[enabled ? 'show' : 'hide'](); + $multiSelectActions.hide(); + + if (enabled) { + $multiSelectActions.filter(function() { + var preFilter = $(this).data('list-view-action-prefilter'); + var $selectedVMs; + var context = {}; + + if (preFilter) { + $selectedVMs = $listView.find('tbody tr').filter(function() { + return $(this).find('td.multiselect input[type=checkbox]:checked').size() + }); + context[$listView.data('view-args').activeSection] = $selectedVMs.map(function(index, item) { + return $(item).data('json-obj'); + }); + + return preFilter(context); + } + + return true; + }).show(); + } } $.fn.listView = function(args, options) { From 9b2565dccae94fd0751979424e32b41c196ee4f1 Mon Sep 17 00:00:00 2001 From: amoghvk Date: Mon, 9 Jun 2014 14:59:31 -0700 Subject: [PATCH 074/819] CLOUDSTACK-6710: Add missing OS mappings --- setup/db/db/schema-430to440.sql | 706 ++++++++++++++++++++++++++++++++ 1 file changed, 706 insertions(+) diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index c669283345..607c5068db 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -1690,6 +1690,712 @@ ALTER TABLE `cloud`.`load_balancer_healthcheck_policies` ADD COLUMN `display` ti ALTER TABLE `cloud`.`load_balancer_stickiness_policies` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.1', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.0', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.1', 'ubuntu64Guest', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Server64Guest', 168, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 114, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 34, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 33, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winVistaGuest', 56, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 203, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 130, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 38, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ServGuest', 55, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin11_64Guest', 224, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 28, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian4Guest', 73, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetEnterprise64Guest', 51, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin10_64Guest', 222, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 32, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 96, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'other26xLinuxGuest', 75, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 93, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 202, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetDatacenterGuest', 87, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 100, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin11Guest', 223, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8_64Guest', 166, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian4_64Guest', 74, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 37, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows7Guest', 48, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'asianux3Guest', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest64', 103, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winVista64Guest', 101, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 111, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 128, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghorn64Guest', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'darwin10Guest', 221, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 11, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetWebGuest', 91, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'asianux3_64Guest', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris10Guest', 79, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 124, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherLinux64Guest', 99, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'freebsdGuest', 83, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetStandardGuest', 89, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris10_64Guest', 80, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win98Guest', 62, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 129, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 35, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetStandard64Guest', 90, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetEnterpriseGuest', 50, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6Guest', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win95Guest', 63, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win31Guest', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 5, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 110, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian5Guest', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'debian5_64Guest', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 123, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 8, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 58, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Guest', 165, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 26, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetDatacenter64Guest', 88, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 30, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel6_64Guest', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 163, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 36, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 13, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows8Server64Guest', 167, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPProGuest', 57, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 12, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 59, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'netware6Guest', 77, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 97, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 109, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 1, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 27, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 31, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris8Guest', 82, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 39, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 125, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'os2Guest', 104, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel2Guest', 131, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 112, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 201, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winXPPro64Guest', 94, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherLinuxGuest', 98, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suse64Guest', 108, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 6, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 126, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5_64Guest', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'unixWare7Guest', 86, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000AdvServGuest', 95, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 127, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNetBusinessGuest', 92, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'dosGuest', 102, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ServGuest', 61, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'windows7_64Guest', 49, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'win2000ProGuest', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'netware5Guest', 78, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 7, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest', 85, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 200, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 122, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntuGuest', 121, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'oesGuest', 68, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghornGuest', 52, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 3, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel4Guest', 29, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'other26xLinux64Guest', 76, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'freebsd64Guest', 84, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 9, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'solaris9Guest', 81, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'otherGuest', 60, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winLonghorn64Guest', 53, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel5Guest', 113, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'suseGuest', 107, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 4, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 14, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 10, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'winNTGuest', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centos64Guest', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'centosGuest', 2, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'ubuntu64Guest', 164, now(), 0); + alter table `cloud`.`user_ip_address` add column removed datetime DEFAULT NULL COMMENT 'date removed'; alter table `cloud`.`user_ip_address` add column created datetime NULL COMMENT 'date created'; From 854f6ce3eede60239d5a082bd1d08354223c4fff Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 15 Jul 2014 16:19:23 -0700 Subject: [PATCH 075/819] UI > network > Edit Network action > not pass networkdomain parameter to updateNetwork API when input field is empty. --- ui/scripts/network.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 3c8107b95e..b3a003d06e 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -913,7 +913,7 @@ }; //args.data.networkdomain is null when networkdomain field is hidden - if (args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) { + if (args.data.networkdomain != null && args.data.networkdomain.length > 0 && args.data.networkdomain != args.context.networks[0].networkdomain) { $.extend(data, { networkdomain: args.data.networkdomain }); From dfee7b1456e9490889f93060023555d898bf5ae5 Mon Sep 17 00:00:00 2001 From: sanjeevneelarapu Date: Thu, 26 Jun 2014 22:27:57 +0530 Subject: [PATCH 076/819] CLOUDSTACK-6992 Test data was passed to test methods.Made code changes to get test data and pass it to test methods. Also reading portable ip config values was not proper in getPortableIpRangeServices method. So corrected it CLOUDSTACK-6992: Incorporated review comments for patch request 23009 CLOUDSTACK-6992: Added portable ip range to services class Signed-off-by: sanjeevneelarapu Signed-off-by: SrikanteswaraRao Talluri --- .../integration/component/test_portable_ip.py | 30 ++++++++++++------- tools/marvin/marvin/lib/common.py | 20 ++++++------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/test/integration/component/test_portable_ip.py b/test/integration/component/test_portable_ip.py index b9c9059d2b..ce27dd8270 100644 --- a/test/integration/component/test_portable_ip.py +++ b/test/integration/component/test_portable_ip.py @@ -105,7 +105,7 @@ def __init__(self): "privateport": 22, "publicport": 22, "protocol": "TCP", - "cidr" : '0.0.0.0/0', + "cidr": '0.0.0.0/0', }, "small": # Create a small virtual machine instance with disk offering @@ -143,6 +143,14 @@ def __init__(self): "publicport": 22, "protocol": 'TCP', }, + "portableIpRange": + { + "gateway": "10.223.252.195", + "netmask": "255.255.255.192", + "startip": "10.223.252.196", + "endip": "10.223.252.197", + "vlan": "1001", + }, "ostype": 'CentOS 5.3 (64-bit)' } @@ -155,8 +163,8 @@ class TestCreatePortablePublicIpRanges(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestCreatePortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -287,8 +295,8 @@ class TestDeletePortablePublicIpRanges(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestDeletePortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -445,8 +453,8 @@ class TestListPortablePublicIpRanges(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestListPortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -537,7 +545,7 @@ def test_list_portable_ip_range(self): "Listed netmask not matching with the netmask of created public ip range") return - @attr(tags=["advanced","swamy", "selfservice"]) + @attr(tags=["advanced", "swamy", "selfservice"]) def test_list_portable_ip_range_non_root_admin(self): """Test list portable ip ranges with non admin root account """ @@ -571,8 +579,8 @@ class TestAssociatePublicIp(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestAssociatePublicIp, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -887,8 +895,8 @@ class TestDisassociatePublicIp(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestDisassociatePublicIp, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -1126,8 +1134,8 @@ class TestDeleteAccount(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestDeleteAccount, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -1328,8 +1336,8 @@ class TestPortableIpTransferAcrossNetworks(cloudstackTestCase): def setUpClass(cls): cls.testClient = super(TestPortableIpTransferAcrossNetworks, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() - cls.services = Services().services + cls.config = cls.services # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -1447,7 +1455,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags=["advanced","swamy", "selfservice"]) + @attr(tags=["advanced", "swamy", "selfservice"]) def test_list_portable_ip_range_non_root_admin(self): """Test list portable ip ranges with non admin root account """ @@ -1514,7 +1522,7 @@ def test_list_portable_ip_range_non_root_admin(self): "List Public IP should return a valid static NAT info that was created on portable ip" ) self.assertTrue( - static_nat_list[0].ipaddress == portableip.ipaddress.ipaddress and static_nat_list[0].virtualmachineid==self.virtual_machine2.id, + static_nat_list[0].ipaddress == portableip.ipaddress.ipaddress and static_nat_list[0].virtualmachineid == self.virtual_machine2.id, "There is some issue in transferring portable ip {} across networks".format(portableip.ipaddress.ipaddress) ) try: diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py index 29677d3a0c..bc6b9c775f 100644 --- a/tools/marvin/marvin/lib/common.py +++ b/tools/marvin/marvin/lib/common.py @@ -1172,28 +1172,28 @@ def getPortableIpRangeServices(config): services = {} attributeError = False - if config.portableIpRange.startip: - services["startip"] = config.portableIpRange.startip + if config["portableIpRange"]["startip"]: + services["startip"] = config["portableIpRange"]["startip"] else: attributeError = True - if config.portableIpRange.endip: - services["endip"] = config.portableIpRange.endip + if config["portableIpRange"]["endip"]: + services["endip"] = config["portableIpRange"]["endip"] else: attributeError = True - if config.portableIpRange.netmask: - services["netmask"] = config.portableIpRange.netmask + if config["portableIpRange"]["netmask"]: + services["netmask"] = config["portableIpRange"]["netmask"] else: attributeError = True - if config.portableIpRange.gateway: - services["gateway"] = config.portableIpRange.gateway + if config["portableIpRange"]["gateway"]: + services["gateway"] = config["portableIpRange"]["gateway"] else: attributeError = True - if config.portableIpRange.vlan: - services["vlan"] = config.portableIpRange.vlan + if config["portableIpRange"]["vlan"]: + services["vlan"] = config["portableIpRange"]["vlan"] if attributeError: services = FAILED From 5ccd904e83f6e1acdbcfb9e246fc9e357536e8f9 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 16 Jul 2014 10:59:58 +0200 Subject: [PATCH 077/819] simple first test for backward compatibility testing in rvr4vpc work --- .../VirtualNetworkApplianceManagerTest.java | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java new file mode 100644 index 0000000000..612b4db123 --- /dev/null +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java @@ -0,0 +1,184 @@ +package com.cloud.network.router; + +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.when; + +import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.MonitoringServiceDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.OpRouterMonitorServiceDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.dao.UserIpv6AddressDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.dao.VpnUserDao; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.UserDao; +import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.user.dao.UserStatsLogDao; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicIpAliasDao; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmDetailsDao; +import com.cloud.vm.dao.VMInstanceDao; + +@RunWith(MockitoJUnitRunner.class) +public class VirtualNetworkApplianceManagerTest { + @Mock + private ClusterDao _clusterDao; + + @Mock + private ConfigurationDao _configDao; + + @Mock + private DataCenterDao _dcDao; + + @Mock + private GuestOSDao _guestOSDao; + + @Mock + private HostDao _hostDao; + + @Mock + private IPAddressDao _ipAddressDao; + + @Mock + private UserIpv6AddressDao _ipv6Dao; + + @Mock + private LoadBalancerDao _loadBalancerDao; + + @Mock + private LoadBalancerVMMapDao _loadBalancerVMMapDao; + + @Mock + private MonitoringServiceDao _monitorServiceDao; + + @Mock + private ManagementServerHostDao _msHostDao; + + @Mock + private NetworkDao _networkDao; + + @Mock + private NetworkOfferingDao _networkOfferingDao; + + @Mock + private NicDao _nicDao; + + @Mock + private NicIpAliasDao _nicIpAliasDao; + + @Mock + private OpRouterMonitorServiceDao _opRouterMonitorServiceDao; + + @Mock + private PortForwardingRulesDao _pfRulesDao; + + @Mock + private PhysicalNetworkServiceProviderDao _physicalProviderDao; + + @Mock + private HostPodDao _podDao; + + @Mock + private DomainRouterDao _routerDao; + + @Mock + private FirewallRulesDao _rulesDao; + + @Mock + private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; + + @Mock + private Site2SiteVpnConnectionDao _s2sVpnConnectionDao; + + @Mock + private Site2SiteVpnGatewayDao _s2sVpnGatewayDao; + + @Mock + private ServiceOfferingDao _serviceOfferingDao; + + @Mock + private VMTemplateDao _templateDao; + + @Mock + private UserDao _userDao; + + @Mock + private UserStatisticsDao _userStatsDao; + + @Mock + private UserStatsLogDao _userStatsLogDao; + + @Mock + private UserVmDao _userVmDao; + + @Mock + private VlanDao _vlanDao; + + @Mock + private VMInstanceDao _vmDao; + + @Mock + private UserVmDetailsDao _vmDetailsDao; + + @Mock + private VolumeDao _volumeDao; + + @Mock + private RemoteAccessVpnDao _vpnDao; + + @Mock + private VpnUserDao _vpnUsersDao; + + @Mock + private VirtualRouterProviderDao _vrProviderDao; + + @Mock private AccountManager _accountMgr; + + @Mock private VirtualMachineManager _itMgr; + + @InjectMocks + private VirtualNetworkApplianceManagerImpl virtualNetworkApplianceManagerImpl; + + @Test + public void testDestroyRouter() throws Exception { + VirtualRouter r = new DomainRouterVO(1L, 0L, 0L, "router", 0L, HypervisorType.Any, 0L, 0L, + 1L, false, 0, false, RedundantState.UNKNOWN, false, false, null); + when(_routerDao.findById(1L)).thenReturn((DomainRouterVO)r); + VirtualRouter vr = virtualNetworkApplianceManagerImpl.destroyRouter(1L, new AccountVO(1L), 0L); + assert vr != null; + } + +} From 56e37243b83371c46dddeee18e48d82e16f87d9e Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Tue, 15 Jul 2014 12:55:48 +0530 Subject: [PATCH 078/819] CLOUDSTACK-7114. [EC2 QueryAPI] Inconsistency in mapping the "Allocated" state of a Volume to "Available". --- awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 4879a4b6d4..41fe56e330 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -1231,7 +1231,9 @@ public EC2Volume createVolume(EC2CreateVolume request) { resp.setInstanceId(vol.getVirtualMachineId()); resp.setSize(vol.getSize()); resp.setSnapshotId(vol.getSnapshotId()); - resp.setState(vol.getState()); + if (vol.getState() != null) { + resp.setState(mapToAmazonVolState(vol.getState())); + } resp.setType(vol.getVolumeType()); resp.setVMState(vol.getVirtualMachineState()); resp.setAttachmentState("detached"); From dbc7d803291547f50d00dde0c37490c2005b7fdc Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 16 Jul 2014 12:40:50 +0200 Subject: [PATCH 079/819] Aggregate command cleanup is not required for the virtual router as we already cleanup in the finish. And consequently dies if somebody tries to test with assertions enabled. --- .../VirtualRoutingResource.java | 13 +- .../network/element/VirtualRouterElement.java | 184 +++++++++--------- .../VirtualNetworkApplianceManager.java | 11 +- .../VirtualNetworkApplianceManagerImpl.java | 4 - ...MockVpcVirtualNetworkApplianceManager.java | 24 ++- 5 files changed, 106 insertions(+), 130 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 1fa5bf20d2..00501e3847 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -361,7 +361,7 @@ private Answer execute(AggregationControlCommand cmd) { Queue queue = new LinkedBlockingQueue<>(); _vrAggregateCommandsSet.put(routerName, queue); - return new Answer(cmd); + return new Answer(cmd, true, "Command aggregation started"); } else if (action == Action.Finish) { Queue queue = _vrAggregateCommandsSet.get(routerName); int answerCounts = 0; @@ -402,20 +402,11 @@ private Answer execute(AggregationControlCommand cmd) { return new Answer(cmd, false, result.getDetails()); } - return new Answer(cmd); + return new Answer(cmd, true, "Command aggregation finished"); } finally { queue.clear(); _vrAggregateCommandsSet.remove(routerName); } - } else if (action == Action.Cleanup) { - assert (_vrAggregateCommandsSet.containsKey(routerName)); - Queue queue = _vrAggregateCommandsSet.get(routerName); - if (queue != null) { - queue.clear(); - } - _vrAggregateCommandsSet.remove(routerName); - - return new Answer(cmd); } return new Answer(cmd, false, "Fail to recongize aggregation action " + action.toString()); } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 3b3cacd094..3fcf5783a5 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -16,6 +16,26 @@ // 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 javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import com.google.gson.Gson; + +import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd; +import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd; +import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd; +import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd; +import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; + import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; @@ -81,32 +101,16 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.UserVmDao; -import com.google.gson.Gson; -import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd; -import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd; -import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd; -import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd; -import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.log4j.Logger; - -import javax.ejb.Local; -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; @Local(value = {NetworkElement.class, FirewallServiceProvider.class, - DhcpServiceProvider.class, UserDataServiceProvider.class, - StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, - PortForwardingServiceProvider.class, IpDeployer.class, - RemoteAccessVPNServiceProvider.class, NetworkMigrationResponder.class}) + DhcpServiceProvider.class, UserDataServiceProvider.class, + StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, + PortForwardingServiceProvider.class, IpDeployer.class, + RemoteAccessVPNServiceProvider.class, NetworkMigrationResponder.class}) public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, - UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, - LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, - NetworkMigrationResponder, AggregatedCommandExecutor { +UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, +LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, +NetworkMigrationResponder, AggregatedCommandExecutor { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); public static final AutoScaleCounterType AutoScaleCounterCpu = new AutoScaleCounterType("cpu"); public static final AutoScaleCounterType AutoScaleCounterMemory = new AutoScaleCounterType("memory"); @@ -179,7 +183,7 @@ protected boolean canHandle(Network network, Service service) { @Override public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, - ConcurrentOperationException, InsufficientCapacityException { + ConcurrentOperationException, InsufficientCapacityException { if (offering.isSystemOnly()) { return false; @@ -205,7 +209,7 @@ public boolean implement(Network network, NetworkOffering offering, DeployDestin @Override public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) { return false; } @@ -225,8 +229,8 @@ public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; List routers = - _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters(), - offering.getRedundantRouter()); + _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters(), + offering.getRedundantRouter()); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } @@ -239,14 +243,14 @@ public boolean applyFWRules(Network config, List rules) List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + - config.getId()); + config.getId()); return true; } if (rules != null && rules.size() == 1) { // for VR no need to add default egress rule to DENY traffic if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System && - !_networkMgr.getNetworkEgressDefaultPolicy(config.getId())) + !_networkMgr.getNetworkEgressDefaultPolicy(config.getId())) return true; } @@ -274,7 +278,7 @@ private static boolean containsOnlyNumbers(String str, String endChar) { boolean matchedEndChar = false; if (str.length() < 2) return false; // atleast one numeric and one char. example: - // 3h + // 3h char strEnd = str.toCharArray()[str.length() - 1]; for (char c : endChar.toCharArray()) { if (strEnd == c) { @@ -287,7 +291,7 @@ private static boolean containsOnlyNumbers(String str, String endChar) { return false; } try { - int i = Integer.parseInt(number); + Integer.parseInt(number); } catch (NumberFormatException e) { return false; } @@ -323,21 +327,14 @@ public static boolean validateHAProxyLBRule(LoadBalancingRule rule) { } } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { - /* - * FORMAT : appsession len timeout - * [request-learn] [prefix] [mode - * ] - */ - /* example: appsession JSESSIONID len 52 timeout 3h */ - String cookieName = null; // optional String length = null; // optional String holdTime = null; // optional for (Pair paramKV : paramsList) { String key = paramKV.first(); String value = paramKV.second(); - if ("cookie-name".equalsIgnoreCase(key)) - cookieName = value; + if ("cookie-name".equalsIgnoreCase(key)) { + } if ("length".equalsIgnoreCase(key)) length = value; if ("holdtime".equalsIgnoreCase(key)) @@ -403,7 +400,7 @@ public String[] applyVpnUsers(RemoteAccessVpn vpn, List users List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + " doesn't exist in the network " + - network.getId()); + network.getId()); return null; } return _routerMgr.applyVpnUsers(network, users, routers); @@ -466,7 +463,7 @@ public boolean applyIps(Network network, List ipAddre List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + "router doesn't exist in the network " + - network.getId()); + network.getId()); return true; } @@ -493,61 +490,61 @@ public static String getHAProxyStickinessCapability() { method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method."); method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false); method.addParam("mode", false, "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created" - + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); + + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); method.addParam("nocache", false, "This option is recommended in conjunction with the insert mode when there is a cache between the client" - + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " - + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" - + " for instance, then all customers will then fetch the page from an outer cache and will all share the " - + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + "insert and postonly options. ", true); + + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " + + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" + + " for instance, then all customers will then fetch the page from an outer cache and will all share the " + + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + "insert and postonly options. ", true); method.addParam("indirect", false, "When this option is specified in insert mode, cookies will only be added when the server was not reached" - + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," - + " or after a redispatch, then the cookie will be inserted. If the client has all the required information" - + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " - + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " - + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true); + + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," + + " or after a redispatch, then the cookie will be inserted. If the client has all the required information" + + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " + + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " + + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true); method.addParam("postonly", false, "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" - + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " - + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" - + " first POST which generally is a login request, this is a very efficient method to optimize caching " - + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true); + + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " + + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" + + " first POST which generally is a login request, this is a very efficient method to optimize caching " + + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true); method.addParam("domain", false, "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" - + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " - + "ending with that name. It is also possible to specify several domain names by invoking this option multiple" - + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " - + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false); + + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " + + "ending with that name. It is also possible to specify several domain names by invoking this option multiple" + + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " + + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false); methodList.add(method); method = - new LbStickinessMethod(StickinessMethodType.AppCookieBased, - "This is App session based sticky method. Define session stickiness on an existing application cookie. " - + "It can be used only for a specific http traffic"); + new LbStickinessMethod(StickinessMethodType.AppCookieBased, + "This is App session based sticky method. Define session stickiness on an existing application cookie. " + + "It can be used only for a specific http traffic"); method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " - + "have to learn for each new session. Default value: Auto geneared based on ip", false); + + "have to learn for each new session. Default value: Auto geneared based on ip", false); method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + "each cookie value. Default value:52", false); method.addParam("holdtime", false, "This is the time after which the cookie will be removed from memory if unused. The value should be in " - + "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," - + " cannot use th combinations like 20h30m. Default value:3h ", false); + + "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," + + " cannot use th combinations like 20h30m. Default value:3h ", false); method.addParam( - "request-learn", - false, - "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability", - true); + "request-learn", + false, + "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability", + true); method.addParam( - "prefix", - false, - "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). " - + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", - true); + "prefix", + false, + "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). " + + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", + true); method.addParam("mode", false, "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " - + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " - + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" - + " In this mode, the parser will look for the appsession in the query string.", false); + + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " + + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" + + " In this mode, the parser will look for the appsession in the query string.", false); methodList.add(method); method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + "it can be used for any type of protocol."); method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + " or 400g. Default value:200k", false); method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." - + " example: expire=30m 20s 50h 4d. Default value:3h", false); + + " example: expire=30m 20s 50h 4d. Default value:3h", false); methodList.add(method); Gson gson = new Gson(); @@ -622,7 +619,7 @@ public boolean applyStaticNats(Network config, List rules) List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + "router doesn't exist in the network " + - config.getId()); + config.getId()); return true; } @@ -749,7 +746,7 @@ public OvsProvider configure(ConfigureOvsElementCmd cmd) { OvsProviderVO element = _ovsProviderDao.findById(cmd.getId()); if (element == null) { s_logger.debug("Can't find Ovs element with network service provider id " - + cmd.getId()); + + cmd.getId()); return null; } @@ -763,7 +760,7 @@ public OvsProvider configure(ConfigureOvsElementCmd cmd) { public VirtualRouterProvider addElement(Long nspId, Type providerType) { if (!(providerType == Type.VirtualRouter || providerType == Type.VPCVirtualRouter)) { throw new InvalidParameterValueException("Element " + getName() + " supports only providerTypes: " + Type.VirtualRouter.toString() + " and " + - Type.VPCVirtualRouter); + Type.VPCVirtualRouter); } VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType); if (element != null) { @@ -781,7 +778,7 @@ public boolean applyPFRules(Network network, List rules) thr List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + - network.getId()); + network.getId()); return true; } @@ -806,7 +803,7 @@ public boolean isReady(PhysicalNetworkServiceProvider provider) { @Override public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), getVirtualRouterProvider()); if (element == null) { return true; @@ -844,13 +841,13 @@ public VirtualRouterProvider getCreatedElement(long id) { @Override public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { return true; } @Override public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.Dhcp)) { if (vm.getType() != VirtualMachine.Type.User) { return false; @@ -887,7 +884,7 @@ public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavai @Override public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.Dhcp)) { if (vm.getType() != VirtualMachine.Type.User) { return false; @@ -909,7 +906,7 @@ public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfi @Override public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.UserData)) { if (vm.getType() != VirtualMachine.Type.User) { return false; @@ -940,7 +937,7 @@ protected List getRouters(Network network, DeployDestination des publicNetwork = true; } boolean isPodBased = - (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && + (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && network.getTrafficType() == TrafficType.Guest; List routers; @@ -1118,12 +1115,7 @@ public boolean completeAggregatedExecution(Network network, DeployDestination de @Override public boolean cleanupAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException { - List routers = getRouters(network, dest); - - if ((routers == null) || (routers.size() == 0)) { - throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); - } - - return _routerMgr.cleanupAggregatedExecution(network, routers); + // The VR code already cleansup in the Finish routine using finally, lets not waste another command + return true; } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 58ffb2f895..85ce8b9dcc 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -16,6 +16,11 @@ // under the License. package com.cloud.network.router; +import java.util.List; +import java.util.Map; + +import org.apache.cloudstack.framework.config.ConfigKey; + import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; @@ -35,10 +40,6 @@ import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.framework.config.ConfigKey; - -import java.util.List; -import java.util.Map; /** * NetworkManager manages the network for the different end users. @@ -137,6 +138,4 @@ boolean configDhcpForSubnet(Network network, NicProfile nic, VirtualMachineProfi public boolean prepareAggregatedExecution(Network network, List routers) throws AgentUnavailableException; public boolean completeAggregatedExecution(Network network, List routers) throws AgentUnavailableException; - - public boolean cleanupAggregatedExecution(Network network, List routers) throws AgentUnavailableException; } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d8e3761464..33d7cd7396 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -4464,8 +4464,4 @@ public boolean completeAggregatedExecution(Network network, List return aggregationExecution(Action.Finish, network, routers); } - @Override - public boolean cleanupAggregatedExecution(Network network, List routers) throws AgentUnavailableException { - return aggregationExecution(Action.Cleanup, network, routers); - } } diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java index cbed4cab41..7a98a6d2a2 100644 --- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java +++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java @@ -17,6 +17,17 @@ package com.cloud.vpc; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.springframework.stereotype.Component; + +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; + import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; @@ -44,14 +55,6 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; -import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; -import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; -import java.util.List; -import java.util.Map; @Component @Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class}) @@ -428,11 +431,6 @@ public boolean completeAggregatedExecution(Network network, List return true; //To change body of implemented methods use File | Settings | File Templates. } - @Override - public boolean cleanupAggregatedExecution(Network network, List routers) throws AgentUnavailableException { - return true; //To change body of implemented methods use File | Settings | File Templates. - } - @Override public boolean startRemoteAccessVpn(RemoteAccessVpn vpn, VirtualRouter router) throws ResourceUnavailableException { // TODO Auto-generated method stub From e78bb1d22571ecfb115d654d08d782af74e98e75 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 16 Jul 2014 16:22:31 +0200 Subject: [PATCH 080/819] Switch the catch to Throwable. Uncaught exceptions in a scheduled threadpool executor will not report or log uncaught exceptions but will kill the thread causing unexplained timeouts in CS. --- .../com/cloud/agent/manager/DirectAgentAttache.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java index 7ca6929686..fa89841c74 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java +++ b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; + import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.agent.api.Answer; @@ -298,9 +299,10 @@ protected void runInContext() { } else { answer = new Answer(cmds[i], false, "Agent is disconnected"); } - } catch (Exception e) { - s_logger.warn(log(seq, "Exception Caught while executing command"), e); - answer = new Answer(cmds[i], false, e.toString()); + } catch (Throwable t) { + // Catch Throwable as all exceptions will otherwise be eaten by the executor framework + s_logger.warn(log(seq, "Throwable caught while executing command"), t); + answer = new Answer(cmds[i], false, t.toString()); } answers.add(answer); if (!answer.getResult() && stopOnError) { @@ -317,8 +319,9 @@ protected void runInContext() { } processAnswers(seq, resp); - } catch (Exception e) { - s_logger.warn(log(seq, "Exception caught "), e); + } catch (Throwable t) { + // This is pretty serious as processAnswers might not be called and the calling process is stuck waiting for the full timeout + s_logger.error(log(seq, "Throwable caught in runInContext, this will cause the management to become unpredictable"), t); } finally { _outstandingTaskCount.decrementAndGet(); scheduleFromQueue(); From 799258662c536384c222991cd712d9487c767b13 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 16 Jul 2014 16:38:55 +0200 Subject: [PATCH 081/819] rvr4vpc simple test for deployRouter --- ...rtualNetworkApplianceManagerImplTest.java} | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) rename server/test/com/cloud/network/router/{VirtualNetworkApplianceManagerTest.java => VirtualNetworkApplianceManagerImplTest.java} (76%) diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java similarity index 76% rename from server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java rename to server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 612b4db123..6ab6eea819 100644 --- a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerTest.java +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -1,5 +1,11 @@ package com.cloud.network.router; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.junit.Test; import org.junit.runner.RunWith; @@ -10,12 +16,20 @@ import static org.mockito.Mockito.when; import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; +import com.cloud.network.VirtualRouterProvider; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -31,9 +45,11 @@ import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.dao.VpnUserDao; +import com.cloud.network.element.VirtualRouterProviderVO; import com.cloud.network.router.VirtualRouter.RedundantState; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; @@ -44,7 +60,9 @@ import com.cloud.user.dao.UserStatisticsDao; import com.cloud.user.dao.UserStatsLogDao; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineProfile.Param; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicIpAliasDao; @@ -53,7 +71,7 @@ import com.cloud.vm.dao.VMInstanceDao; @RunWith(MockitoJUnitRunner.class) -public class VirtualNetworkApplianceManagerTest { +public class VirtualNetworkApplianceManagerImplTest { @Mock private ClusterDao _clusterDao; @@ -169,6 +187,8 @@ public class VirtualNetworkApplianceManagerTest { @Mock private VirtualMachineManager _itMgr; + @Mock private ResourceManager _resourceMgr; + @InjectMocks private VirtualNetworkApplianceManagerImpl virtualNetworkApplianceManagerImpl; @@ -181,4 +201,16 @@ public void testDestroyRouter() throws Exception { assert vr != null; } + @Test + public void testDeployRouterNotRedundant() throws Exception { + DataCenter dc = new DataCenterVO(1L, "name", "description", "dns", null, null, null, "cidr", "domain", null, + NetworkType.Basic, "zoneToken", "domainSuffix"); + when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L); + when(_resourceMgr.getDefaultHypervisor(1L)).thenReturn(HypervisorType.Any); + DeploymentPlan plan = new DataCenterDeployment(1L); + VirtualRouter vr = virtualNetworkApplianceManagerImpl.deployRouter(new AccountVO(1L), new DeployDestination(dc,null,null,null), plan, null, false, + new VirtualRouterProviderVO(), 0L, null, new LinkedHashMap> (), true /* start the router */, + null); + assert vr != null; + } } From cc37eb50cfeadeec77cf5ff435a64144569483c6 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 16 Jul 2014 16:52:02 +0200 Subject: [PATCH 082/819] checkstyle: unused imports --- .../router/VirtualNetworkApplianceManagerImplTest.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 6ab6eea819..0b98813090 100644 --- a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -1,10 +1,9 @@ package com.cloud.network.router; +import static org.mockito.Mockito.when; + import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; - -import javax.inject.Inject; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.junit.Test; @@ -13,8 +12,6 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import static org.mockito.Mockito.when; - import com.cloud.cluster.dao.ManagementServerHostDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -29,7 +26,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; -import com.cloud.network.VirtualRouterProvider; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -62,7 +58,6 @@ import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineProfile.Param; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicIpAliasDao; From b0d7e10aef985021829ee9f50af3d170982c9298 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 16 Jul 2014 16:56:11 +0200 Subject: [PATCH 083/819] Prevent a NPE when shutting down a network that did not have a vlan assigned yet. --- .../cloud/network/guru/GuestNetworkGuru.java | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 28df46b716..fb11473935 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -109,13 +109,13 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur Random _rand = new Random(System.currentTimeMillis()); static final ConfigKey UseSystemGuestVlans = - new ConfigKey( - "Advanced", - Boolean.class, - "use.system.guest.vlans", - "true", - "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool", - false, ConfigKey.Scope.Account); + new ConfigKey( + "Advanced", + Boolean.class, + "use.system.guest.vlans", + "true", + "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool", + false, ConfigKey.Scope.Account); private static final TrafficType[] TrafficTypes = {TrafficType.Guest}; @@ -184,8 +184,8 @@ public Network design(NetworkOffering offering, DeploymentPlan plan, Network use } NetworkVO network = - new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(), - plan.getPhysicalNetworkId()); + new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(), + plan.getPhysicalNetworkId()); if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { throw new InvalidParameterValueException("cidr and gateway must be specified together."); @@ -277,16 +277,16 @@ public int getGloballyConfiguredCidrSize() { } protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) - throws InsufficientVirtualNetworkCapacityException { + throws InsufficientVirtualNetworkCapacityException { if (network.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, UseSystemGuestVlans.valueIn(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, - dcId); + dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, - EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0); + EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } @@ -294,7 +294,7 @@ protected void allocateVnet(Network network, NetworkVO implemented, long dcId, l @Override public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapacityException { + throws InsufficientVirtualNetworkCapacityException { assert (network.getState() == State.Implementing) : "Why are we implementing " + network; long dcId = dest.getDataCenter().getId(); @@ -308,8 +308,8 @@ public Network implement(Network network, NetworkOffering offering, DeployDestin } NetworkVO implemented = - new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, - network.getDataCenterId(), physicalNetworkId); + new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, + network.getDataCenterId(), physicalNetworkId); allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId()); @@ -325,7 +325,7 @@ public Network implement(Network network, NetworkOffering offering, DeployDestin @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, - InsufficientAddressCapacityException { + InsufficientAddressCapacityException { assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling" + " me when the traffic type is : " + network.getTrafficType(); @@ -364,7 +364,7 @@ public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfil guestIp = _ipAddrMgr.acquireGuestIpAddress(network, nic.getRequestedIpv4()); if (guestIp == null) { throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class, - dc.getId()); + dc.getId()); } } @@ -400,7 +400,7 @@ public void updateNicProfile(NicProfile profile, Network network) { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? "; nic.setBroadcastUri(network.getBroadcastUri()); @@ -416,15 +416,18 @@ public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservat @Override public void shutdown(NetworkProfile profile, NetworkOffering offering) { + if (profile.getBroadcastUri() == null) { + return; // Nothing to do here if the uri is null already + } if ((profile.getBroadcastDomainType() == BroadcastDomainType.Vlan || profile.getBroadcastDomainType() == BroadcastDomainType.Vxlan) && !offering.getSpecifyVlan()) { s_logger.debug("Releasing vnet for the network id=" + profile.getId()); - _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(), - profile.getAccountId(), profile.getReservationId()); - ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, - EventTypes.EVENT_ZONE_VLAN_RELEASE, - "Released Zone Vnet: " + BroadcastDomainType.getValue(profile.getBroadcastUri()) + " for Network: " + profile.getId(), 0); + _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(), + profile.getReservationId()); + ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, + "Released Zone Vnet: " + BroadcastDomainType.getValue(profile.getBroadcastUri()) + " for Network: " + profile.getId(), 0); } + profile.setBroadcastUri(null); } From 5b37c65577888874cb7cbfef58b5f0c97f49eeef Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 16 Jul 2014 17:26:29 +0200 Subject: [PATCH 084/819] oversimplified test fixed --- .../router/VirtualNetworkApplianceManagerImplTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 0b98813090..118effdba3 100644 --- a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -1,6 +1,8 @@ package com.cloud.network.router; import static org.mockito.Mockito.when; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import java.util.LinkedHashMap; import java.util.List; @@ -193,7 +195,7 @@ public void testDestroyRouter() throws Exception { 1L, false, 0, false, RedundantState.UNKNOWN, false, false, null); when(_routerDao.findById(1L)).thenReturn((DomainRouterVO)r); VirtualRouter vr = virtualNetworkApplianceManagerImpl.destroyRouter(1L, new AccountVO(1L), 0L); - assert vr != null; + assertNotEquals(vr, null); } @Test @@ -206,6 +208,7 @@ public void testDeployRouterNotRedundant() throws Exception { VirtualRouter vr = virtualNetworkApplianceManagerImpl.deployRouter(new AccountVO(1L), new DeployDestination(dc,null,null,null), plan, null, false, new VirtualRouterProviderVO(), 0L, null, new LinkedHashMap> (), true /* start the router */, null); - assert vr != null; + // TODO: more elaborate mocking needed to have a vr returned + assertEquals(vr, null); } } From 2f2efb095454025b51dafd08dcbb31e4e83d3cdb Mon Sep 17 00:00:00 2001 From: Prachi Damle Date: Mon, 14 Jul 2014 16:29:11 -0700 Subject: [PATCH 085/819] CS-19828: EC2 API tool errors while parsing response for detachVolume, describeAddress and revokeSecurityGroupIngress Changes: - Set the mandatory response properties in case of DetachVolume and DescribeAddress API responses - Use the correct CS API responsename for revokesecuritygroupingress Conflicts: awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java --- awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java | 5 ++--- awsapi/src/com/cloud/stack/models/ApiConstants.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 41fe56e330..c8b0099f7a 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -30,15 +30,12 @@ import java.util.Map; import java.util.Properties; import java.util.UUID; - import javax.inject.Inject; import javax.naming.ConfigurationException; import javax.xml.parsers.ParserConfigurationException; - import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.xml.sax.SAXException; - import com.cloud.bridge.model.CloudStackServiceOfferingVO; import com.cloud.bridge.persist.dao.CloudStackAccountDao; import com.cloud.bridge.persist.dao.CloudStackSvcOfferingDao; @@ -75,6 +72,7 @@ import com.cloud.stack.models.CloudStackZone; import com.cloud.utils.component.ManagerBase; + /** * EC2Engine processes the ec2 commands and calls their cloudstack analogs * @@ -1175,6 +1173,7 @@ public EC2Volume detachVolume(EC2Volume request) { resp.setState(vol.getState()); resp.setType(vol.getVolumeType()); resp.setVMState(vol.getVirtualMachineState()); + resp.setAttachmentState("detached"); resp.setZoneName(vol.getZoneName()); } } catch (Exception e) { diff --git a/awsapi/src/com/cloud/stack/models/ApiConstants.java b/awsapi/src/com/cloud/stack/models/ApiConstants.java index 8eeebb025b..e54f23895c 100644 --- a/awsapi/src/com/cloud/stack/models/ApiConstants.java +++ b/awsapi/src/com/cloud/stack/models/ApiConstants.java @@ -394,7 +394,7 @@ public class ApiConstants { public static final String RESTART_NETWORK = "restartNetwork"; public static final String RESTART_NETWORK_RESPONSE = "restartnetworkresponse"; public static final String REVOKE_SECURITY_GROUP_INGRESS = "revokeSecurityGroupIngress"; - public static final String REVOKE_SECURITY_GROUP_INGRESS_RESPONSE = "revokesecuritygroupingress"; + public static final String REVOKE_SECURITY_GROUP_INGRESS_RESPONSE = "revokesecuritygroupingressresponse"; public static final String ROOT_DEVICE_ID = "rootdeviceid"; public static final String ROOT_DEVICE_TYPE = "rootdevicetype"; public static final String RULE_ID = "ruleid"; From 771b53b3421fcde27e882a022e4f1b43146ca0e4 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 16 Jul 2014 16:30:15 -0700 Subject: [PATCH 086/819] CLOUDSTACK-4725: if storage pool has different path, but the uuid is the same, then treat them as the same storage pool --- .../storage/datastore/db/PrimaryDataStoreDaoImpl.java | 4 +++- server/src/com/cloud/storage/StorageManagerImpl.java | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index cb8ec31fdb..0c372a5b99 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -184,7 +184,9 @@ public List listByStatusInZone(long dcId, StoragePoolStatus statu public StoragePoolVO findPoolByHostPath(long datacenterId, Long podId, String host, String path, String uuid) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("hostAddress", host); - sc.setParameters("path", path); + if (path != null) { + sc.setParameters("path", path); + } sc.setParameters("datacenterId", datacenterId); sc.setParameters("podId", podId); sc.setParameters("uuid", uuid); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 06f271852c..2246387a5e 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -554,6 +554,15 @@ public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws Con pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), "", pInfo.getUuid()); } } + if (pool == null) { + //the path can be different, but if they have the same uuid, assume they are the same storage + pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), null, + pInfo.getUuid()); + if (pool != null) { + s_logger.debug("Found a storage pool: " + pInfo.getUuid() + ", but with different hostpath " + pInfo.getHostPath() + ", still treat it as the same pool"); + } + } + DataStoreProvider provider = dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider(); DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); if (pool == null) { From 27bc791746d6167fe2b268c2efe4fa9ee16fa580 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 17 Jul 2014 09:20:58 +0200 Subject: [PATCH 087/819] rats --- .../VirtualNetworkApplianceManagerImplTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 118effdba3..8c40178d7a 100644 --- a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -1,3 +1,19 @@ +// 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.router; import static org.mockito.Mockito.when; From 6f9b3cc9d13bd1bc002ce0afad3ed416b590f882 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 16 Jul 2014 20:30:12 -0400 Subject: [PATCH 088/819] CLOUDSTACK-7108: Reading provisioningtype for disk offering in base.py --- tools/marvin/marvin/lib/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index fe257f009d..e9d5bb4b5b 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -1954,6 +1954,9 @@ def create(cls, apiclient, services, custom=False, domainid=None): if "tags" in services: cmd.tags = services["tags"] + if "provisioningtype" in services: + cmd.provisioningtype = services["provisioningtype"] + return DiskOffering(apiclient.createDiskOffering(cmd).__dict__) def delete(self, apiclient): From 34bed5fa56a43c5f2ce776270f3915dd96feed6b Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 17 Jul 2014 10:09:45 +0200 Subject: [PATCH 089/819] I wonder if people are really interested in the location of my home folder --- build/replace.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/replace.properties b/build/replace.properties index 265f335872..0e24f68421 100644 --- a/build/replace.properties +++ b/build/replace.properties @@ -27,4 +27,4 @@ MSMNTDIR=/mnt COMPONENTS-SPEC=components.xml AWSAPILOG=awsapi.log REMOTEHOST=localhost -COMMONLIBDIR=C:\Users\htrippaers\eclipse_workspace\cloudstack\client\target\cloud-client-ui-4.2.0-SNAPSHOT\WEB-INF\classes +COMMONLIBDIR=client/target/cloud-client-ui-4.5.0-SNAPSHOT/WEB-INF/lib/ From d3e7b43ee9398690f094ae2eb2a1a1957f7f3b07 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Thu, 17 Jul 2014 13:04:58 +0530 Subject: [PATCH 090/819] CLOUDSTACK-7119. [VMware] Don't allow VM reset when VM has snapshots. --- server/src/com/cloud/vm/UserVmManagerImpl.java | 6 ++++++ server/test/com/cloud/vm/UserVmManagerTest.java | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index dac4acf182..d0bc1867b8 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -4627,6 +4627,12 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) templateId = vm.getIsoId(); } + // If target VM has associated VM snapshots then don't allow restore of VM + List vmSnapshots = _vmSnapshotDao.findByVm(vmId); + if (vmSnapshots.size() > 0 && vm.getHypervisorType() == HypervisorType.VMware) { + throw new InvalidParameterValueException("Unable to restore VM, please specify a VM that does not have VM snapshots"); + } + VMTemplateVO template = null; //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly if (newTemplateId != null) { diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 3188d04792..aed468d3b8 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -86,6 +87,8 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.snapshot.VMSnapshotVO; +import com.cloud.vm.snapshot.dao.VMSnapshotDao; public class UserVmManagerTest { @@ -149,6 +152,8 @@ public class UserVmManagerTest { PrimaryDataStoreDao _storagePoolDao; @Mock UsageEventDao _usageEventDao; + @Mock + VMSnapshotDao _vmSnapshotDao; @Before public void setup() { @@ -172,6 +177,7 @@ public void setup() { _userVmMgr._scaleRetry = 2; _userVmMgr._entityMgr = _entityMgr; _userVmMgr._storagePoolDao = _storagePoolDao; + _userVmMgr._vmSnapshotDao = _vmSnapshotDao; doReturn(3L).when(_account).getId(); doReturn(8L).when(_vmMock).getAccountId(); @@ -181,6 +187,9 @@ public void setup() { when(_vmMock.getId()).thenReturn(314L); when(_vmInstance.getId()).thenReturn(1L); when(_vmInstance.getServiceOfferingId()).thenReturn(2L); + List mockList = mock(List.class); + when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(mockList); + when(mockList.size()).thenReturn(0); } @@ -298,7 +307,9 @@ public void testRestoreVMF4() throws ResourceUnavailableException, InsufficientC doNothing().when(_volsDao).attachVolume(anyLong(), anyLong(), anyLong()); when(_volumeMock.getId()).thenReturn(3L); doNothing().when(_volsDao).detachVolume(anyLong()); - + List mockList = mock(List.class); + when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(mockList); + when(mockList.size()).thenReturn(0); when(_templateMock.getUuid()).thenReturn("b1a3626e-72e0-4697-8c7c-a110940cc55d"); Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); @@ -343,7 +354,9 @@ public void testRestoreVMF5() throws ResourceUnavailableException, InsufficientC doNothing().when(_volsDao).attachVolume(anyLong(), anyLong(), anyLong()); when(_volumeMock.getId()).thenReturn(3L); doNothing().when(_volsDao).detachVolume(anyLong()); - + List mockList = mock(List.class); + when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(mockList); + when(mockList.size()).thenReturn(0); when(_templateMock.getUuid()).thenReturn("b1a3626e-72e0-4697-8c7c-a110940cc55d"); Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid"); From 186606a0bf82402e7755cd7998f133023cc96c6c Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Wed, 16 Jul 2014 20:50:34 -0400 Subject: [PATCH 091/819] CLOUDSTACK-7107: Disabling failed test case --- test/integration/smoke/test_primary_storage.py | 2 +- test/integration/smoke/test_vm_life_cycle.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 66aec59b8a..7a4f8d61d8 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -51,7 +51,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false", BugId="7074") def test_01_primary_storage_nfs(self): """Test primary storage pools - XEN, KVM, VMWare """ diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index 13868301bb..259c63d896 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -471,7 +471,7 @@ def test_07_restore_vm(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false", BugId="7107") def test_08_migrate_vm(self): """Test migrate VM """ From d382be9578d49fd839952d06944f6312946f0472 Mon Sep 17 00:00:00 2001 From: Saksham Srivastava Date: Mon, 2 Jun 2014 15:51:06 +0530 Subject: [PATCH 092/819] CLOUDSTACK-6508: impossible to list projects from API with domainid set --- server/src/com/cloud/api/query/QueryManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index b09bb0fbbf..39eabd1e25 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1298,7 +1298,7 @@ private Pair, Integer> listProjectsInternal(ListProjectsCmd throw new PermissionDeniedException("Can't list account " + accountName + " projects; unauthorized"); } - if (domainId != null && domainId.equals(caller.getDomainId())) { + if (domainId != null && !domainId.equals(caller.getDomainId())) { throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized"); } From 28a4ae3713af85b95bc0aae52f7fff032ee595aa Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 16 Jul 2014 21:57:01 -0400 Subject: [PATCH 093/819] CLOUDSTACK-7025: Resolving test script issue --- test/integration/component/test_add_remove_network.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/integration/component/test_add_remove_network.py b/test/integration/component/test_add_remove_network.py index 4222f7afec..dbba59bef2 100644 --- a/test/integration/component/test_add_remove_network.py +++ b/test/integration/component/test_add_remove_network.py @@ -208,6 +208,8 @@ def setUpClass(cls): domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) + cls.defaultNetworkId = cls.virtual_machine.nic[0].networkid + # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) From 0c050e04fd80b83dccdeb9d4abe4298aedcf0ea0 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 16 Jul 2014 22:08:29 -0400 Subject: [PATCH 094/819] CLOUDSTACK-7020:Fixed test script issue --- test/integration/component/test_usage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index 4413f43342..4f9d1d73a4 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -661,6 +661,7 @@ def setUpClass(cls): cls.services["ostype"] ) cls.services["server"]["zoneid"] = cls.zone.id + cls._cleanup = [] try: cls.account = Account.create( cls.api_client, From 7f6ea4bbed344c012011820735409ee8731e08b0 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 16 Jul 2014 22:23:59 -0400 Subject: [PATCH 095/819] CLOUDSTACK-7014: Resolving test script related to affinity groups tests --- test/integration/component/test_affinity_groups.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/integration/component/test_affinity_groups.py b/test/integration/component/test_affinity_groups.py index de5f007dbb..9a53c4c7ff 100644 --- a/test/integration/component/test_affinity_groups.py +++ b/test/integration/component/test_affinity_groups.py @@ -346,7 +346,7 @@ def tearDownClass(cls): try: cls.api_client = super(TestListAffinityGroups, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.__cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -594,7 +594,7 @@ def tearDownClass(cls): try: cls.api_client = super(TestDeleteAffinityGroups, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.__cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -865,7 +865,7 @@ def tearDownClass(cls): try: cls.api_client = super(TestUpdateVMAffinityGroups, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.__cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -1149,7 +1149,7 @@ def tearDownClass(cls): try: cls.api_client = super(TestDeployVMAffinityGroups, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.__cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -1496,7 +1496,7 @@ def tearDownClass(cls): try: cls.api_client = super(TestAffinityGroupsAdminUser, cls).getClsTestClient().getApiClient() #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.__cleanup) + cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) From 332191b1bf2935bcad4c05a9fd61d0ebc30f035b Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Wed, 16 Jul 2014 23:30:43 -0400 Subject: [PATCH 096/819] CLOUDSTACK-7013: Fixing test script issue in test_add_remove_network.py --- test/integration/component/test_add_remove_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_add_remove_network.py b/test/integration/component/test_add_remove_network.py index dbba59bef2..2bd6ec2d0c 100644 --- a/test/integration/component/test_add_remove_network.py +++ b/test/integration/component/test_add_remove_network.py @@ -1391,7 +1391,7 @@ def setUpClass(cls): cls._cleanup = [] cls.account = Account.create(cls.api_client,cls.services["account"],domainid = cls.domain.id) - cls.append(cls.account) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client,cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) From 3b76278b978e0e08057fd3351bc6431b63985a05 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 17 Jul 2014 15:32:03 +0200 Subject: [PATCH 097/819] rvr4vpc: more interesting test --- ...irtualNetworkApplianceManagerImplTest.java | 226 ++++++++---------- 1 file changed, 105 insertions(+), 121 deletions(-) diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 8c40178d7a..4e8e6a6ddf 100644 --- a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java +++ b/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -16,9 +16,9 @@ // under the License. package com.cloud.network.router; -import static org.mockito.Mockito.when; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; import java.util.LinkedHashMap; import java.util.List; @@ -64,7 +64,10 @@ import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; +import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.Storage.ProvisioningType; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; @@ -75,6 +78,7 @@ import com.cloud.user.dao.UserStatsLogDao; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; @@ -85,121 +89,49 @@ @RunWith(MockitoJUnitRunner.class) public class VirtualNetworkApplianceManagerImplTest { - @Mock - private ClusterDao _clusterDao; - - @Mock - private ConfigurationDao _configDao; - - @Mock - private DataCenterDao _dcDao; - - @Mock - private GuestOSDao _guestOSDao; - - @Mock - private HostDao _hostDao; - - @Mock - private IPAddressDao _ipAddressDao; - - @Mock - private UserIpv6AddressDao _ipv6Dao; - - @Mock - private LoadBalancerDao _loadBalancerDao; - - @Mock - private LoadBalancerVMMapDao _loadBalancerVMMapDao; - - @Mock - private MonitoringServiceDao _monitorServiceDao; - - @Mock - private ManagementServerHostDao _msHostDao; - - @Mock - private NetworkDao _networkDao; - - @Mock - private NetworkOfferingDao _networkOfferingDao; - - @Mock - private NicDao _nicDao; - - @Mock - private NicIpAliasDao _nicIpAliasDao; - - @Mock - private OpRouterMonitorServiceDao _opRouterMonitorServiceDao; - - @Mock - private PortForwardingRulesDao _pfRulesDao; - - @Mock - private PhysicalNetworkServiceProviderDao _physicalProviderDao; - - @Mock - private HostPodDao _podDao; - - @Mock - private DomainRouterDao _routerDao; - - @Mock - private FirewallRulesDao _rulesDao; - - @Mock - private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; - - @Mock - private Site2SiteVpnConnectionDao _s2sVpnConnectionDao; - - @Mock - private Site2SiteVpnGatewayDao _s2sVpnGatewayDao; - - @Mock - private ServiceOfferingDao _serviceOfferingDao; - - @Mock - private VMTemplateDao _templateDao; - - @Mock - private UserDao _userDao; - - @Mock - private UserStatisticsDao _userStatsDao; - - @Mock - private UserStatsLogDao _userStatsLogDao; - - @Mock - private UserVmDao _userVmDao; - - @Mock - private VlanDao _vlanDao; - - @Mock - private VMInstanceDao _vmDao; - - @Mock - private UserVmDetailsDao _vmDetailsDao; - - @Mock - private VolumeDao _volumeDao; - - @Mock - private RemoteAccessVpnDao _vpnDao; - - @Mock - private VpnUserDao _vpnUsersDao; - - @Mock - private VirtualRouterProviderDao _vrProviderDao; + // mock dao/db access + @Mock private ClusterDao _clusterDao; + @Mock private ConfigurationDao _configDao; + @Mock private DataCenterDao _dcDao; + @Mock private GuestOSDao _guestOSDao; + @Mock private HostDao _hostDao; + @Mock private IPAddressDao _ipAddressDao; + @Mock private UserIpv6AddressDao _ipv6Dao; + @Mock private LoadBalancerDao _loadBalancerDao; + @Mock private LoadBalancerVMMapDao _loadBalancerVMMapDao; + @Mock private MonitoringServiceDao _monitorServiceDao; + @Mock private ManagementServerHostDao _msHostDao; + @Mock private NetworkDao _networkDao; + @Mock private NetworkOfferingDao _networkOfferingDao; + @Mock private NicDao _nicDao; + @Mock private NicIpAliasDao _nicIpAliasDao; + @Mock private OpRouterMonitorServiceDao _opRouterMonitorServiceDao; + @Mock private PortForwardingRulesDao _pfRulesDao; + @Mock private PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Mock private HostPodDao _podDao; + @Mock private DomainRouterDao _routerDao; + @Mock private FirewallRulesDao _rulesDao; + @Mock private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; + @Mock private Site2SiteVpnConnectionDao _s2sVpnConnectionDao; + @Mock private Site2SiteVpnGatewayDao _s2sVpnGatewayDao; + @Mock private ServiceOfferingDao _serviceOfferingDao; + @Mock private VMTemplateDao _templateDao; + @Mock private UserDao _userDao; + @Mock private UserStatisticsDao _userStatsDao; + @Mock private UserStatsLogDao _userStatsLogDao; + @Mock private UserVmDao _userVmDao; + @Mock private VlanDao _vlanDao; + @Mock private VMInstanceDao _vmDao; + @Mock private UserVmDetailsDao _vmDetailsDao; + @Mock private VolumeDao _volumeDao; + @Mock private RemoteAccessVpnDao _vpnDao; + @Mock private VpnUserDao _vpnUsersDao; + @Mock private VirtualRouterProviderDao _vrProviderDao; + + // mock the managers that have no influence on this functionality @Mock private AccountManager _accountMgr; - @Mock private VirtualMachineManager _itMgr; - @Mock private ResourceManager _resourceMgr; @InjectMocks @@ -211,20 +143,72 @@ public void testDestroyRouter() throws Exception { 1L, false, 0, false, RedundantState.UNKNOWN, false, false, null); when(_routerDao.findById(1L)).thenReturn((DomainRouterVO)r); VirtualRouter vr = virtualNetworkApplianceManagerImpl.destroyRouter(1L, new AccountVO(1L), 0L); - assertNotEquals(vr, null); + assertEquals(vr, r); } @Test public void testDeployRouterNotRedundant() throws Exception { - DataCenter dc = new DataCenterVO(1L, "name", "description", "dns", null, null, null, "cidr", "domain", null, - NetworkType.Basic, "zoneToken", "domainSuffix"); - when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L); - when(_resourceMgr.getDefaultHypervisor(1L)).thenReturn(HypervisorType.Any); + ServiceOfferingVO svcoff = new ServiceOfferingVO("name", + /* cpu */ 1, + /* ramsize */ 1024*1024, + /* (clock?)speed */ 1024*1024*1024, + /* rateMbps */ 1, + /* multicastRateMbps */ 0, + /* offerHA */ false, + "displayText", + ProvisioningType.THIN, + /* useLocalStorage */ false, + /* recreatable */ false, + "tags", + /* systemUse */ false, + VirtualMachine.Type.DomainRouter, + /* defaultUse */ false); + + DataCenter dc = new DataCenterVO(/* id */ 1L, + "name", + "description", + "dns1", + /* dns2 */ null, + /* dns3 */ null, + /* dns4 */ null, + "cidr", + "domain", + /*domainid */ null, + NetworkType.Basic, + "zoneToken", + "domainSuffix"); + + DomainRouterVO router = new DomainRouterVO(/* id */ 1L, + /* serviceOfferingId */ 1L, + /* elementId */ 0L, + "name", + /* templateId */0L, + HypervisorType.XenServer, + /* guestOSId */ 0L, + /* domainId */ 0L, + /* accountId */ 1L, + /* isRedundantRouter */ false, + /* priority */ 0, + /* isPriorityBumpUp */ false, + RedundantState.UNKNOWN, + /* haEnabled */ false, + /* stopPending */ false, + /* vpcId */ null); + DeploymentPlan plan = new DataCenterDeployment(1L); + + when(_serviceOfferingDao.findById(1L)).thenReturn(svcoff); + when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L); +// being anti-social and testing my own case first + when(_resourceMgr.getDefaultHypervisor(1L)).thenReturn(HypervisorType.XenServer); + when(_templateDao.findRoutingTemplate(HypervisorType.XenServer, "SystemVM Template (XenServer)")).thenReturn(new VMTemplateVO()); + when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router); + when(_routerDao.findById(router.getId())).thenReturn(router); + VirtualRouter vr = virtualNetworkApplianceManagerImpl.deployRouter(new AccountVO(1L), new DeployDestination(dc,null,null,null), plan, null, false, - new VirtualRouterProviderVO(), 0L, null, new LinkedHashMap> (), true /* start the router */, + new VirtualRouterProviderVO(), 1L, null, new LinkedHashMap> (), true /* start the router */, null); // TODO: more elaborate mocking needed to have a vr returned - assertEquals(vr, null); + assertEquals(vr, router); } } From 4bab99972f5e87bb6059f34cd0a302db703342f7 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Thu, 17 Jul 2014 00:11:02 -0400 Subject: [PATCH 098/819] CLOUDSTACK-7022: Fixed typo --- test/integration/component/test_usage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index 4f9d1d73a4..fe80da7ffd 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -1480,7 +1480,7 @@ def setUpClass(cls): cls.api_client, cls.services["service_offering"] ) - cls._cleanup.append(cls.sevice_offering) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["server"], From 2a01fd4c5101b402fe527d913db8296f7f8ef6b8 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 17 Jul 2014 11:40:27 -0700 Subject: [PATCH 099/819] Quick view: remove extra padding area Remove extra 'buffer zone' around quick view tooltip. This was causing misleading behavior in some cases, due to the cursor being hovered over a different row while another row's quick view was still open --- ui/css/cloudstack3.css | 4 ++-- ui/scripts/ui/widgets/listView.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 5a35977757..23681a7642 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -1396,14 +1396,14 @@ div.list-view td.state.off span { .quick-view-tooltip { width: 470px; display: inline-block; - padding-top: 50px; + padding-top: 0; margin-left: 8px; } .quick-view-tooltip > div.title { width: 444px; position: absolute; - top: 71px; + top: 20px; left: 10px; color: #808080; font-weight: 100; diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 9626a64667..22182c1208 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1462,7 +1462,7 @@ $quickViewTooltip.css({ position: 'absolute', left: $tr.offset().left + $tr.width() - $quickViewTooltip.width(), - top: $quickView.offset().top - 50, + top: $quickView.offset().top, zIndex: $tr.closest('.panel').zIndex() + 1 }); From 809b47e4eb2a99248ad122499e288610a5cd12ad Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 17 Jul 2014 18:40:14 -0700 Subject: [PATCH 100/819] CLOUDSTACK-7124: Fix semicolon caused VPN programming issue Semicolon can cause trouble in bash, need to be escaped. --- .../resource/virtualnetwork/ConfigHelper.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java index 25a2bd9890..d94c1c660b 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java @@ -19,15 +19,6 @@ package com.cloud.agent.resource.virtualnetwork; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.codec.binary.Base64; - -import com.google.gson.Gson; - import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.routing.CreateIpAliasCommand; @@ -62,6 +53,13 @@ import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.rules.FirewallRule; import com.cloud.utils.net.NetUtils; +import com.google.gson.Gson; +import org.apache.commons.codec.binary.Base64; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; public class ConfigHelper { @@ -447,10 +445,11 @@ private static List generateConfig(Site2SiteVpnCfgCommand cmd) { args += cmd.getPeerGatewayIp(); args += " -N "; args += cmd.getPeerGuestCidrList(); + // escape semicolon which may cause issue in bash args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; + args += "\"" + cmd.getEspPolicy().replaceAll(";", "\\\\;") + "\""; args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; + args += "\"" + cmd.getIkePolicy().replaceAll(";", "\\\\;") + "\""; args += " -t "; args += Long.toString(cmd.getIkeLifetime()); args += " -T "; From ef28fd36727bfffbbcb7f2fc120139b7c7d39eb2 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 17 Jul 2014 19:40:45 -0700 Subject: [PATCH 101/819] CLOUDSTACK-7124: Fix unit test --- .../VirtualRoutingResourceTest.java | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java index fc1e3f5da5..3ddb269898 100644 --- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java +++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java @@ -19,25 +19,6 @@ package com.cloud.agent.resource.virtualnetwork; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; - -import javax.naming.ConfigurationException; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; @@ -80,6 +61,23 @@ import com.cloud.network.vpc.VpcGateway; import com.cloud.utils.ExecutionResult; import com.cloud.utils.net.NetUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -575,10 +573,10 @@ private void verifyArgs(Site2SiteVpnCfgCommand cmd, String script, String args) assertEquals(script, VRScripts.S2SVPN_IPSEC); switch (_count) { case 1: - assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 1"); + assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1\\;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 1"); break; case 2: - assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 0 -p "); + assertEquals(args, "-A -l 64.10.1.10 -n 192.168.1.1/16 -g 64.10.1.1 -r 124.10.1.10 -N 192.168.100.1/24 -e \"3des-sha1,aes128-md5\" -i \"3des-sha1,aes128-sha1\\;modp1536\" -t 1800 -T 1800 -s \"psk\" -d 0 -p "); break; case 3: assertEquals(args, "-D -r 124.10.1.10 -n 192.168.1.1/16 -N 192.168.100.1/24"); From b080eaf3270ffae32f7809e5d492139f33603e89 Mon Sep 17 00:00:00 2001 From: Mike Tutkowski Date: Wed, 16 Jul 2014 08:23:49 -0600 Subject: [PATCH 102/819] Updates to the way resizing a volume works --- .../command/user/volume/ResizeVolumeCmd.java | 16 +- .../subsystem/api/storage/VolumeService.java | 2 + .../storage/volume/VolumeServiceImpl.java | 30 +++ .../SolidFirePrimaryDataStoreDriver.java | 58 ++++- .../SolidFirePrimaryDataStoreLifeCycle.java | 2 +- .../com/cloud/network/NetworkServiceImpl.java | 4 +- .../cloud/storage/ResizeVolumePayload.java | 6 +- .../com/cloud/storage/VmWorkResizeVolume.java | 14 +- .../cloud/storage/VolumeApiServiceImpl.java | 240 ++++++++++++------ utils/src/com/cloud/utils/StringUtils.java | 32 +++ 10 files changed, 319 insertions(+), 85 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java index 1cf4f29dc2..49fd6ca194 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java @@ -55,7 +55,13 @@ public class ResizeVolumeCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the disk volume") private Long id; - @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in G") + @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS") + private Long minIops; + + @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS") + private Long maxIops; + + @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in GB") private Long size; @Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink") @@ -81,6 +87,14 @@ public Long getId() { return getEntityId(); } + public Long getMinIops() { + return minIops; + } + + public Long getMaxIops() { + return maxIops; + } + public Long getSize() { return size; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java index b6e61069e7..cadce56c58 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java @@ -96,6 +96,8 @@ AsyncCallFuture createVolumeFromTemplateAsync(VolumeInfo volume AsyncCallFuture resize(VolumeInfo volume); + void resizeVolumeOnHypervisor(long volumeId, long newSize, long destHostId, String instanceName); + void handleVolumeSync(DataStore store); SnapshotInfo takeSnapshot(VolumeInfo volume); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 3a71147f8a..3fc43ea2d8 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -51,6 +51,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.DeleteCommand; @@ -65,6 +66,8 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; @@ -1280,6 +1283,33 @@ public AsyncCallFuture resize(VolumeInfo volume) { return future; } + @Override + public void resizeVolumeOnHypervisor(long volumeId, long newSize, long destHostId, String instanceName) { + final String errMsg = "Resize command failed"; + + try { + Answer answer = null; + Host destHost = _hostDao.findById(destHostId); + EndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(destHost); + + if (ep != null) { + VolumeVO volume = _volumeDao.findById(volumeId); + PrimaryDataStore primaryDataStore = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); + ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(volume.getPath(), new StorageFilerTO(primaryDataStore), volume.getSize(), newSize, true, instanceName); + + answer = ep.sendMessage(resizeCmd); + } else { + throw new CloudRuntimeException("Could not find a remote endpoint to send command to. Check if host or SSVM is down."); + } + + if (answer == null || !answer.getResult()) { + throw new CloudRuntimeException(answer != null ? answer.getDetails() : errMsg); + } + } catch (Exception e) { + throw new CloudRuntimeException(errMsg, e); + } + } + protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); AsyncCallFuture future = context.future; diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java index c06a72895a..5a23fcf399 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java @@ -42,6 +42,7 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; +import com.cloud.capacity.CapacityManager; import com.cloud.dc.ClusterDetailsVO; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.dao.DataCenterDao; @@ -49,6 +50,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.ResizeVolumePayload; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; @@ -57,10 +59,12 @@ import com.cloud.user.AccountDetailsDao; import com.cloud.user.AccountVO; import com.cloud.user.dao.AccountDao; +import com.cloud.utils.exception.CloudRuntimeException; public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Inject private AccountDao _accountDao; @Inject private AccountDetailsDao _accountDetailsDao; + @Inject private CapacityManager _capacityMgr; @Inject private ClusterDetailsDao _clusterDetailsDao; @Inject private DataCenterDao _zoneDao; @Inject private HostDao _hostDao; @@ -400,8 +404,58 @@ public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - throw new UnsupportedOperationException(); + public void resize(DataObject dataObject, AsyncCompletionCallback callback) { + String iqn = null; + String errMsg = null; + + if (dataObject.getType() == DataObjectType.VOLUME) { + VolumeInfo volumeInfo = (VolumeInfo)dataObject; + iqn = volumeInfo.get_iScsiName(); + long storagePoolId = volumeInfo.getPoolId(); + long sfVolumeId = Long.parseLong(volumeInfo.getFolder()); + ResizeVolumePayload payload = (ResizeVolumePayload)volumeInfo.getpayload(); + + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); + SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getSolidFireVolume(sfConnection, sfVolumeId); + + verifySufficientIopsForStoragePool(storagePoolId, volumeInfo.getId(), payload.newMinIops); + + SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolumeId, sfVolume.getTotalSize(), payload.newMinIops, payload.newMaxIops, + getDefaultBurstIops(storagePoolId, payload.newMaxIops)); + + VolumeVO volume = _volumeDao.findById(sfVolumeId); + + volume.setMinIops(payload.newMinIops); + volume.setMaxIops(payload.newMaxIops); + + _volumeDao.update(volume.getId(), volume); + } else { + errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to resize"; + } + + CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg)); + + result.setResult(errMsg); + + callback.complete(result); + } + + private void verifySufficientIopsForStoragePool(long storagePoolId, long volumeId, long newMinIops) { + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + VolumeVO volume = _volumeDao.findById(volumeId); + + long currentMinIops = volume.getMinIops(); + long diffInMinIops = newMinIops - currentMinIops; + + // if the desire is for more IOPS + if (diffInMinIops > 0) { + long usedIops = _capacityMgr.getUsedIops(storagePool); + long capacityIops = storagePool.getCapacityIops(); + + if (usedIops + diffInMinIops > capacityIops) { + throw new CloudRuntimeException("Insufficient number of IOPS available in this storage pool"); + } + } } @Override diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java index c23db14a6a..bc08704519 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java @@ -53,7 +53,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle { private static final Logger s_logger = Logger.getLogger(SolidFirePrimaryDataStoreLifeCycle.class); - @Inject CapacityManager _capacityMgr; + @Inject private CapacityManager _capacityMgr; @Inject private DataCenterDao zoneDao; @Inject private PrimaryDataStoreDao storagePoolDao; @Inject private PrimaryDataStoreHelper dataStoreHelper; diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index c8105e8274..c5d71348a2 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -158,6 +158,7 @@ import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; @@ -2403,7 +2404,8 @@ protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long ne s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade"); return false; } - if (!oldNetworkOffering.getTags().equalsIgnoreCase(newNetworkOffering.getTags())) { + + if (!StringUtils.areTagsEqual(oldNetworkOffering.getTags(), newNetworkOffering.getTags())) { s_logger.debug("Network offerings " + newNetworkOffering.getUuid() + " and " + oldNetworkOffering.getUuid() + " have different tags, can't upgrade"); return false; } diff --git a/server/src/com/cloud/storage/ResizeVolumePayload.java b/server/src/com/cloud/storage/ResizeVolumePayload.java index 55dc66161f..7a927b2179 100644 --- a/server/src/com/cloud/storage/ResizeVolumePayload.java +++ b/server/src/com/cloud/storage/ResizeVolumePayload.java @@ -19,12 +19,16 @@ public class ResizeVolumePayload { public final Long newSize; + public final Long newMinIops; + public final Long newMaxIops; public final boolean shrinkOk; public final String instanceName; public final long[] hosts; - public ResizeVolumePayload(Long newSize, boolean shrinkOk, String instanceName, long[] hosts) { + public ResizeVolumePayload(Long newSize, Long newMinIops, Long newMaxIops, boolean shrinkOk, String instanceName, long[] hosts) { this.newSize = newSize; + this.newMinIops = newMinIops; + this.newMaxIops = newMaxIops; this.shrinkOk = shrinkOk; this.instanceName = instanceName; this.hosts = hosts; diff --git a/server/src/com/cloud/storage/VmWorkResizeVolume.java b/server/src/com/cloud/storage/VmWorkResizeVolume.java index 3ccaecd242..1caab10c9c 100644 --- a/server/src/com/cloud/storage/VmWorkResizeVolume.java +++ b/server/src/com/cloud/storage/VmWorkResizeVolume.java @@ -24,17 +24,21 @@ public class VmWorkResizeVolume extends VmWork { private long volumeId; private long currentSize; private long newSize; + private Long newMinIops; + private Long newMaxIops; private Long newServiceOfferingId; private boolean shrinkOk; public VmWorkResizeVolume(long userId, long accountId, long vmId, String handlerName, - long volumeId, long currentSize, long newSize, Long newServiceOfferingId, boolean shrinkOk) { + long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Long newServiceOfferingId, boolean shrinkOk) { super(userId, accountId, vmId, handlerName); this.volumeId = volumeId; this.currentSize = currentSize; this.newSize = newSize; + this.newMinIops = newMinIops; + this.newMaxIops = newMaxIops; this.newServiceOfferingId = newServiceOfferingId; this.shrinkOk = shrinkOk; } @@ -51,6 +55,14 @@ public long getNewSize() { return newSize; } + public long getNewMinIops() { + return newMinIops; + } + + public long getNewMaxIops() { + return newMaxIops; + } + public Long getNewServiceOfferingId() { return newServiceOfferingId; } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index e788cb2971..49cb520cda 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -121,6 +121,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.Predicate; import com.cloud.utils.ReflectionUse; +import com.cloud.utils.StringUtils; import com.cloud.utils.UriUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; @@ -637,9 +638,9 @@ public VolumeVO doInTransaction(TransactionStatus status) { public boolean validateVolumeSizeRange(long size) { if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { - throw new InvalidParameterValueException("Please specify a size of at least 1 Gb."); + throw new InvalidParameterValueException("Please specify a size of at least 1 GB."); } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) { - throw new InvalidParameterValueException("volume size " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " Gb."); + throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB."); } return true; @@ -716,67 +717,99 @@ protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Lo @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true) public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException { Long newSize = null; + Long newMinIops = null; + Long newMaxIops = null; boolean shrinkOk = cmd.getShrinkOk(); VolumeVO volume = _volsDao.findById(cmd.getEntityId()); + if (volume == null) { throw new InvalidParameterValueException("No such volume"); } + /* Does the caller have authority to act on this volume? */ + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); - DiskOfferingVO newDiskOffering = null; + DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId()); - newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId()); + /* Only works for KVM/XenServer/VMware for now, and volumes with 'None' since they're just allocated in DB */ - /* Only works for KVM/Xen/VMware for now, and volumes with 'None' since they're just allocated in db */ - if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM - && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer - && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware - && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.None) { - throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM, VMware, XenServer hypervisor for resize"); + HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId()); + + if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer && + hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.None) { + throw new InvalidParameterValueException("CloudStack currently only supports volumes marked as the KVM, VMware, or XenServer hypervisor type for resize."); } if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) { - throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. " - + "Volume " + volume.getUuid() + " state is:" + volume.getState()); + throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. Volume " + + volume.getUuid() + " is in state " + volume.getState() + "."); } - /* - * figure out whether or not a new disk offering or size parameter is - * required, get the correct size value - */ + // if we are to use the existing disk offering if (newDiskOffering == null) { - if (diskOffering.isCustomized() || volume.getVolumeType().equals(Volume.Type.ROOT)) { - newSize = cmd.getSize(); + newSize = cmd.getSize(); - if (newSize == null) { - throw new InvalidParameterValueException("new offering is of custom size, need to specify a size"); + // if the caller is looking to change the size of the volume + if (newSize != null) { + if (!diskOffering.isCustomized() && !volume.getVolumeType().equals(Volume.Type.ROOT)) { + throw new InvalidParameterValueException("To change a volume's size without providing a new disk offering, its current disk offering must be " + + "customizable or it must be a root volume."); } - newSize = (newSize << 30); - } else { - throw new InvalidParameterValueException("current offering" + volume.getDiskOfferingId() + " cannot be resized, need to specify a disk offering"); + // convert from bytes to GiB + newSize = newSize << 30; + } + else { + // no parameter provided; just use the original size of the volume + newSize = volume.getSize(); + } + + newMinIops = cmd.getMinIops(); + + if (newMinIops != null) { + if (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops()) { + throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Min IOPS' parameter."); + } + } + else { + // no parameter provided; just use the original min IOPS of the volume + newMinIops = volume.getMinIops(); + } + + newMaxIops = cmd.getMaxIops(); + + if (newMaxIops != null) { + if (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops()) { + throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Max IOPS' parameter."); + } + } + else { + // no parameter provided; just use the original max IOPS of the volume + newMaxIops = volume.getMaxIops(); } + + validateIops(newMinIops, newMaxIops); } else { - if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) { - throw new InvalidParameterValueException("Can only resize Data volumes via new disk offering"); + if (newDiskOffering.getRemoved() != null) { + throw new InvalidParameterValueException("Requested disk offering has been removed."); } - if (newDiskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) { - throw new InvalidParameterValueException("Disk offering ID is missing or invalid"); + if (!DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) { + throw new InvalidParameterValueException("Requested disk offering type is invalid."); } if (diskOffering.getTags() != null) { - if (newDiskOffering.getTags() == null || !newDiskOffering.getTags().equals(diskOffering.getTags())) { - throw new InvalidParameterValueException("Tags on new and old disk offerings must match"); + if (!StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) { + throw new InvalidParameterValueException("The tags on the new and old disk offerings must match."); } } else if (newDiskOffering.getTags() != null) { - throw new InvalidParameterValueException("There are no tags on current disk offering, new disk offering needs to have no tags"); + throw new InvalidParameterValueException("There are no tags on the current disk offering. The new disk offering needs to have no tags, as well."); } - if (newDiskOffering.getDomainId() == null) { - // do nothing as offering is public - } else { + if (newDiskOffering.getDomainId() != null) { + // not a public offering; check access _configMgr.checkDiskOfferingAccess(CallContext.current().getCallingAccount(), newDiskOffering); } @@ -784,108 +817,147 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep newSize = cmd.getSize(); if (newSize == null) { - throw new InvalidParameterValueException("new offering is of custom size, need to specify a size"); + throw new InvalidParameterValueException("The new disk offering requires that a size be specified."); } - newSize = (newSize << 30); + // convert from bytes to GiB + newSize = newSize << 30; } else { newSize = newDiskOffering.getDiskSize(); } - } - if (newSize == null) { - throw new InvalidParameterValueException("could not detect a size parameter or fetch one from the diskofferingid parameter"); - } + if (volume.getSize() != newSize && !volume.getVolumeType().equals(Volume.Type.DATADISK)) { + throw new InvalidParameterValueException("Only data volumes can be resized via a new disk offering."); + } - if (!validateVolumeSizeRange(newSize)) { - throw new InvalidParameterValueException("Requested size out of range"); - } + if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) { + newMinIops = cmd.getMinIops() != null ? cmd.getMinIops() : volume.getMinIops(); + newMaxIops = cmd.getMaxIops() != null ? cmd.getMaxIops() : volume.getMaxIops(); - /* does the caller have the authority to act on this volume? */ - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); + validateIops(newMinIops, newMaxIops); + } + else { + newMinIops = newDiskOffering.getMinIops(); + newMaxIops = newDiskOffering.getMaxIops(); + } + } long currentSize = volume.getSize(); - /* - * lets make certain they (think they) know what they're doing if they - * want to shrink, by forcing them to provide the shrinkok parameter. - * This will be checked again at the hypervisor level where we can see - * the actual disk size - */ - if (currentSize > newSize && !shrinkOk) { - throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize - + " would shrink the volume, need to sign off by supplying the shrinkok parameter with value of true"); - } + // if the caller is looking to change the size of the volume + if (currentSize != newSize) { + if (!validateVolumeSizeRange(newSize)) { + throw new InvalidParameterValueException("Requested size out of range"); + } - if (!shrinkOk) { - /* Check resource limit for this account on primary storage resource */ - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - - currentSize).longValue()); + /* + * Let's make certain they (think they) know what they're doing if they + * want to shrink by forcing them to provide the shrinkok parameter. + * This will be checked again at the hypervisor level where we can see + * the actual disk size. + */ + if (currentSize > newSize && !shrinkOk) { + throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume." + + "Need to sign off by supplying the shrinkok parameter with value of true."); + } + + if (newSize > currentSize) { + /* Check resource limit for this account on primary storage resource */ + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(), + new Long(newSize - currentSize).longValue()); + } } - /* If this volume has never been beyond allocated state, short circuit everything and simply update the database */ + // Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS are available to perform + // the requested change + + /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */ if (volume.getState() == Volume.State.Allocated) { - s_logger.debug("Volume is allocated, but never created, simply updating database with new size"); + s_logger.debug("Volume is in the allocated state, but has never been created. Simply updating database with new size and IOPS."); + volume.setSize(newSize); + volume.setMinIops(newMinIops); + volume.setMaxIops(newMaxIops); + if (newDiskOffering != null) { volume.setDiskOfferingId(cmd.getNewDiskOfferingId()); } + _volsDao.update(volume.getId(), volume); + return volume; } UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); - if (userVm != null) { // serialize VM operation AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); + if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { placeHolder = createPlaceHolderWork(userVm.getId()); } + try { - return orchestrateResizeVolume(volume.getId(), currentSize, newSize, + return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); } finally { - if (VmJobEnabled.value()) + if (VmJobEnabled.value()) { _workJobDao.expunge(placeHolder.getId()); + } } - } else { - Outcome outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, + Outcome outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); - Volume vol = null; try { outcome.get(); } catch (InterruptedException e) { - throw new RuntimeException("Operation is interrupted", e); + throw new RuntimeException("Operation was interrupted", e); } catch (java.util.concurrent.ExecutionException e) { - throw new RuntimeException("Execution excetion", e); + throw new RuntimeException("Execution exception", e); } Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob()); + if (jobResult != null) { - if (jobResult instanceof ConcurrentOperationException) + if (jobResult instanceof ConcurrentOperationException) { throw (ConcurrentOperationException)jobResult; - else if (jobResult instanceof Throwable) + } + else if (jobResult instanceof Throwable) { throw new RuntimeException("Unexpected exception", (Throwable)jobResult); + } else if (jobResult instanceof Long) { - vol = _volsDao.findById((Long)jobResult); + return _volsDao.findById((Long)jobResult); } } + return volume; } } - return orchestrateResizeVolume(volume.getId(), currentSize, newSize, + + return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); + } + + private void validateIops(Long minIops, Long maxIops) { + if ((minIops == null && maxIops != null) || (minIops != null && maxIops == null)) { + throw new InvalidParameterValueException("Either 'miniops' and 'maxiops' must both be provided or neither must be provided."); } - private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newDiskOfferingId, boolean shrinkOk) { + if (minIops != null && maxIops != null) { + if (minIops > maxIops) { + throw new InvalidParameterValueException("The 'miniops' parameter must be less than or equal to the 'maxiops' parameter."); + } + } + } + + private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Long newDiskOfferingId, boolean shrinkOk) { VolumeVO volume = _volsDao.findById(volumeId); UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); /* @@ -905,12 +977,12 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n } /* Xen only works offline, SR does not support VDI.resizeOnline */ - if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) { + if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) { throw new InvalidParameterValueException("VM must be stopped or disk detached in order to resize with the Xen HV"); } } - ResizeVolumePayload payload = new ResizeVolumePayload(newSize, shrinkOk, instanceName, hosts); + ResizeVolumePayload payload = new ResizeVolumePayload(newSize, newMinIops, newMaxIops, shrinkOk, instanceName, hosts); try { VolumeInfo vol = volFactory.getVolume(volume.getId()); @@ -925,6 +997,18 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n volume = _volsDao.findById(volume.getId()); + StoragePoolVO storagePool = _storagePoolDao.findById(vol.getPoolId()); + + if (storagePool.isManaged()) { + if (hosts.length > 0) { + volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName); + } + + volume.setSize(newSize); + + /** @todo let the storage driver know the CloudStack volume within the storage volume in question has a new size */ + } + if (newDiskOfferingId != null) { volume.setDiskOfferingId(newDiskOfferingId); } @@ -2364,7 +2448,7 @@ public Object[] doInTransaction(TransactionStatus status) { } public Outcome resizeVolumeThroughJobQueue(final Long vmId, final long volumeId, - final long currentSize, final long newSize, final Long newServiceOfferingId, final boolean shrinkOk) { + final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops, final Long newServiceOfferingId, final boolean shrinkOk) { final CallContext context = CallContext.current(); final User callingUser = context.getCallingUser(); @@ -2394,7 +2478,7 @@ public Object[] doInTransaction(TransactionStatus status) { // save work context info (there are some duplications) VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), - VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newServiceOfferingId, shrinkOk); + VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newMinIops, newMaxIops, newServiceOfferingId, shrinkOk); workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); @@ -2529,7 +2613,7 @@ private Pair orchestrateDetachVolumeFromVM(VmWorkDetachV @ReflectionUse private Pair orchestrateResizeVolume(VmWorkResizeVolume work) throws Exception { - Volume vol = orchestrateResizeVolume(work.getVolumeId(), work.getCurrentSize(), work.getNewSize(), + Volume vol = orchestrateResizeVolume(work.getVolumeId(), work.getCurrentSize(), work.getNewSize(), work.getNewMinIops(), work.getNewMaxIops(), work.getNewServiceOfferingId(), work.isShrinkOk()); return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId()))); diff --git a/utils/src/com/cloud/utils/StringUtils.java b/utils/src/com/cloud/utils/StringUtils.java index 09045aa735..3b8cf71ca3 100644 --- a/utils/src/com/cloud/utils/StringUtils.java +++ b/utils/src/com/cloud/utils/StringUtils.java @@ -198,6 +198,38 @@ public static String cleanDetails(String stringToClean, String detailsIndexSting return cleanResult; } + public static boolean areTagsEqual(String tags1, String tags2) { + if (tags1 == null && tags2 == null) { + return true; + } + + if (tags1 != null && tags2 == null) { + return false; + } + + if (tags1 == null && tags2 != null) { + return false; + } + + final String delimiter = ","; + + List lstTags1 = new ArrayList(); + String[] aTags1 = tags1.split(delimiter); + + for (String tag1 : aTags1) { + lstTags1.add(tag1.toLowerCase()); + } + + List lstTags2 = new ArrayList(); + String[] aTags2 = tags2.split(delimiter); + + for (String tag2 : aTags2) { + lstTags2.add(tag2.toLowerCase()); + } + + return lstTags1.containsAll(lstTags2) && lstTags2.containsAll(lstTags1); + } + public static String stripControlCharacters(String s) { return StringUtilities.stripControls(s); } From f3cbb699955243007ffb53b335d9508b2e422a06 Mon Sep 17 00:00:00 2001 From: punith-cloudbyte Date: Fri, 11 Jul 2014 16:35:23 +0530 Subject: [PATCH 103/819] first commit of improvised cloudbyte storage plugin Signed-off-by: Mike Tutkowski --- ...pring-storage-volume-cloudbyte-context.xml | 16 +- .../ElastistorPrimaryDataStoreDriver.java | 325 ++- .../ElastistorPrimaryDataStoreLifeCycle.java | 527 +++-- .../provider/ElastistorHostListener.java | 27 +- .../ElastistorPrimaryDataStoreProvider.java | 97 +- .../datastore/util/ElastistorUtil.java | 2042 ++++++++++++++--- .../util/ElastistorVolumeApiService.java | 32 + .../util/ElastistorVolumeApiServiceImpl.java | 206 ++ .../util/ListElastistorInterfaceCmd.java | 58 + .../util/ListElastistorInterfaceResponse.java | 63 + .../datastore/util/ListElastistorPoolCmd.java | 61 + .../util/ListElastistorPoolResponse.java | 114 + .../util/ListElastistorVolumeCmd.java | 59 + .../util/ListElastistorVolumeResponse.java | 99 + 14 files changed, 3130 insertions(+), 596 deletions(-) create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java create mode 100644 plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml index 87c5f51393..4a564826f9 100755 --- a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml +++ b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml @@ -28,13 +28,11 @@ > - - - - - - - - + class="org.apache.cloudstack.storage.datastore.provider.ElastistorPrimaryDataStoreProvider"> + + + + + diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java index 99d1e2aaa4..a4f38ce888 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.Map; import javax.inject.Inject; @@ -31,14 +32,39 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; +import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; +import com.cloud.host.Host; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.ResizeVolumePayload; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeDetailVO; +import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.user.AccountManager; +import com.cloud.utils.exception.CloudRuntimeException; -public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver{ +/** + * The implementation class for ElastistorPrimaryDataStoreDriver. + * This directs the public interface methods to use CloudByte's Elastistor based + * volumes. + */ +public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(ElastistorPrimaryDataStoreDriver.class); @@ -46,6 +72,15 @@ public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStor AccountManager _accountMgr; @Inject DiskOfferingDao _diskOfferingDao; + @Inject + private VolumeDao _volumeDao; + @Inject + private PrimaryDataStoreDao _storagePoolDao; + @Inject + StorageManager storageMgr; + @Inject + VolumeDetailsDao _volumeDetailsDao; + @Override public DataTO getTO(DataObject data) { return null; @@ -57,11 +92,167 @@ public DataStoreTO getStoreTO(DataStore store) { } public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { - super.createAsync(dataStore, dataObject, callback); + + String iqn = null; + String errMsg = null; + + CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg)); + + if (dataObject.getType() == DataObjectType.VOLUME) { + + VolumeInfo volumeInfo = (VolumeInfo) dataObject; + + long storagePoolId = dataStore.getId(); + String volumeName = volumeInfo.getName(); + Long Iops = volumeInfo.getMaxIops(); + // quota size of the cloudbyte volume will be increased with the given HypervisorSnapshotReserve + Long quotaSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId)); + + StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId()); + VolumeVO volume = _volumeDao.findById(volumeInfo.getId()); + + // if the primary storage is not managed (thick provisioned) + // then no need to create volume at elastistor, + // calling super(default) that creates a vdi(disk) only. + if (!(storagePool.isManaged())) { + super.createAsync(dataStore, dataObject, callback); + + // update the volume property + volume.setPoolType(storagePool.getPoolType()); + _volumeDao.update(volume.getId(), volume); + + return; + } + + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeInfo.getDiskOfferingId()); + + long capacityIops = storagePool.getCapacityIops(); + capacityIops = capacityIops - Iops; + + if (capacityIops < 0) { + throw new CloudRuntimeException("IOPS not available. [pool:" + storagePool.getName() + "] [availiops:" + capacityIops + "] [requirediops:" + Iops + "]"); + } + + String protocoltype = null; + StoragePoolVO dataStoreVO = (StoragePoolVO) _storagePoolDao.findById(storagePoolId); + String desc = diskOffering.getDisplayText(); + + if (desc.toLowerCase().contains("iscsi")) { + protocoltype = "iscsi"; + } else if (dataStoreVO.getPoolType().equals(StoragePoolType.NetworkFilesystem) || dataStoreVO.getPoolType().equals(StoragePoolType.Filesystem)) { + protocoltype = "nfs"; + } else { + protocoltype = "iscsi"; + } + + FileSystem esvolume = null; + try { + esvolume = ElastistorUtil.createElastistorVolume(volumeName, dataStoreVO.getUuid(), quotaSize, Iops, protocoltype, volumeName); + } catch (Throwable e) { + s_logger.error(e.toString(), e); + result.setResult(e.toString()); + callback.complete(result); + throw new CloudRuntimeException(e.getMessage()); + } + + if (esvolume.getNfsenabled().equalsIgnoreCase("true")) { + volume.set_iScsiName(esvolume.getPath()); + volume.setPoolType(StoragePoolType.NetworkFilesystem); + } else { + iqn = esvolume.getIqn(); + String modifiediqn = "/" + iqn + "/0"; + volume.set_iScsiName(modifiediqn); + volume.setPoolType(StoragePoolType.IscsiLUN); + } + + volume.setFolder(String.valueOf(esvolume.getUuid())); + volume.setPoolId(storagePoolId); + volume.setUuid(esvolume.getUuid()); + volume.setPath(null); + + _volumeDao.update(volume.getId(), volume); + + // create new volume details for the volume + updateVolumeDetails(volume, esvolume); + + long capacityBytes = storagePool.getCapacityBytes(); + long usedBytes = storagePool.getUsedBytes(); + + Long inbytes = volume.getSize(); + + usedBytes += inbytes; + + storagePool.setCapacityIops(capacityIops); + storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); + s_logger.info("Elastistor volume creation complete."); + } else { + errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync"; + s_logger.error(errMsg); + } + + result.setResult(errMsg); + + callback.complete(result); } public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { - super.deleteAsync(dataStore, dataObject, callback); + + String errMsg = null; + + StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId()); + + // if the primary storage is not managed(thick provisioned) then no need + // to delete volume at elastistor, just + // call the super(default) to delete a vdi(disk) only. + + if (!(storagePool.isManaged())) { + super.deleteAsync(dataStore, dataObject, callback); + return; + } + + if (dataObject.getType() == DataObjectType.VOLUME) { + VolumeInfo volumeInfo = (VolumeInfo) dataObject; + + long storagePoolId = dataStore.getId(); + boolean result = false; + try { + result = ElastistorUtil.deleteElastistorVolume(volumeInfo.getUuid()); + } catch (Throwable e) { + e.printStackTrace(); + CommandResult result2 = new CommandResult(); + result2.setResult(e.toString()); + callback.complete(result2); + } + + if (result) { + + _volumeDao.deleteVolumesByInstance(volumeInfo.getId()); + + long usedBytes = storagePool.getUsedBytes(); + long capacityIops = storagePool.getCapacityIops(); + + usedBytes -= volumeInfo != null ? volumeInfo.getSize() : 0; + capacityIops += volumeInfo != null ? volumeInfo.getMaxIops() : 0; + + storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes); + storagePool.setCapacityIops(capacityIops < 0 ? 0 : capacityIops); + + _storagePoolDao.update(storagePoolId, storagePool); + } else { + errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync"; + } + + } else { + errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync"; + } + + CommandResult result = new CommandResult(); + + result.setResult(errMsg); + + callback.complete(result); } @Override @@ -77,16 +268,120 @@ public boolean canCopy(DataObject srcData, DataObject destData) { @Override public void resize(DataObject data, AsyncCompletionCallback callback) { - throw new UnsupportedOperationException(); + + s_logger.debug("Resize elastistor volume started"); + Boolean status = false; + VolumeObject vol = (VolumeObject) data; + StoragePool pool = (StoragePool) data.getDataStore(); + + ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload(); + + CreateCmdResult result = new CreateCmdResult(null, null); + + StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId()); + + if (!(poolVO.isManaged())) { + super.resize(data, callback); + return; + } + + try { + + status = ElastistorUtil.updateElastistorVolumeSize(vol.getUuid(), resizeParameter.newSize); + + } catch (Throwable e) { + s_logger.error("Resize elastistor volume failed, please contact elastistor admin.", e); + result.setResult(e.toString()); + callback.complete(result); + } + + if (status) { + // now updating the cloudstack storagepool usedbytes and volume + Long usedBytes = poolVO.getUsedBytes(); + Long currentVolumeSize = vol.getSize(); + Long newUsedBytes; + + if (currentVolumeSize < resizeParameter.newSize) { + newUsedBytes = usedBytes + (resizeParameter.newSize - currentVolumeSize); + poolVO.setUsedBytes(newUsedBytes); + } else { + newUsedBytes = usedBytes - (currentVolumeSize - resizeParameter.newSize); + poolVO.setUsedBytes(newUsedBytes); + } + + _storagePoolDao.update(pool.getId(), poolVO); + + vol.getVolume().setSize(resizeParameter.newSize); + vol.update(); + callback.complete(result); + } else { + callback.complete(result); + } + + } + + //this method will utilize the volume details table to add third party volume properties + public void updateVolumeDetails(VolumeVO volume, FileSystem esvolume) { + + VolumeDetailVO compression = new VolumeDetailVO(volume.getId(), "compression", esvolume.getCompression(), false); + _volumeDetailsDao.persist(compression); + VolumeDetailVO deduplication = new VolumeDetailVO(volume.getId(), "deduplication", esvolume.getDeduplication(), false); + _volumeDetailsDao.persist(deduplication); + VolumeDetailVO sync = new VolumeDetailVO(volume.getId(), "sync", esvolume.getSync(), false); + _volumeDetailsDao.persist(sync); + VolumeDetailVO graceallowed = new VolumeDetailVO(volume.getId(), "graceallowed", esvolume.getGraceallowed(), false); + _volumeDetailsDao.persist(graceallowed); + + } + + @Override + public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) { + long volumeSize = volume.getSize(); + Integer hypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve(); + + if (hypervisorSnapshotReserve != null) { + if (hypervisorSnapshotReserve < 25) { + hypervisorSnapshotReserve = 25; + } + + volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f); + } + + return volumeSize; } public ChapInfo getChapInfo(VolumeInfo volumeInfo) { - return super.getChapInfo(volumeInfo); + return null; } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - throw new UnsupportedOperationException(); + CreateCmdResult result = null; + try { + s_logger.info("taking elastistor volume snapshot"); + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO(); + + String volumeid = snapshotTO.getVolume().getUuid(); + String snapshotname = snapshotTO.getName(); + + Answer answer = ElastistorUtil.createElastistorVolumeSnapshot(volumeid, snapshotname); + + if(answer.getResult() == false){ + s_logger.info("elastistor volume snapshot failed"); + throw new CloudRuntimeException("elastistor volume snapshot failed"); + }else{ + s_logger.info("elastistor volume snapshot succesfull"); + result = new CreateCmdResult(null, null); + result.setSuccess(answer.getResult()); + result.setAnswer(answer); + } + } + catch (Throwable e) { + s_logger.debug("Failed to take snapshot: " + e.getMessage()); + result = new CreateCmdResult(null, null); + result.setResult(e.toString()); + } + callback.complete(result); } @Override @@ -94,4 +389,22 @@ public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback getCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + // TODO Auto-generated method stub + + } + } diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java index 33004e3c69..8dbf03ab05 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java @@ -36,8 +36,10 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.util.ElastistorUtil; -import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.CreateTsmCmdResponse; -import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.CreateVolumeCmdResponse; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.Tsm; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.UpdateTsmCmdResponse; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.UpdateTsmStorageCmdResponse; import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; import org.apache.log4j.Logger; @@ -46,6 +48,7 @@ import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.capacity.CapacityManager; import com.cloud.dc.dao.DataCenterDao; import com.cloud.host.Host; import com.cloud.host.HostVO; @@ -87,6 +90,8 @@ public class ElastistorPrimaryDataStoreLifeCycle implements PrimaryDataStoreLife StoragePoolDetailsDao _storagePoolDetailsDao; @Inject DataCenterDao _zoneDao; + @Inject + CapacityManager _capacityMgr; @Override public DataStore initialize(Map dsInfos) { @@ -100,36 +105,56 @@ public DataStore initialize(Map dsInfos) { Long capacityBytes = (Long) dsInfos.get("capacityBytes"); Long capacityIops = (Long) dsInfos.get("capacityIops"); String tags = (String) dsInfos.get("tags"); + boolean managed = (Boolean) dsInfos.get("managed"); Map details = (Map) dsInfos.get("details"); - String storageIp = getStorageIp(url); - int storagePort = getDefaultStoragePort(url); - StoragePoolType storagetype = getStorageType(url); - String accesspath = getAccessPath(url); - String protocoltype = getProtocolType(url); - String[] mp = accesspath.split("/"); - String mountpoint = mp[1]; - String uuid = null ; - + String domainName = details.get("domainname"); + + String storageIp; + int storagePort = 0; + StoragePoolType storagetype = null; + String accesspath = null; + String protocoltype = null; + String mountpoint = null; + + if (!managed) { + storageIp = getStorageIp(url); + storagePort = getDefaultStoragePort(url); + storagetype = getStorageType(url); + accesspath = getAccessPath(url); + protocoltype = getProtocolType(url); + String[] mp = accesspath.split("/"); + mountpoint = mp[1]; + + } else if (details.get("hypervisortype") == "KVM") { + storageIp = url; + storagePort = 3260; + storagetype = StoragePoolType.Iscsi; + accesspath = storageIp + ":/" + storagePoolName; + }else{ + storageIp = url; + storagePort = 2049; + storagetype = StoragePoolType.NetworkFilesystem; + accesspath = storageIp + ":/" + storagePoolName; + } /** * if the elastistor params which are required for plugin configuration - * are not injected through spring-storage-volume-cloudbyte-context.xml, it can be set from details map. + * are not injected through spring-storage-volume-cloudbyte-context.xml, + * it can be set from details map. */ - if(details.get("esaccountid") != null) + if (details.get("esaccountid") != null) ElastistorUtil.setElastistorAccountId(details.get("esaccountid")); - if(details.get("esapikey") != null) - ElastistorUtil.setElastistorApiKey(details.get("esapikey")); - if(details.get("esdefaultgateway") != null) + if (details.get("esdefaultgateway") != null) ElastistorUtil.setElastistorGateway(details.get("esdefaultgateway")); - if(details.get("estntinterface") != null) + if (details.get("estntinterface") != null) ElastistorUtil.setElastistorInterface(details.get("estntinterface")); - if(details.get("esmanagementip") != null) - ElastistorUtil.setElastistorManagementIp(details.get("esmanagementip")); - if(details.get("espoolid") != null) + if (details.get("espoolid") != null) ElastistorUtil.setElastistorPoolId(details.get("espoolid")); - if(details.get("essubnet") != null) + if (details.get("essubnet") != null) ElastistorUtil.setElastistorSubnet(details.get("essubnet")); - if (capacityBytes == null || capacityBytes <= 0) { + s_logger.info("Elastistor details was set successfully."); + + if (capacityBytes == null || capacityBytes <= 0) { throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0."); } @@ -137,33 +162,33 @@ public DataStore initialize(Map dsInfos) { throw new IllegalArgumentException("'capacityIops' must be present and greater than 0."); } + if (domainName == null) { + domainName = "ROOT"; + s_logger.debug("setting the domain to ROOT"); + } + // elastistor does not allow same name and ip pools. List storagePoolVO = _storagePoolDao.listAll(); - for(StoragePoolVO poolVO : storagePoolVO){ - if (storagePoolName.equals(poolVO.getName())) { - throw new IllegalArgumentException("storage pool with that name already exists in elastistor,please specify a unique name ."); - } - if (storageIp.equals(poolVO.getHostAddress())) { - throw new IllegalArgumentException("storage pool with that ip already exists in elastistor,please specify a unique ip ."); - } + for (StoragePoolVO poolVO : storagePoolVO) { + if (storagePoolName.equals(poolVO.getName())) { + throw new IllegalArgumentException("Storage pool with this name already exists in elastistor, please specify a unique name. [name:" + storagePoolName + "]"); + } + if (storageIp.equals(poolVO.getHostAddress())) { + throw new IllegalArgumentException("Storage pool with this ip already exists in elastistor, please specify a unique ip. [ip:" + storageIp + "]"); + } } PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); - // creates the volume in elastistor - parameters = createElastistorVolume(parameters, storagePoolName, storageIp, capacityBytes, capacityIops, protocoltype, mountpoint); - parameters.setHost(storageIp); parameters.setPort(storagePort); - if(protocoltype.contentEquals("nfs")){ parameters.setPath(accesspath); - } parameters.setType(storagetype); parameters.setZoneId(zoneId); parameters.setPodId(podId); parameters.setName(storagePoolName); parameters.setProviderName(providerName); - parameters.setManaged(false); + parameters.setManaged(managed); parameters.setCapacityBytes(capacityBytes); parameters.setUsedBytes(0); parameters.setCapacityIops(capacityIops); @@ -172,147 +197,173 @@ public DataStore initialize(Map dsInfos) { parameters.setDetails(details); parameters.setClusterId(clusterId); + Tsm tsm = null; + if (managed) { + // creates the TSM in elastistor + tsm = createElastistorTSM(storagePoolName, storageIp, capacityBytes, capacityIops, domainName); + } else { + // creates the TSM & Volume in elastistor + tsm = createElastistorTSM(storagePoolName, storageIp, capacityBytes, capacityIops, domainName); + + parameters = createElastistorVolume(parameters, tsm, storagePoolName, capacityBytes, capacityIops, protocoltype, mountpoint); + } + + // setting tsm's uuid as storagepool's uuid + parameters.setUuid(tsm.getUuid()); + return _dataStoreHelper.createPrimaryDataStore(parameters); } - private PrimaryDataStoreParameters createElastistorVolume(PrimaryDataStoreParameters parameters, String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops, String protocoltype, String mountpoint){ + private Tsm createElastistorTSM(String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops, String domainName) { - s_logger.info("creation of elastistor volume started"); + s_logger.info("Creation of elastistor TSM started."); + + Tsm tsm; + String elastistorAccountId; try { + // to create a tsm , account id is required, so getting the account id for the given cloudstack domain + elastistorAccountId = ElastistorUtil.getElastistorAccountId(domainName); - CreateTsmCmdResponse tsmCmdResponse = ElastistorUtil.createElastistorTsm(storagePoolName, storageIp, capacityBytes, capacityIops); + // create the tsm for the given account id + tsm = ElastistorUtil.createElastistorTsm(storagePoolName, storageIp, capacityBytes, capacityIops, elastistorAccountId); + } catch (Throwable e) { + s_logger.error("Failed to create TSM in elastistor.", e); + throw new CloudRuntimeException("Failed to create TSM in elastistor. " + e.getMessage()); + } + + s_logger.info("Creation of elastistor TSM completed successfully."); - String uuid = tsmCmdResponse.getTsm().getUuid(); - parameters.setUuid(uuid); + return tsm; + } - CreateVolumeCmdResponse volumeCmdResponse = ElastistorUtil.createElastistorVolume(storagePoolName, tsmCmdResponse, capacityBytes, capacityIops, protocoltype ,mountpoint); + private PrimaryDataStoreParameters createElastistorVolume(PrimaryDataStoreParameters parameters, Tsm tsm, String storagePoolName, Long capacityBytes, Long capacityIops, String protocoltype, + String mountpoint) { - if(protocoltype.contentEquals("iscsi")){ - String accesspath = "/"+volumeCmdResponse.getFileSystem().getIqn()+"/0"; - parameters.setPath(accesspath); + try { + + s_logger.info("Creation of elastistor volume started."); + + FileSystem volume = ElastistorUtil.createElastistorVolume(storagePoolName, tsm.getUuid(), capacityBytes, capacityIops, protocoltype, mountpoint); + + if (protocoltype.contentEquals("iscsi")) { + String accesspath = "/" + volume.getIqn() + "/0"; + parameters.setPath(accesspath); } - s_logger.info("creation of elastistor volume complete"); + s_logger.info("Creation of elastistor volume completed successfully."); return parameters; } catch (Throwable e) { - throw new CloudRuntimeException("Failed to create volume in elastistor" + e.toString()); + s_logger.error("Failed to create volume in elastistor.", e); + throw new CloudRuntimeException("Failed to create volume in elastistor. " + e.getMessage()); } } private String getAccessPath(String url) { - StringTokenizer st = new StringTokenizer(url ,"/"); + StringTokenizer st = new StringTokenizer(url, "/"); int count = 0; while (st.hasMoreElements()) { - if(count == 2) - { String s = "/" ; - return s.concat(st.nextElement().toString()); - } - st.nextElement(); - count++; - } + if (count == 2) { + String s = "/"; + return s.concat(st.nextElement().toString()); + } + st.nextElement(); + count++; + } return null; } - private StoragePoolType getStorageType(String url) { - StringTokenizer st = new StringTokenizer(url ,":"); + StringTokenizer st = new StringTokenizer(url, ":"); - while (st.hasMoreElements()) - { + while (st.hasMoreElements()) { String accessprotocol = st.nextElement().toString(); - if(accessprotocol.contentEquals("nfs")) - { - return StoragePoolType.NetworkFilesystem; - } - else if(accessprotocol.contentEquals("iscsi")) - { - return StoragePoolType.IscsiLUN; - } + if (accessprotocol.contentEquals("nfs")) { + return StoragePoolType.NetworkFilesystem; + } else if (accessprotocol.contentEquals("iscsi")) { + return StoragePoolType.IscsiLUN; + } - else + else - break; + break; - } - return null; + } + return null; } private String getProtocolType(String url) { - StringTokenizer st = new StringTokenizer(url ,":"); - - while (st.hasMoreElements()) - { - String accessprotocol = st.nextElement().toString(); - - if(accessprotocol.contentEquals("nfs")){ - return "nfs"; - }else if(accessprotocol.contentEquals("iscsi")){ - return "iscsi"; - } else - break; - } + StringTokenizer st = new StringTokenizer(url, ":"); + + while (st.hasMoreElements()) { + String accessprotocol = st.nextElement().toString(); + + if (accessprotocol.contentEquals("nfs")) { + return "nfs"; + } else if (accessprotocol.contentEquals("iscsi")) { + return "iscsi"; + } else + break; + } return null; } - // this method parses the url and gets the default storage port based on access protocol + // this method parses the url and gets the default storage port based on + // access protocol private int getDefaultStoragePort(String url) { - StringTokenizer st = new StringTokenizer(url ,":"); + StringTokenizer st = new StringTokenizer(url, ":"); - while (st.hasMoreElements()) - { + while (st.hasMoreElements()) { - String accessprotocol = st.nextElement().toString(); + String accessprotocol = st.nextElement().toString(); - if(accessprotocol.contentEquals("nfs")){ - return 2049; - } - else if(accessprotocol.contentEquals("iscsi")){ - return 3260; - } - else - break; + if (accessprotocol.contentEquals("nfs")) { + return 2049; + } else if (accessprotocol.contentEquals("iscsi")) { + return 3260; + } else + break; - } + } return -1; } - // parses the url and returns the storage volume ip + // parses the url and returns the storage volume ip private String getStorageIp(String url) { - StringTokenizer st = new StringTokenizer(url ,"/"); + StringTokenizer st = new StringTokenizer(url, "/"); int count = 0; while (st.hasMoreElements()) { - if(count == 1) - return st.nextElement().toString(); + if (count == 1) + return st.nextElement().toString(); - st.nextElement(); + st.nextElement(); count++; - } + } return null; } - @Override - public boolean attachCluster(DataStore store, ClusterScope scope) { + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { - dataStoreHelper.attachCluster(store); + dataStoreHelper.attachCluster(store); - PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store; - // Check if there is host up in this cluster - List allHosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, primarystore.getClusterId(), - primarystore.getPodId(), primarystore.getDataCenterId()); - if (allHosts.isEmpty()) { - primaryDataStoreDao.expunge(primarystore.getId()); - throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " - + primarystore.getClusterId()); - } + StoragePoolVO dataStoreVO = _storagePoolDao.findById(store.getId()); + PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store; + // Check if there is host up in this cluster + List allHosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, primarystore.getClusterId(), primarystore.getPodId(), primarystore.getDataCenterId()); + if (allHosts.isEmpty()) { + primaryDataStoreDao.expunge(primarystore.getId()); + throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + primarystore.getClusterId()); + } + if (!dataStoreVO.isManaged()) { boolean success = false; for (HostVO h : allHosts) { success = createStoragePool(h.getId(), primarystore); @@ -320,56 +371,54 @@ public boolean attachCluster(DataStore store, ClusterScope scope) { break; } } + } - s_logger.debug("In createPool Adding the pool to each of the hosts"); - List poolHosts = new ArrayList(); - for (HostVO h : allHosts) { - try { - storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId()); - poolHosts.add(h); - } catch (Exception e) { - s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e); - } + s_logger.debug("In createPool Adding the pool to each of the hosts"); + List poolHosts = new ArrayList(); + for (HostVO h : allHosts) { + try { + storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId()); + poolHosts.add(h); + } catch (Exception e) { + s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e); + } - if (poolHosts.isEmpty()) { - s_logger.warn("No host can access storage pool " + primarystore + " on cluster " - + primarystore.getClusterId()); + if (poolHosts.isEmpty()) { + s_logger.warn("No host can access storage pool " + primarystore + " on cluster " + primarystore.getClusterId()); primaryDataStoreDao.expunge(primarystore.getId()); throw new CloudRuntimeException("Failed to access storage pool"); } - } - - return true; } - private boolean createStoragePool(long hostId, StoragePool pool) { - s_logger.debug("creating pool " + pool.getName() + " on host " + hostId); - if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem - && pool.getPoolType() != StoragePoolType.IscsiLUN && pool.getPoolType() != StoragePoolType.Iscsi - && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint - && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 - && pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM) { - s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType()); - return false; - } - CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, pool); - final Answer answer = agentMgr.easySend(hostId, cmd); - if (answer != null && answer.getResult()) { - return true; - } else { - primaryDataStoreDao.expunge(pool.getId()); - String msg = ""; - if (answer != null) { - msg = "Can not create storage pool through host " + hostId + " due to " + answer.getDetails(); - s_logger.warn(msg); - } else { - msg = "Can not create storage pool through host " + hostId + " due to CreateStoragePoolCommand returns null"; - s_logger.warn(msg); - } - throw new CloudRuntimeException(msg); - } + return true; } + private boolean createStoragePool(long hostId, StoragePool pool) { + s_logger.debug("creating pool " + pool.getName() + " on host " + hostId); + if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem && pool.getPoolType() != StoragePoolType.IscsiLUN + && pool.getPoolType() != StoragePoolType.Iscsi && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint + && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 && pool.getPoolType() != StoragePoolType.RBD + && pool.getPoolType() != StoragePoolType.CLVM) { + s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType()); + return false; + } + CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, pool); + final Answer answer = agentMgr.easySend(hostId, cmd); + if (answer != null && answer.getResult()) { + return true; + } else { + primaryDataStoreDao.expunge(pool.getId()); + String msg = ""; + if (answer != null) { + msg = "Can not create storage pool through host " + hostId + " due to " + answer.getDetails(); + s_logger.warn(msg); + } else { + msg = "Can not create storage pool through host " + hostId + " due to CreateStoragePoolCommand returns null"; + s_logger.warn(msg); + } + throw new CloudRuntimeException(msg); + } + } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { @@ -379,24 +428,24 @@ public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo exis @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { - List hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(hypervisorType, scope.getScopeId()); - s_logger.debug("In createPool. Attaching the pool to each of the hosts."); - List poolHosts = new ArrayList(); - for (HostVO host : hosts) { - try { - storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId()); - poolHosts.add(host); - } catch (Exception e) { - s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e); + List hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(hypervisorType, scope.getScopeId()); + s_logger.debug("In createPool. Attaching the pool to each of the hosts."); + List poolHosts = new ArrayList(); + for (HostVO host : hosts) { + try { + storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId()); + poolHosts.add(host); + } catch (Exception e) { + s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e); + } } - } - if (poolHosts.isEmpty()) { - s_logger.warn("No host can access storage pool " + dataStore + " in this zone."); - primaryDataStoreDao.expunge(dataStore.getId()); - throw new CloudRuntimeException("Failed to create storage pool as it is not accessible to hosts."); - } - dataStoreHelper.attachZone(dataStore, hypervisorType); - return true; + if (poolHosts.isEmpty()) { + s_logger.warn("No host can access storage pool " + dataStore + " in this zone."); + primaryDataStoreDao.expunge(dataStore.getId()); + throw new CloudRuntimeException("Failed to create storage pool as it is not accessible to hosts."); + } + dataStoreHelper.attachZone(dataStore, hypervisorType); + return true; } @Override @@ -421,63 +470,53 @@ public boolean deleteDataStore(DataStore store) { // find the hypervisor where the storage is attached to. HypervisorType hType = null; - if(hostPoolRecords.size() > 0 ){ + if (hostPoolRecords.size() > 0) { hType = getHypervisorType(hostPoolRecords.get(0).getHostId()); } - // Remove the SR associated with the Xenserver - for (StoragePoolHostVO host : hostPoolRecords) { - DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool); - final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd); - - if (answer != null && answer.getResult()) { - // if host is KVM hypervisor then send deleteStoragepoolcmd to all the kvm hosts. - if (HypervisorType.KVM != hType) { - break; - } - } else { - if (answer != null) { - s_logger.error("Failed to delete storage pool: " + answer.getResult()); + StoragePoolVO storagePoolVO = _storagePoolDao.findById(store.getId()); + + if (!(storagePoolVO.isManaged())) { + // Remove the SR associated with the Xenserver + for (StoragePoolHostVO host : hostPoolRecords) { + DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool); + final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd); + + if (answer != null && answer.getResult()) { + // if host is KVM hypervisor then send deleteStoragepoolcmd + // to all the kvm hosts. + if (HypervisorType.KVM != hType) { + break; + } + } else { + if (answer != null) { + s_logger.error("Failed to delete storage pool: " + answer.getResult()); + } } } } - - //delete the Elastistor volume at backend - deleteElastistorVolume(pool); + // delete the Elastistor volume at backend + deleteElastistorVolume(pool, storagePoolVO.isManaged()); return _dataStoreHelper.deletePrimaryDataStore(store); } - private void deleteElastistorVolume(StoragePool pool){ - - String poolip = pool.getHostAddress(); - String esip = null; - String apikey = null; - - // check if apikey and managentip is empty, if so getting it from stragepooldetails - if(ElastistorUtil.s_esIPVAL == "" && ElastistorUtil.s_esAPIKEYVAL == ""){ - Map detailsMap = _storagePoolDetailsDao.listDetailsKeyPairs(pool.getId()); - ElastistorUtil.setElastistorManagementIp(detailsMap.get("esmanagementip")); - esip=ElastistorUtil.s_esIPVAL; - ElastistorUtil.setElastistorApiKey(detailsMap.get("esapikey")); - apikey = ElastistorUtil.s_esAPIKEYVAL; - }else{ - esip = ElastistorUtil.s_esIPVAL; - apikey = ElastistorUtil.s_esAPIKEYVAL; - } + private void deleteElastistorVolume(StoragePool pool, boolean managed) { - boolean status; - try { - status = ElastistorUtil.deleteElastistorVolume(poolip,esip,apikey); - } catch (Throwable e) { - throw new CloudRuntimeException("Failed to delete primary storage on elastistor" + e); - } + String poolid = pool.getUuid(); + boolean status; - if(status == true){ - s_logger.info("deletion of elastistor primary storage complete"); - }else{ - s_logger.error("deletion of elastistor volume failed"); - } + try { + status = ElastistorUtil.deleteElastistorTsm(poolid, managed); + } catch (Throwable e) { + throw new CloudRuntimeException("Failed to delete primary storage on elastistor" + e); + } + + if (status == true) { + s_logger.info("deletion of elastistor primary storage complete"); + } else { + s_logger.error("deletion of elastistor volume failed"); + } } @@ -495,5 +534,57 @@ public boolean migrateToObjectStore(DataStore store) { @Override public void updateStoragePool(StoragePool storagePool, Map details) { + String capacityBytes = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES); + String capacityIops = details.get(PrimaryDataStoreLifeCycle.CAPACITY_IOPS); + + StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePool.getId()); + + try { + if(capacityBytes != null){ + long usedBytes = _capacityMgr.getUsedBytes(storagePoolVO); + + if (Long.valueOf(capacityBytes) < usedBytes) { + throw new CloudRuntimeException("Cannot reduce the number of bytes for this storage pool as it would lead to an insufficient number of bytes"); + } + + UpdateTsmStorageCmdResponse updateTsmStorageCmdResponse = ElastistorUtil.updateElastistorTsmStorage(capacityBytes,storagePool.getUuid()); + + if(updateTsmStorageCmdResponse.getStorage().getId() != null){ + // update the cloudstack db + _storagePoolDao.updateCapacityBytes(storagePool.getId(), Long.valueOf(capacityBytes)); + + s_logger.info("elastistor TSM storage successfully updated"); + }else{ + throw new CloudRuntimeException("Failed to update the storage of Elastistor TSM" + updateTsmStorageCmdResponse.toString()); + } + } + + if(capacityIops != null){ + + long usedIops = _capacityMgr.getUsedIops(storagePoolVO); + + if (Long.valueOf(capacityIops) < usedIops) { + throw new CloudRuntimeException("Cannot reduce the number of IOPS for this storage pool as it would lead to an insufficient number of IOPS"); + } + + UpdateTsmCmdResponse updateTsmCmdResponse = ElastistorUtil.updateElastistorTsmIOPS(capacityIops,storagePool.getUuid()); + + if(updateTsmCmdResponse.getTsm(0).getUuid() != null){ + // update the cloudstack db + _storagePoolDao.updateCapacityIops(storagePool.getId(), Long.valueOf(capacityIops)); + + s_logger.info("elastistor TSM IOPS successfully updated"); + + }else{ + throw new CloudRuntimeException("Failed to update the IOPS of Elastistor TSM" + updateTsmCmdResponse.toString()); + } + } + + } catch (Throwable e) { + throw new CloudRuntimeException("Failed to update the storage pool" + e); + } + + } + } diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java index de4711a140..c68e51d633 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -30,6 +31,9 @@ import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.alert.AlertManager; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -48,10 +52,30 @@ public class ElastistorHostListener implements HypervisorHostListener { StoragePoolHostDao storagePoolHostDao; @Inject PrimaryDataStoreDao primaryStoreDao; + @Inject + PrimaryDataStoreDao storagePoolDao; + @Inject + HostDao _hostDao; @Override public boolean hostConnect(long hostId, long poolId) { StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); + + StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(poolId, hostId); + HostVO host = _hostDao.findById(hostId); + + if (storagePoolHost == null) { + storagePoolHost = new StoragePoolHostVO(poolId, hostId, ""); + + storagePoolHostDao.persist(storagePoolHost); + } + + StoragePoolVO poolVO = storagePoolDao.findById(pool.getId()); + + if(poolVO.isManaged() && (host.getHypervisorType() != HypervisorType.KVM)){ + return true; + } + ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, pool); final Answer answer = agentMgr.easySend(hostId, cmd); @@ -75,8 +99,7 @@ public boolean hostConnect(long hostId, long poolId) { @Override public boolean hostDisconnected(long hostId, long poolId) { - StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost( - poolId, hostId); + StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(poolId, hostId); if (storagePoolHost != null) { storagePoolHostDao.deleteStoragePoolHostDetails(hostId, poolId); diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java index e59108299a..f0b0943964 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java @@ -29,6 +29,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.driver.ElastistorPrimaryDataStoreDriver; import org.apache.cloudstack.storage.datastore.lifecycle.ElastistorPrimaryDataStoreLifeCycle; @@ -41,24 +43,21 @@ import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.component.ComponentContext; +/** + * This is the starting point of the elastistor storage plugin. This bean will + * be detected by Spring container & initialized. This will be one of the + * providers available via {@link DataStoreProviderManagerImpl} object. + */ @Component public class ElastistorPrimaryDataStoreProvider implements PrimaryDataStoreProvider { private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class); - //these classes will be injected by spring + // these classes will be injected by spring private ElastistorPrimaryDataStoreLifeCycle lifecycle; private PrimaryDataStoreDriver driver; private HypervisorHostListener listener; - // these params will be initialized with respective values given in spring-storage-volume-cloudbyte-context.xml bean for the elastistor porpose only. - private String esmanagementip; - private String esapikey; - private String esaccountid; - private String espoolid; - private String esdefaultgateway; - private String essubnet; - private String estntinterface; @Inject AgentManager agentMgr; @@ -70,7 +69,8 @@ public class ElastistorPrimaryDataStoreProvider implements PrimaryDataStoreProvi StoragePoolHostDao storagePoolHostDao; @Inject PrimaryDataStoreDao primaryStoreDao; - + @Inject + ConfigurationDao configurationDao; @Override public String getName() { @@ -95,17 +95,19 @@ public HypervisorHostListener getHostListener() { @Override public boolean configure(Map params) { + s_logger.info("Will configure elastistor's lifecycle, driver, listener & global configurations."); + lifecycle = ComponentContext.inject(ElastistorPrimaryDataStoreLifeCycle.class); driver = ComponentContext.inject(ElastistorPrimaryDataStoreDriver.class); listener = ComponentContext.inject(ElastistorHostListener.class); - ElastistorUtil.setElastistorAccountId(esaccountid); - ElastistorUtil.setElastistorApiKey(esapikey); - ElastistorUtil.setElastistorManagementIp(esmanagementip); - ElastistorUtil.setElastistorPoolId(espoolid); - ElastistorUtil.setElastistorGateway(esdefaultgateway); - ElastistorUtil.setElastistorInterface(estntinterface); - ElastistorUtil.setElastistorSubnet(essubnet); + // insert new cloudbyte global config to the configuration table + setCloudbyteGlobalConfiguration(); + + // set the injected configuration object in elastistor util class too!!! + ElastistorUtil.setConfigurationDao(configurationDao); + + s_logger.info("Successfully configured elastistor's lifecycle, driver, listener & global configurations."); return true; } @@ -118,58 +120,21 @@ public Set getTypes() { return types; } - public String getEspoolid() { - return espoolid; - } - - public void setEspoolid(String espoolid) { - this.espoolid = espoolid; - } - - public String getEsmanagementip() { - return esmanagementip; - } - - public void setEsmanagementip(String esmanagementip) { - this.esmanagementip = esmanagementip; - } - public String getEsaccountid() { - return esaccountid; - } - - public void setEsaccountid(String esaccountid) { - this.esaccountid = esaccountid; - } + private void setCloudbyteGlobalConfiguration() { - public String getEsapikey() { - return esapikey; - } + if (configurationDao.findByName("cloudbyte.management.ip") == null) { + ConfigurationVO managementIP = new ConfigurationVO("Advanced", "DEFAULT", "management-server", + "cloudbyte.management.ip", null, "configure the cloudbyte elasticenter management IP"); - public void setEsapikey(String esapikey) { - this.esapikey = esapikey; - } - - public String getesdefaultgateway() { - return esdefaultgateway; - } + configurationDao.persist(managementIP); + } - public void setesdefaultgateway(String esdefaultgateway) { - this.esdefaultgateway = esdefaultgateway; - } - public String getEssubnet() { - return essubnet; - } - - public void setEssubnet(String essubnet) { - this.essubnet = essubnet; - } - - public String getEstntinterface(){ - return estntinterface; - } + if (configurationDao.findByName("cloudbyte.management.apikey") == null) { + ConfigurationVO managementApiKey = new ConfigurationVO("Advanced", "DEFAULT", "management-server", + "cloudbyte.management.apikey", null, "configure the cloudbyte elasticenter management API KEY"); - public void setEstntinterface(String estntinterface){ - this.estntinterface = estntinterface; + configurationDao.persist(managementApiKey); + } } -} +} \ No newline at end of file diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java index b75d12a6a4..4e9cef3e7f 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java @@ -37,9 +37,12 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.http.auth.InvalidCredentialsException; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; import com.cloud.utils.exception.CloudRuntimeException; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; @@ -54,6 +57,15 @@ public class ElastistorUtil { private static final Logger s_logger = Logger.getLogger(ElastistorUtil.class); + private static ConfigurationDao configurationDao; + + public static ConfigurationDao getConfigurationDao() { + return configurationDao; + } + + public static void setConfigurationDao(ConfigurationDao configurationDao) { + ElastistorUtil.configurationDao = configurationDao; + } /** * Elastistor REST API Param Keys. These should match exactly with the @@ -84,7 +96,7 @@ public class ElastistorUtil { public static final String REST_PARAM_GRACEALLOWED = "graceallowed"; public static final String REST_PARAM_IOPS = "iops"; public static final String REST_PARAM_THROUGHPUT = "throughput"; - public static final String REST_PARAM_MEMLIMIT= "memlimit"; + public static final String REST_PARAM_MEMLIMIT = "memlimit"; public static final String REST_PARAM_NETWORKSPEED = "networkspeed"; public static final String REST_PARAM_TSMID = "tsmid"; public static final String REST_PARAM_DATASETID = "datasetid"; @@ -92,12 +104,13 @@ public class ElastistorUtil { public static final String REST_PARAM_DEDUPLICATION = "deduplication"; public static final String REST_PARAM_COMPRESSION = "compression"; public static final String REST_PARAM_SYNC = "sync"; - public static final String REST_PARAM_MOUNTPOINT= "mountpoint"; + public static final String REST_PARAM_MOUNTPOINT = "mountpoint"; public static final String REST_PARAM_CASESENSITIVITY = "casesensitivity"; public static final String REST_PARAM_UNICODE = "unicode"; - public static final String REST_PARAM_PROTOCOLTYPE= "protocoltype"; + public static final String REST_PARAM_PROTOCOLTYPE = "protocoltype"; public static final String REST_PARAM_AUTHNETWORK = "authnetwork"; public static final String REST_PARAM_MAPUSERSTOROOT = "mapuserstoroot"; + public static final String REST_PARAM_STORAGEID = "storageid"; /** * Constants related to elastistor which are persisted in cloudstack @@ -106,7 +119,7 @@ public class ElastistorUtil { public static final String ES_SUBNET = "essubnet"; public static final String ES_INTERFACE = "estntinterface"; public static final String ES_GATEWAY = "esdefaultgateway"; - public static final String ES_PROVIDER_NAME = "elastistor"; + public static final String ES_PROVIDER_NAME = "CloudByte"; public static final String ES_ACCOUNT_ID = "esAccountId"; public static final String ES_POOL_ID = "esPoolId"; public static final String ES_ACCOUNT_NAME = "esAccountName"; @@ -151,7 +164,6 @@ public class ElastistorUtil { private static final String ES_MAPUSERSTOROOT_VAL = "yes"; private static final String ES_SYNC_VAL = "always"; - /** * Private constructor s.t. its never instantiated. */ @@ -162,20 +174,29 @@ private ElastistorUtil() { /** * This intializes a new jersey restclient for http call with elasticenter */ - public static ElastiCenterClient getElastistorRestClient(String managementIp , String apiKey) { + public static ElastiCenterClient getElastistorRestClient() { ElastiCenterClient restclient = null; try { + String ip = getConfigurationDao().getValue("cloudbyte.management.ip"); + String apikey = getConfigurationDao().getValue("cloudbyte.management.apikey"); + + if (ip == null) { + throw new CloudRuntimeException("set the value of cloudbyte.management.ip in global settings"); + } + if (apikey == null) { + throw new CloudRuntimeException("set the value of cloudbyte.management.apikey in global settings"); + } - restclient = new ElastiCenterClient(managementIp, apiKey); + restclient = new ElastiCenterClient(ip, apikey); } catch (InvalidCredentialsException e) { - throw new CloudRuntimeException("InvalidCredentialsException", e); + throw new CloudRuntimeException("InvalidCredentialsException:" + e.getMessage(), e); } catch (InvalidParameterException e) { - throw new CloudRuntimeException("InvalidParameterException", e); + throw new CloudRuntimeException("InvalidParameterException:" + e.getMessage(), e); } catch (SSLHandshakeException e) { - throw new CloudRuntimeException("SSLHandshakeException", e); + throw new CloudRuntimeException("SSLHandshakeException:" + e.getMessage(), e); } catch (ServiceUnavailableException e) { - throw new CloudRuntimeException("ServiceUnavailableException", e); + throw new CloudRuntimeException("ServiceUnavailableException:" + e.getMessage(), e); } return restclient; } @@ -209,80 +230,143 @@ public static void setElastistorSubnet(String value) { } /** - * This creates a new tenant storage machine(TSM) for the given storagepool ip in elastistor. + * This creates a new Account in Elasticenter for the given Domain Name. + * + * @return */ - public static CreateTsmCmdResponse createElastistorTsm(String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops) throws Throwable { - - String totalthroughput = String.valueOf(capacityIops*4); - String totaliops = String.valueOf(capacityIops); - - String quotasize = convertCapacityBytes(capacityBytes); - - CreateTsmCmd createTsmCmd = new CreateTsmCmd(); - - if ( null != ElastistorUtil.s_esACCOUNTIDVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID, ElastistorUtil.s_esACCOUNTIDVAL); - if ( null != totalthroughput ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSM_THROUGHPUT, totalthroughput); - if ( null != ElastistorUtil.s_esPOOLIDVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID, ElastistorUtil.s_esPOOLIDVAL); - if ( null != storagePoolName ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, "TSM"+storagePoolName); - if ( null != quotasize ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); - if ( null != storageIp ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IPADDRESS, storageIp); - if ( null != ElastistorUtil.s_esSUBNETVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SUBNET, ElastistorUtil.s_esSUBNETVAL); - if ( null != ElastistorUtil.s_esGATEWAYVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GATEWAY, ElastistorUtil.s_esGATEWAYVAL); - if ( null != ElastistorUtil.s_esINTERFACEVAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_INTERFACE, ElastistorUtil.s_esINTERFACEVAL); - if ( null != ElastistorUtil.ES_NOOFCOPIES_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, ElastistorUtil.ES_NOOFCOPIES_VAL); - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); - if ( null != totaliops ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TOTALIOPS, totaliops); - if ( null != ElastistorUtil.ES_LATENCY_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); - if ( null != ElastistorUtil.ES_GRACEALLOWED_VAL ) createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); - - CreateTsmCmdResponse cmdResponse; - - try { - cmdResponse = (CreateTsmCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(createTsmCmd); - - if ( cmdResponse.getTsm().getUuid() == null ){ - throw new CloudRuntimeException("tsm creation failed , contact elatistor admin"); - } - return cmdResponse; - } catch (Exception e) { - throw new CloudRuntimeException("tsm creation failed , contact elatistor admin" + e.toString()); + public static String getElastistorAccountId(String domainName) throws Throwable { + + ListAccountResponse listAccountResponse = ListElastistorAccounts(); + + if (listAccountResponse.getAccounts().getCount() != 0) { + int i; + // check weather a account in elasticenter with given Domain name is + // already present in the list of accounts + for (i = 0; i < listAccountResponse.getAccounts().getCount(); i++) { + if (domainName.equals(listAccountResponse.getAccounts().getAccount(i).getName())) { + return listAccountResponse.getAccounts().getAccount(i).getUuid(); + } + } + + // if no account matches the give Domain Name , create one with the + // Domain name + CreateAccountResponse createAccountResponse = createElastistorAccount(domainName); + return createAccountResponse.getAccount().getUuid(); + + } else { + // if no account is present in the elasticenter create one + CreateAccountResponse createAccountResponse = createElastistorAccount(domainName); + return createAccountResponse.getAccount().getUuid(); + } } + /** + * This creates a new tenant storage machine(TSM) for the given storagepool + * ip in elastistor. + * + * @param domainName + * TODO + */ + public static Tsm createElastistorTsm(String storagePoolName, String storageIp, Long capacityBytes, Long capacityIops, String domainName) throws Throwable { + + String totalthroughput = String.valueOf(capacityIops * 4); + String totaliops = String.valueOf(capacityIops); + + String quotasize = convertCapacityBytes(capacityBytes); + + CreateTsmCmd createTsmCmd = new CreateTsmCmd(); + + if (null != ElastistorUtil.s_esACCOUNTIDVAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID, domainName); + if (null != totalthroughput) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSM_THROUGHPUT, totalthroughput); + if (null != ElastistorUtil.s_esPOOLIDVAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID, ElastistorUtil.s_esPOOLIDVAL); + if (null != storagePoolName) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, storagePoolName); + if (null != quotasize) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); + if (null != storageIp) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IPADDRESS, storageIp); + if (null != ElastistorUtil.s_esSUBNETVAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SUBNET, ElastistorUtil.s_esSUBNETVAL); + if (null != ElastistorUtil.s_esGATEWAYVAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GATEWAY, ElastistorUtil.s_esGATEWAYVAL); + if (null != ElastistorUtil.s_esINTERFACEVAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_INTERFACE, ElastistorUtil.s_esINTERFACEVAL); + if (null != ElastistorUtil.ES_NOOFCOPIES_VAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, ElastistorUtil.ES_NOOFCOPIES_VAL); + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if (null != totaliops) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TOTALIOPS, totaliops); + if (null != ElastistorUtil.ES_LATENCY_VAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if (null != ElastistorUtil.ES_GRACEALLOWED_VAL) + createTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); + + CreateTsmCmdResponse createTsmCmdResponse; + Tsm tsm = null; + try { + createTsmCmdResponse = (CreateTsmCmdResponse) getElastistorRestClient().executeCommand(createTsmCmd); + + if (createTsmCmdResponse.getJobid() == null) { + throw new CloudRuntimeException("tsm creation failed , contact elatistor admin"); + } else { + tsm = queryAsyncTsmJobResult(createTsmCmdResponse.getJobid()); + if (tsm == null) { + throw new CloudRuntimeException("tsm queryAsync failed , contact elatistor admin"); + } + } + return tsm; + } catch (Exception e) { + throw new CloudRuntimeException("tsm creation failed , contact elatistor admin" + e.toString()); + } + } /** * This creates the specified volume on the created tsm. */ - public static CreateVolumeCmdResponse createElastistorVolume(String storagePoolName, CreateTsmCmdResponse cmdResponse, Long capacityBytes, Long capacityIops,String protocoltype, String mountpoint) throws Throwable { + public static FileSystem createElastistorVolume(String volumeName, String tsmid, Long capacityBytes, Long capacityIops, String protocoltype, String mountpoint) throws Throwable { String datasetid; - String tsmid; String qosgroupid; - String VolumeName = storagePoolName; + String VolumeName = volumeName; String totaliops = String.valueOf(capacityIops); - String totalthroughput = String.valueOf(capacityIops*4); + String totalthroughput = String.valueOf(capacityIops * 4); String quotasize = convertCapacityBytes(capacityBytes); AddQosGroupCmd addQosGroupCmd = new AddQosGroupCmd(); - - tsmid = cmdResponse.getTsm().getUuid(); - datasetid = cmdResponse.getTsm().getDatasetid(); - - if (null != VolumeName)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, "QOS_" + VolumeName); - if (null != totaliops)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IOPS, totaliops); - if (null != ElastistorUtil.ES_LATENCY_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); - if (null != ElastistorUtil.ES_BLOCKSIZE_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); - if (null != totalthroughput)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_THROUGHPUT, totalthroughput); - if (null != ElastistorUtil.ES_MEMLIMIT_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MEMLIMIT, ElastistorUtil.ES_MEMLIMIT_VAL); - if (null != ElastistorUtil.ES_NETWORKSPEED_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NETWORKSPEED, ElastistorUtil.ES_NETWORKSPEED_VAL); - if (null != tsmid)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); - if (null != datasetid)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); - if (null != ElastistorUtil.ES_GRACEALLOWED_VAL)addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); - - AddQosGroupCmdResponse addQosGroupCmdResponse = (AddQosGroupCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(addQosGroupCmd); + ListTsmsResponse listTsmsResponse = listTsm(tsmid); + + tsmid = listTsmsResponse.getTsms().getTsm(0).getUuid(); + datasetid = listTsmsResponse.getTsms().getTsm(0).getDatasetid(); + + if (null != VolumeName) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, "QOS_" + VolumeName); + if (null != totaliops) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IOPS, totaliops); + if (null != ElastistorUtil.ES_LATENCY_VAL) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_LATENCY, ElastistorUtil.ES_LATENCY_VAL); + if (null != totalthroughput) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_THROUGHPUT, totalthroughput); + if (null != ElastistorUtil.ES_MEMLIMIT_VAL) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MEMLIMIT, ElastistorUtil.ES_MEMLIMIT_VAL); + if (null != ElastistorUtil.ES_NETWORKSPEED_VAL) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NETWORKSPEED, ElastistorUtil.ES_NETWORKSPEED_VAL); + if (null != tsmid) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); + if (null != datasetid) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); + if (null != ElastistorUtil.ES_GRACEALLOWED_VAL) + addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL); + + AddQosGroupCmdResponse addQosGroupCmdResponse = (AddQosGroupCmdResponse) getElastistorRestClient().executeCommand(addQosGroupCmd); if (addQosGroupCmdResponse.getQoSGroup().getUuid() == null) { @@ -296,45 +380,83 @@ public static CreateVolumeCmdResponse createElastistorVolume(String storagePoolN qosgroupid = addQosGroupCmdResponse.getQoSGroup().getUuid(); - if (null != ElastistorUtil.s_esACCOUNTIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID,ElastistorUtil.s_esACCOUNTIDVAL); - if (null != qosgroupid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QOSGROUPID, qosgroupid); - if (null != tsmid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); - if (null != ElastistorUtil.s_esPOOLIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID,ElastistorUtil.s_esPOOLIDVAL); - if (null != VolumeName)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, VolumeName); - if (null != quotasize)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); - if(protocoltype.equalsIgnoreCase("nfs")){ - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); - } - else{ - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, "512B"); - if ( null != ElastistorUtil.ES_BLOCKSIZE_VAL ) createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, "512B"); - } - if (null != ElastistorUtil.ES_DEDUPLICATION_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DEDUPLICATION, ElastistorUtil.ES_DEDUPLICATION_VAL); - if (null != ElastistorUtil.ES_SYNC_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SYNC, ElastistorUtil.ES_SYNC_VAL); - if (null != ElastistorUtil.ES_COMPRESSION_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_COMPRESSION, ElastistorUtil.ES_COMPRESSION_VAL); - if (null != ElastistorUtil.ES_NOOFCOPIES_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, ElastistorUtil.ES_NOOFCOPIES_VAL); + // if (null != + // ElastistorUtil.s_esACCOUNTIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID,ElastistorUtil.s_esACCOUNTIDVAL); + if (null != qosgroupid) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QOSGROUPID, qosgroupid); + if (null != tsmid) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TSMID, tsmid); + // if (null != + // ElastistorUtil.s_esPOOLIDVAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_POOLID,ElastistorUtil.s_esPOOLIDVAL); + if (null != VolumeName) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NAME, VolumeName); + if (null != quotasize) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_QUOTA_SIZE, quotasize); + if (protocoltype.equalsIgnoreCase("nfs")) { + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, ElastistorUtil.ES_BLOCKSIZE_VAL); + } else { + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_BLOCKSIZE, "512B"); + if (null != ElastistorUtil.ES_BLOCKSIZE_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_RECORDSIZE, "512B"); + } + if (null != ElastistorUtil.ES_DEDUPLICATION_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DEDUPLICATION, ElastistorUtil.ES_DEDUPLICATION_VAL); + if (null != ElastistorUtil.ES_SYNC_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_SYNC, ElastistorUtil.ES_SYNC_VAL); + if (null != ElastistorUtil.ES_COMPRESSION_VAL) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_COMPRESSION, ElastistorUtil.ES_COMPRESSION_VAL); + // if (null != + // ElastistorUtil.ES_NOOFCOPIES_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_NOOFCOPIES, + // ElastistorUtil.ES_NOOFCOPIES_VAL); createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MOUNTPOINT, mountpoint); - if (null != ElastistorUtil.ES_CASESENSITIVITY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_CASESENSITIVITY, ElastistorUtil.ES_CASESENSITIVITY_VAL); - if (null != ElastistorUtil.ES_READONLY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_READONLY, ElastistorUtil.ES_READONLY_VAL); - if (null != datasetid)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); - if (null != ElastistorUtil.ES_UNICODE_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_UNICODE, ElastistorUtil.ES_UNICODE_VAL); + // if (null != + // ElastistorUtil.ES_CASESENSITIVITY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_CASESENSITIVITY, + // ElastistorUtil.ES_CASESENSITIVITY_VAL); + // if (null != + // ElastistorUtil.ES_READONLY_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_READONLY, + // ElastistorUtil.ES_READONLY_VAL); + if (null != datasetid) + createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid); + // if (null != + // ElastistorUtil.ES_UNICODE_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_UNICODE, + // ElastistorUtil.ES_UNICODE_VAL); createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_PROTOCOLTYPE, protocoltype); - if (null != ElastistorUtil.ES_AUTHNETWORK_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_AUTHNETWORK, ElastistorUtil.ES_AUTHNETWORK_VAL); - if (null != ElastistorUtil.ES_MAPUSERSTOROOT_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MAPUSERSTOROOT, ElastistorUtil.ES_MAPUSERSTOROOT_VAL); + // if (null != + // ElastistorUtil.ES_AUTHNETWORK_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_AUTHNETWORK, + // ElastistorUtil.ES_AUTHNETWORK_VAL); + // if (null != + // ElastistorUtil.ES_MAPUSERSTOROOT_VAL)createVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_MAPUSERSTOROOT, + // ElastistorUtil.ES_MAPUSERSTOROOT_VAL); CreateVolumeCmdResponse createVolumeCmdResponse; + FileSystem volume = null; + FileSystem fileSystem = null; + try { - createVolumeCmdResponse = (CreateVolumeCmdResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(createVolumeCmd); + createVolumeCmdResponse = (CreateVolumeCmdResponse) getElastistorRestClient().executeCommand(createVolumeCmd); - if (createVolumeCmdResponse.getFileSystem().getUuid() == null) { + if (createVolumeCmdResponse.getJobid() == null) { throw new CloudRuntimeException("creating volume failed , contact elatistor admin"); } else { - return createVolumeCmdResponse; - } + volume = queryAsyncVolumeJobResult(createVolumeCmdResponse.getJobid()); + if (volume == null) { + throw new CloudRuntimeException("tsm queryAsync failed , contact elatistor admin"); + } else { + if (protocoltype.equalsIgnoreCase("nfs")) { + fileSystem = updateNfsService(volume.getUuid()); + } else { + fileSystem = updateIscsiService(volume.getUuid()); + } + } + } + return fileSystem; } catch (Exception e) { throw new CloudRuntimeException("creating volume failed , contact elatistor admin", e); } @@ -343,107 +465,374 @@ public static CreateVolumeCmdResponse createElastistorVolume(String storagePoolN } + public static FileSystem updateNfsService(String volumeid) throws Throwable { + + FileSystem fileSystem = null; + + String datasetid = updateElastistorNfsVolume(volumeid); + + if (datasetid == null) { + throw new CloudRuntimeException("Updating Nfs Volume Failed"); + } else { + + fileSystem = listVolume(datasetid); + if (fileSystem == null) { + throw new CloudRuntimeException("Volume Creation failed : List Filesystem failed"); + } + } + return fileSystem; + + } + + public static FileSystem updateIscsiService(String volumeid) throws Throwable { + + Volumeiscsioptions volumeiscsioptions = null; + FileSystem fileSystem = null; + String accountId; + + fileSystem = listVolume(volumeid); + + accountId = fileSystem.getAccountid(); + + volumeiscsioptions = updateElastistorIscsiVolume(volumeid, accountId); + + if (volumeiscsioptions == null) { + throw new CloudRuntimeException("Updating Iscsi Volume Failed"); + } else { + + fileSystem = listVolume(volumeiscsioptions.getVolumeid()); + if (fileSystem == null) { + throw new CloudRuntimeException("Volume Creation failed : List Filesystem failed"); + } + } + return fileSystem; + + } + + public static String updateElastistorNfsVolume(String volumeid) throws Throwable { + + NfsServiceCmd nfsServiceCmd = new NfsServiceCmd(); + + nfsServiceCmd.putCommandParameter("datasetid", volumeid); + nfsServiceCmd.putCommandParameter("authnetwork", "all"); + nfsServiceCmd.putCommandParameter("managedstate", "true"); + nfsServiceCmd.putCommandParameter("alldirs", "yes"); + nfsServiceCmd.putCommandParameter("mapuserstoroot", "yes"); + nfsServiceCmd.putCommandParameter("readonly", "no"); + + NfsServiceResponse nfsServiceResponse = (NfsServiceResponse) getElastistorRestClient().executeCommand(nfsServiceCmd); + + if (nfsServiceResponse.getNfsService().getUuid() != null) { + + UpdateControllerCmd controllerCmd = new UpdateControllerCmd(); + + controllerCmd.putCommandParameter("nfsid", nfsServiceResponse.getNfsService().getUuid()); + controllerCmd.putCommandParameter("type", "configurenfs"); + controllerCmd.putCommandParameter("id", nfsServiceResponse.getNfsService().getControllerid()); + + UpdateControllerResponse controllerResponse = (UpdateControllerResponse) getElastistorRestClient().executeCommand(controllerCmd); + + if (controllerResponse.getController().getUuid() != null) { + s_logger.info("updated nfs service to ALL"); + return nfsServiceResponse.getNfsService().getDatasetid(); + } else { + throw new CloudRuntimeException("Updating Nfs Volume Failed"); + } + + } + return null; + } + + public static Volumeiscsioptions updateElastistorIscsiVolume(String volumeid, String accountid) throws Throwable { + + // now listing the iscsi volume service group to get iscsi id + + ListVolumeiSCSIServiceCmd listVolumeiSCSIServiceCmd = new ListVolumeiSCSIServiceCmd(); + + if (null != volumeid) + listVolumeiSCSIServiceCmd.putCommandParameter(ElastistorUtil.REST_PARAM_STORAGEID, volumeid); + + ListVolumeiSCSIServiceResponse volumeiSCSIServiceResponse = (ListVolumeiSCSIServiceResponse) getElastistorRestClient().executeCommand(listVolumeiSCSIServiceCmd); + + String iscsiId = volumeiSCSIServiceResponse.getIscsiVolume().getIscsiVolume(0).getUuid(); + String AG_Id = volumeiSCSIServiceResponse.getIscsiVolume().getIscsiVolume(0).getAg_id(); + + // now listing the initiator group to get initiator id + + ListiSCSIInitiatorCmd initiatorCmd = new ListiSCSIInitiatorCmd(); + + if (null != volumeid) + initiatorCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ACCOUNTID, accountid); + + ListiSCSIInitiatorResponse initiatorResponse = (ListiSCSIInitiatorResponse) getElastistorRestClient().executeCommand(initiatorCmd); + + String intiatorgroup; + String IG_Id; + if (initiatorResponse.getIInitiator().getInterface(0).getInitiatorgroup().equalsIgnoreCase("ALL")) { + IG_Id = initiatorResponse.getIInitiator().getInterface(0).getUuid(); + } else { + IG_Id = initiatorResponse.getIInitiator().getInterface(1).getUuid(); + } + + if (iscsiId != null) { + + UpdateVolumeiSCSIServiceCmd updateVolumeiSCSIServiceCmd = new UpdateVolumeiSCSIServiceCmd(); + + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID, iscsiId); + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter("status", "true"); + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter("igid", IG_Id); + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter("authgroupid", AG_Id); + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter("initialdigest", "Auto"); + if (null != volumeid) + updateVolumeiSCSIServiceCmd.putCommandParameter("queuedepth", "32"); + + UpdateVolumeiSCSIServiceCmdResponse cmdResponse = (UpdateVolumeiSCSIServiceCmdResponse) getElastistorRestClient().executeCommand(updateVolumeiSCSIServiceCmd); + + if (cmdResponse.getVolumeiscsioptions().getVolumeid() == null) { + throw new CloudRuntimeException("Updating Iscsi Volume Failed"); + } + return cmdResponse.getVolumeiscsioptions(); + } + return null; + + } + /** * This deletes both the volume and the tsm in elastistor. */ - public static boolean deleteElastistorVolume(String poolip, String esmanagementip, String esapikey) throws Throwable { + public static boolean deleteElastistorTsm(String tsmid, boolean managed) throws Throwable { - String esvolumeid = null; - String estsmid = null; + if (!managed) { - ListTsmsResponse listTsmsResponse = listTsm(poolip); + s_logger.info("elastistor pool is NOT a managed storage , hence deleting the volume then tsm"); - if (listTsmsResponse.getTsmsCount() != 0) { - int i; + String esvolumeid = null; + String estsmid = null; - for (i = 0; i < listTsmsResponse.getTsmsCount(); i++) { - if (poolip.compareTo(listTsmsResponse.getTsms().getTsm(i).getIpaddress()) == 0) { - estsmid = listTsmsResponse.getTsms().getTsm(i).getUuid(); - break; - } - } + ListTsmsResponse listTsmsResponse = listTsm(tsmid); - if (listTsmsResponse.getTsms().getTsm(i).checkvolume()) { - esvolumeid = listTsmsResponse.getTsms().getTsm(i).getVolumeProperties(0).getid(); - DeleteVolumeResponse deleteVolumeResponse = deleteVolume(esvolumeid, null); + if (listTsmsResponse.getTsmsCount() != 0) { - if (deleteVolumeResponse != null) { - String jobid = deleteVolumeResponse.getJobId(); - int jobstatus = queryAsyncJobResult(jobid); + if (listTsmsResponse.getTsms().getTsm(0).checkvolume()) { + esvolumeid = listTsmsResponse.getTsms().getTsm(0).getVolumeProperties(0).getid(); + DeleteVolumeResponse deleteVolumeResponse = deleteVolume(esvolumeid, null); - if (jobstatus == 1) { - s_logger.info("elastistor volume successfully deleted"); - } else { - s_logger.info("now farce deleting the volume"); + if (deleteVolumeResponse != null) { + String jobid = deleteVolumeResponse.getJobId(); + int jobstatus = queryAsyncJobResult(jobid); - while (jobstatus != 1) { - DeleteVolumeResponse deleteVolumeResponse1 = deleteVolume(esvolumeid, "true"); + if (jobstatus == 1) { + s_logger.info("elastistor volume successfully deleted"); + } else { + s_logger.info("now farce deleting the volume"); - if (deleteVolumeResponse1 != null) { - String jobid1 = deleteVolumeResponse1.getJobId(); - jobstatus = queryAsyncJobResult(jobid1); + while (jobstatus != 1) { + DeleteVolumeResponse deleteVolumeResponse1 = deleteVolume(esvolumeid, "true"); + + if (deleteVolumeResponse1 != null) { + String jobid1 = deleteVolumeResponse1.getJobId(); + jobstatus = queryAsyncJobResult(jobid1); + } } + s_logger.info("elastistor volume successfully deleted"); } - s_logger.info("elastistor volume successfully deleted"); } + } else { + s_logger.info("no volume present in on the given tsm"); } - } else { - s_logger.info("no volume present in on the given tsm"); + } - s_logger.info("now trying to delete elastistor tsm"); + } - if (estsmid != null) { - DeleteTsmCmd deleteTsmCmd = new DeleteTsmCmd(); - deleteTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID,estsmid); - DeleteTsmResponse deleteTsmResponse = (DeleteTsmResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(deleteTsmCmd); + s_logger.info("now trying to delete elastistor tsm"); - if (deleteTsmResponse != null) { - String jobstatus = deleteTsmResponse.getJobStatus(); + if (tsmid != null) { + DeleteTsmCmd deleteTsmCmd = new DeleteTsmCmd(); + deleteTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID, tsmid); + DeleteTsmResponse deleteTsmResponse = (DeleteTsmResponse) getElastistorRestClient().executeCommand(deleteTsmCmd); - if (jobstatus.equalsIgnoreCase("true")) { - s_logger.info("deletion of elastistor tsm successful"); - return true; - } else { - s_logger.info("failed to delete elastistor tsm"); - return false; - } + if (deleteTsmResponse != null) { + String jobstatus = deleteTsmResponse.getJobStatus(); + + if (jobstatus.equalsIgnoreCase("true")) { + s_logger.info("deletion of elastistor tsm successful"); + return true; } else { - s_logger.info("elastistor tsm id not present"); + s_logger.info("failed to delete elastistor tsm"); + return false; } + } else { + s_logger.info("elastistor tsm id not present"); } - else { - s_logger.error("no volume is present in the tsm"); + } + s_logger.info("tsm id is null"); + return false; + + /* + * else { s_logger.error("no volume is present in the tsm"); } } else { + * s_logger.error( + * "List tsm failed, no tsm present in the eastistor for the given IP " + * ); return false; } return false; + */ + + } + + public static boolean deleteElastistorVolume(String esvolumeid) throws Throwable { + + FileSystem fileSystem = listVolume(esvolumeid); + + if (fileSystem != null) { + DeleteVolumeResponse deleteVolumeResponse = deleteVolume(esvolumeid, null); + + if (deleteVolumeResponse != null) { + String jobid = deleteVolumeResponse.getJobId(); + int jobstatus = queryAsyncJobResult(jobid); + + if (jobstatus == 1) { + s_logger.info("elastistor volume successfully deleted"); + return true; + } else { + s_logger.info("now force deleting the volume"); + + while (jobstatus != 1) { + DeleteVolumeResponse deleteVolumeResponse1 = deleteVolume(esvolumeid, "true"); + + if (deleteVolumeResponse1 != null) { + String jobid1 = deleteVolumeResponse1.getJobId(); + jobstatus = queryAsyncJobResult(jobid1); + } + } + s_logger.info("elastistor volume successfully deleted"); + return true; + } + } else { + s_logger.info("the given volume is not present on elastistor, datasetrespone is NULL"); + return false; } } else { - s_logger.error("List tsm failed, no tsm present in the eastistor for the given IP "); + s_logger.info("the given volume is not present on elastistor"); return false; } - return false; + + } + + /** + * This give a json response containing the list of Interface's in + * elastistor. + */ + + public static ListInterfacesResponse ListElastistorInterfaces(String controllerid) throws Throwable { + + ListInterfacesCmd listInterfacesCmd = new ListInterfacesCmd(); + listInterfacesCmd.putCommandParameter("controllerid", controllerid); + + ListInterfacesResponse interfacesResponse = (ListInterfacesResponse) getElastistorRestClient().executeCommand(listInterfacesCmd); + + if (interfacesResponse != null && interfacesResponse.getInterfaces() != null) { + return interfacesResponse; + } else { + throw new CloudRuntimeException("There are no elastistor interfaces."); + } + } + + /** + * This give a json response containing the list of Accounts's in + * elastistor. + */ + + public static CreateAccountResponse createElastistorAccount(String domainName) throws Throwable { + + CreateAccountCmd createAccountCmd = new CreateAccountCmd(); + + createAccountCmd.putCommandParameter("name", domainName); + CreateAccountResponse createAccountResponse = (CreateAccountResponse) getElastistorRestClient().executeCommand(createAccountCmd); + + if (createAccountResponse != null) { + return createAccountResponse; + } else { + throw new CloudRuntimeException("Creating Elastistor Account failed"); + } + + } + + /** + * This give a json response containing the list of Accounts's in + * elastistor. + */ + + public static ListAccountResponse ListElastistorAccounts() throws Throwable { + + ListAccountsCmd listAccountsCmd = new ListAccountsCmd(); + + ListAccountResponse accountResponse = (ListAccountResponse) getElastistorRestClient().executeCommand(listAccountsCmd); + + if (accountResponse != null) { + return accountResponse; + } else { + throw new CloudRuntimeException("List Elastistor Account failed"); + } + + } + + /** + * This give a json response containing the list of Pool's in elastistor. + */ + + public static ListPoolsResponse ListElastistorPools() throws Throwable { + + ListPoolsCmd listPoolsCmd = new ListPoolsCmd(); + + ListPoolsResponse listPoolsResponse = (ListPoolsResponse) getElastistorRestClient().executeCommand(listPoolsCmd); + + if (listPoolsResponse != null) { + return listPoolsResponse; + } else { + throw new CloudRuntimeException("List Elastistor pool failed"); + } } /** * This give a json response containing the list of tsm's in elastistor. */ - private static ListTsmsResponse listTsm(String poolip) throws Throwable { + private static ListTsmsResponse listTsm(String uuid) throws Throwable { ListTsmCmd listTsmCmd = new ListTsmCmd(); - listTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IPADDRESS,poolip); + listTsmCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID, uuid); - ListTsmsResponse listTsmsResponse = (ListTsmsResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(listTsmCmd); + ListTsmsResponse listTsmsResponse = (ListTsmsResponse) getElastistorRestClient().executeCommand(listTsmCmd); return listTsmsResponse; } - private static DeleteVolumeResponse deleteVolume(String esvolumeid, String forcedelete)throws Throwable { + /** + * This give a json response containing the list of Volume in elastistor. + */ + public static FileSystem listVolume(String uuid) throws Throwable { + + ListFileSystemCmd listFileSystemCmd = new ListFileSystemCmd(); + + listFileSystemCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID, uuid); + + ListFileSystemResponse listFileSystemResponse = (ListFileSystemResponse) getElastistorRestClient().executeCommand(listFileSystemCmd); + + return listFileSystemResponse.getFilesystems().getFileSystem(0); + } + + private static DeleteVolumeResponse deleteVolume(String esvolumeid, String forcedelete) throws Throwable { DeleteVolumeCmd deleteVolumeCmd = new DeleteVolumeCmd(); - deleteVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID,esvolumeid); + deleteVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_ID, esvolumeid); deleteVolumeCmd.putCommandParameter(ElastistorUtil.REST_PARAM_FORECEDELETE, forcedelete); - DeleteVolumeResponse deleteVolumeResponse = (DeleteVolumeResponse) getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL).executeCommand(deleteVolumeCmd); + DeleteVolumeResponse deleteVolumeResponse = (DeleteVolumeResponse) getElastistorRestClient().executeCommand(deleteVolumeCmd); return deleteVolumeResponse; } @@ -451,7 +840,7 @@ private static DeleteVolumeResponse deleteVolume(String esvolumeid, String force private static int queryAsyncJobResult(String jobid) throws Throwable { QueryAsyncJobResultCmd asyncJobResultCmd = new QueryAsyncJobResultCmd(); - ElastiCenterClient restclient = getElastistorRestClient(s_esIPVAL, s_esAPIKEYVAL); + ElastiCenterClient restclient = getElastistorRestClient(); asyncJobResultCmd.putCommandParameter(ElastistorUtil.REST_PARAM_JOBID, jobid); @@ -472,20 +861,76 @@ private static int queryAsyncJobResult(String jobid) throws Throwable { } - /** - * this method converts the long capacitybytes to string format, which is feasible for elastistor rest api - * 214748364800 = 200G. + private static Tsm queryAsyncTsmJobResult(String jobid) throws Throwable { + + QueryAsyncJobResultCmd asyncJobResultCmd = new QueryAsyncJobResultCmd(); + ElastiCenterClient restclient = getElastistorRestClient(); + + asyncJobResultCmd.putCommandParameter(ElastistorUtil.REST_PARAM_JOBID, jobid); + + QueryAsyncJobResultResponse asyncJobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + if (asyncJobResultResponse != null) { + int jobstatus = asyncJobResultResponse.getAsync().getJobStatus(); + Tsm tsm = null; + while (jobstatus == 0) { + + asyncJobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + jobstatus = asyncJobResultResponse.getAsync().getJobStatus(); + + } + if (jobstatus == 1) { + tsm = asyncJobResultResponse.getAsync().getJobResult().getTsm(); + return tsm; + } + } + return null; + + } + + private static FileSystem queryAsyncVolumeJobResult(String jobid) throws Throwable { + + QueryAsyncJobResultCmd asyncJobResultCmd = new QueryAsyncJobResultCmd(); + ElastiCenterClient restclient = getElastistorRestClient(); + + asyncJobResultCmd.putCommandParameter(ElastistorUtil.REST_PARAM_JOBID, jobid); + + QueryAsyncJobResultResponse asyncJobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + if (asyncJobResultResponse != null) { + int jobstatus = asyncJobResultResponse.getAsync().getJobStatus(); + FileSystem volume = null; + while (jobstatus == 0) { + + asyncJobResultResponse = (QueryAsyncJobResultResponse) restclient.executeCommand(asyncJobResultCmd); + + jobstatus = asyncJobResultResponse.getAsync().getJobStatus(); + + } + if (jobstatus == 1) { + volume = asyncJobResultResponse.getAsync().getJobResult().getVolume(); + return volume; + } + } + return null; + + } + + /** + * this method converts the long capacitybytes to string format, which is + * feasible for elastistor rest api 214748364800 = 200G. */ - private static String convertCapacityBytes(Long capacityBytes){ + private static String convertCapacityBytes(Long capacityBytes) { String quotasize; - if((1099511627776L)>capacityBytes &&(capacityBytes>(1073741824))){ - return quotasize =(String.valueOf(capacityBytes/(1024*1024*1024))+"G"); - }else - { int temp1 = (int) (capacityBytes/(1024*1024*1024)); - int temp2 = temp1/1024; - return quotasize =(String.valueOf(temp2)+"T"); + if ((1099511627776L) > capacityBytes && (capacityBytes > (1073741824))) { + return quotasize = (String.valueOf(capacityBytes / (1024 * 1024 * 1024)) + "G"); + } else { + int temp1 = (int) (capacityBytes / (1024 * 1024 * 1024)); + int temp2 = temp1 / 1024; + return quotasize = (String.valueOf(temp2) + "T"); } } @@ -500,8 +945,8 @@ static interface ElastiCenterCommand { * Utility method to allow the client to validate the input parameters * before sending to the ElastiCenter. * - * This command will be executed by the ElastiCenterClient only this method - * returns true. + * This command will be executed by the ElastiCenterClient only this + * method returns true. */ public boolean validate(); @@ -509,7 +954,8 @@ static interface ElastiCenterCommand { * Returns the query parameters that have to be passed to execute the * command. * - * Returns null if there are query parameters associated with the command + * Returns null if there are query parameters associated with the + * command */ public MultivaluedMap getCommandParameters(); @@ -573,11 +1019,13 @@ public Object getResponseObject() { } -/** - * this is a rest client which is used to call the http rest calls to elastistor - * @author punith - * - */ + /** + * this is a rest client which is used to call the http rest calls to + * elastistor + * + * @author punith + * + */ private static final class ElastiCenterClient { public static boolean debug = false; @@ -597,38 +1045,36 @@ private static final class ElastiCenterClient { private String queryparamapikey = "apikey"; private String queryparamresponse = "response"; - public ElastiCenterClient(String address, String key)throws InvalidCredentialsException, InvalidParameterException,SSLHandshakeException, ServiceUnavailableException { + public ElastiCenterClient(String address, String key) throws InvalidCredentialsException, InvalidParameterException, SSLHandshakeException, ServiceUnavailableException { this.elastiCenterAddress = address; this.apiKey = key; this.initialize(); } - public void initialize() throws InvalidParameterException, - SSLHandshakeException, InvalidCredentialsException, - ServiceUnavailableException { + public void initialize() throws InvalidParameterException, SSLHandshakeException, InvalidCredentialsException, ServiceUnavailableException { if (apiKey == null || apiKey.trim().isEmpty()) { throw new InvalidParameterException("Unable to initialize. Please specify a valid API Key."); } if (elastiCenterAddress == null || elastiCenterAddress.trim().isEmpty()) { - // TODO : Validate the format, like valid IP address or hostname. + // TODO : Validate the format, like valid IP address or + // hostname. throw new InvalidParameterException("Unable to initialize. Please specify a valid ElastiCenter IP Address or Hostname."); } if (ignoreSSLCertificate) { - // Create a trust manager that does not validate certificate chains + // Create a trust manager that does not validate certificate + // chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } - public void checkClientTrusted(X509Certificate[] certs, - String authType) { + public void checkClientTrusted(X509Certificate[] certs, String authType) { } - public void checkServerTrusted(X509Certificate[] certs, - String authType) { + public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; @@ -662,15 +1108,11 @@ public boolean verify(String urlHostName, SSLSession session) { } else if (t instanceof ServiceUnavailableException) { throw (ServiceUnavailableException) t; } else if (t.getCause() instanceof SSLHandshakeException) { - throw new SSLHandshakeException( - "Unable to initialize. An untrusted SSL Certificate was received from " - + elastiCenterAddress - + ". Please verify your truststore or configure ElastiCenterClient to skip the SSL Validation. "); + throw new SSLHandshakeException("Unable to initialize. An untrusted SSL Certificate was received from " + elastiCenterAddress + + ". Please verify your truststore or configure ElastiCenterClient to skip the SSL Validation. "); } else if (t.getCause() instanceof ConnectException) { - throw new ServiceUnavailableException( - "Unable to initialize. Failed to connect to " - + elastiCenterAddress - + ". Please verify the IP Address, Network Connectivity and ensure that Services are running on the ElastiCenter Server. "); + throw new ServiceUnavailableException("Unable to initialize. Failed to connect to " + elastiCenterAddress + + ". Please verify the IP Address, Network Connectivity and ensure that Services are running on the ElastiCenter Server. "); } throw new ServiceUnavailableException("Unable to initialize. Please contact your ElastiCenter Administrator. Exception " + t.getMessage()); } @@ -683,10 +1125,10 @@ public boolean verify(String urlHostName, SSLSession session) { } public Object executeCommand(ElastiCenterCommand cmd) throws Throwable { - return executeCommand(cmd.getCommandName(), cmd.getCommandParameters(),cmd.getResponseObject()); + return executeCommand(cmd.getCommandName(), cmd.getCommandParameters(), cmd.getResponseObject()); } - public Object executeCommand(String command,MultivaluedMap params, Object responeObj) throws Throwable { + public Object executeCommand(String command, MultivaluedMap params, Object responeObj) throws Throwable { if (!initialized) { throw new IllegalStateException("Error : ElastiCenterClient is not initialized."); @@ -713,7 +1155,7 @@ public Object executeCommand(String command,MultivaluedMap param } } if (debug) { - System.out.println("Command Sent " + command + " : "+ queryParams); + System.out.println("Command Sent " + command + " : " + queryParams); } ClientResponse response = webResource.queryParams(queryParams).accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); @@ -746,8 +1188,8 @@ public Object executeCommand(String command,MultivaluedMap param } /** - * these are the list of Elastistor rest commands being called from the plugin. - * + * these are the list of Elastistor rest commands being called from the + * plugin. */ private static final class CreateTsmCmd extends BaseCommand { @@ -777,54 +1219,151 @@ public CreateVolumeCmd() { } - private static final class DeleteTsmCmd extends BaseCommand { + private static final class ListVolumeiSCSIServiceCmd extends BaseCommand { + + public ListVolumeiSCSIServiceCmd() { + super("listVolumeiSCSIService", new ListVolumeiSCSIServiceResponse()); - public DeleteTsmCmd() { - super("deleteTsm", new DeleteTsmResponse()); } } - private static final class DeleteVolumeCmd extends BaseCommand { + private static final class ListiSCSIInitiatorCmd extends BaseCommand { + + public ListiSCSIInitiatorCmd() { + super("listiSCSIInitiator", new ListiSCSIInitiatorResponse()); - public DeleteVolumeCmd() { - super("deleteFileSystem", new DeleteVolumeResponse()); } } - private static final class QueryAsyncJobResultCmd extends BaseCommand { + private static final class NfsServiceCmd extends BaseCommand { - public QueryAsyncJobResultCmd() { - super("queryAsyncJobResult", new QueryAsyncJobResultResponse()); - } + public NfsServiceCmd() { + super("nfsService", new NfsServiceResponse()); - } + } - private static final class ListTsmCmd extends BaseCommand { + } - public ListTsmCmd() { - super("listTsm", new ListTsmsResponse()); - } + private static final class UpdateControllerCmd extends BaseCommand { - } + public UpdateControllerCmd() { + super("updateController", new UpdateControllerResponse()); - /** - * these are the list of Elastistor rest json response classes for parsing the json response sent by elastistor. - * - */ - public static final class CreateTsmCmdResponse { + } - @SerializedName("createTsmResponse") - private TsmWrapper tsmWrapper; + } + + private static final class UpdateVolumeiSCSIServiceCmd extends BaseCommand { + + public UpdateVolumeiSCSIServiceCmd() { + super("updateVolumeiSCSIService", new UpdateVolumeiSCSIServiceCmdResponse()); - public Tsm getTsm() { - return tsmWrapper.getTsm(); } } - public static final class Tsm { + private static final class DeleteTsmCmd extends BaseCommand { + + public DeleteTsmCmd() { + super("deleteTsm", new DeleteTsmResponse()); + } + + } + + private static final class DeleteVolumeCmd extends BaseCommand { + + public DeleteVolumeCmd() { + super("deleteFileSystem", new DeleteVolumeResponse()); + } + + } + + private static final class QueryAsyncJobResultCmd extends BaseCommand { + + public QueryAsyncJobResultCmd() { + super("queryAsyncJobResult", new QueryAsyncJobResultResponse()); + } + + } + + private static final class ListTsmCmd extends BaseCommand { + + public ListTsmCmd() { + super("listTsm", new ListTsmsResponse()); + } + + } + + private static final class ListFileSystemCmd extends BaseCommand { + + public ListFileSystemCmd() { + super("listFileSystem", new ListFileSystemResponse()); + } + + } + + private static final class ListAccountsCmd extends BaseCommand { + + public ListAccountsCmd() { + super("listAccount", new ListAccountResponse()); + } + + } + + private static final class CreateAccountCmd extends BaseCommand { + + public CreateAccountCmd() { + super("createAccount", new CreateAccountResponse()); + } + + } + + private static final class ListInterfacesCmd extends BaseCommand { + + public ListInterfacesCmd() { + super("listSharedNICs", new ListInterfacesResponse()); + } + + } + + private static final class ListPoolsCmd extends BaseCommand { + + public ListPoolsCmd() { + super("listHAPool", new ListPoolsResponse()); + } + + } + + /** + * these are the list of Elastistor rest json response classes for parsing + * the json response sent by elastistor. + * + */ + public static final class CreateTsmCmdResponse { + + @SerializedName("addTsmResponse") + private JobId jobId; + + public String getJobid() { + return jobId.getJobid(); + } + + public String getJobStatus() { + return jobId.getJobStatus(); + } + + @SerializedName("createTsmResponse") + private TsmWrapper tsmWrapper; + + public Tsm getTsm() { + return tsmWrapper.getTsm(); + } + + } + + public static final class Tsm { @SerializedName("id") private String uuid; @@ -859,10 +1398,9 @@ public String getDatasetid() { public boolean checkvolume() { - if(volumeProperties != null){ + if (volumeProperties != null) { return true; - } - else{ + } else { return false; } @@ -970,8 +1508,152 @@ public String getLatency() { } } + public static final class UpdateVolumeiSCSIServiceCmdResponse { + + @SerializedName("updatingvolumeiscsidetails") + private VolumeiSCSIServiceWrapper volumeiSCSIServiceWrapper; + + public Volumeiscsioptions getVolumeiscsioptions() { + + return volumeiSCSIServiceWrapper.getVolumeiscsioptions(); + } + + } + + public static final class VolumeiSCSIServiceWrapper { + + @SerializedName("viscsioptions") + private Volumeiscsioptions viscsioptions; + + public Volumeiscsioptions getVolumeiscsioptions() { + return viscsioptions; + } + + } + + public static final class Volumeiscsioptions { + + @SerializedName("id") + private String uuid; + + @SerializedName("volume_id") + private String volumeid; + + @SerializedName("iqnname") + private String iqnname; + + public String getUuid() { + return uuid; + } + + public String getVolumeid() { + return volumeid; + } + + public String getIqn() { + return iqnname; + } + + } + + public static final class NfsServiceResponse { + + @SerializedName("nfsserviceprotocolresponse") + private NfsServiceWrapper nfsServiceWrapper; + + public NfsService getNfsService() { + + return nfsServiceWrapper.getNfsservice(); + } + + } + + public static final class NfsServiceWrapper { + + @SerializedName("nfs") + private NfsService nfsService; + + public NfsService getNfsservice() { + return nfsService; + } + + } + + public static final class NfsService { + + @SerializedName("id") + private String uuid; + + @SerializedName("STORAGEID") + private String datasetid; + + @SerializedName("controllerid") + private String controllerid; + + @SerializedName("authnetwork") + private String authnetwork; + + public String getUuid() { + return uuid; + } + + public String getDatasetid() { + return datasetid; + } + + public String getControllerid() { + return controllerid; + } + + public String getAuthnetwork() { + return authnetwork; + } + + } + + public static final class UpdateControllerResponse { + + @SerializedName("updateControllerResponse") + private UpdateControllerWrapper controllerWrapper; + + public Controller getController() { + + return controllerWrapper.getController(); + } + + } + + public static final class UpdateControllerWrapper { + + @SerializedName("controller") + private Controller controller; + + public Controller getController() { + return controller; + } + + } + + public static final class Controller { + + @SerializedName("id") + private String uuid; + + public String getUuid() { + return uuid; + } + + } + public static final class CreateVolumeCmdResponse { + @SerializedName("createvolumeresponse") + private JobId jobId; + + public String getJobid() { + return jobId.getJobid(); + } + @SerializedName("adddatasetresponse") private FileSystemWrapper fileSystemWrapper; @@ -1004,33 +1686,86 @@ public static final class FileSystem { @SerializedName("quota") private String quota; - @SerializedName("timestamp") - private String timestamp; + @SerializedName("accountid") + private String accountid; @SerializedName("iqnname") private String iqnname; - @SerializedName("filesystemproperties") - private HashMap[] filesystemproperties; + @SerializedName("nfsenabled") + private String nfsenabled; + + @SerializedName("iscsienabled") + private String iscsienabled; + + @SerializedName("path") + private String path; + + @SerializedName("groupid") + private String groupid; + + @SerializedName("compression") + private String compression; + + @SerializedName("sync") + private String sync; + + @SerializedName("deduplication") + private String deduplication; + + @SerializedName("graceallowed") + private String graceallowed; + + public String getCompression() { + return compression; + } + + public String getSync() { + return sync; + } + + public String getDeduplication() { + return deduplication; + } + + public String getGraceallowed() { + return graceallowed; + } public String getUuid() { - return uuid; - } + return uuid; + } + + public String getQosGroupid() { + return groupid; + } public String getName() { - return name; + return name; + } + + public String getNfsenabled() { + return nfsenabled; + } + + public String getIscsienabled() { + return iscsienabled; + } + + public String getPath() { + return path; } public String getIqn() { - return iqnname; + return iqnname; } public String getQuota() { - return quota; + return quota; } - public String getTimestamp() { - return timestamp; + public String getAccountid() { + return accountid; } } @@ -1054,6 +1789,27 @@ public static final class JobId { @SerializedName("success") private String jobStatus; + @SerializedName("jobresult") + private JobResult jobresult; + + @SerializedName("tsm") + private Tsm tsm; + + @SerializedName("storage") + private FileSystem volume; + + public Tsm getTsm() { + return tsm; + } + + public FileSystem getVolume() { + return volume; + } + + public JobResult getJobResult() { + return jobresult; + } + public String getJobid() { return jobid; } @@ -1064,93 +1820,789 @@ public String getJobStatus() { } - public static final class DeleteVolumeResponse { + public static final class JobResult { + + @SerializedName("tsm") + private Tsm tsm; + + @SerializedName("storage") + private FileSystem volume; + + public Tsm getTsm() { + return tsm; + } + + public FileSystem getVolume() { + return volume; + } + + } + + public static final class DeleteVolumeResponse { - @SerializedName("deleteFileSystemResponse") - private JobId jobId; + @SerializedName("deleteFileSystemResponse") + private JobId jobId; + + public String getJobId() { + return jobId.getJobid(); + } + + } + + public static final class ListCapabilitiesResponse { + + @SerializedName("listcapabilitiesresponse") + private Capabilities capabilities; + + public Capabilities getCapabilities() { + return capabilities; + } + } + + public static final class ListFileSystemResponse { + + @SerializedName("listFilesystemResponse") + private Filesystems filesystems; - public String getJobId() { - return jobId.getJobid(); - } + public int getFilesystemCount() { + return filesystems.getCount(); + } - } + public Filesystems getFilesystems() { + return filesystems; + } + } - public static final class ListCapabilitiesResponse { + public static final class Filesystems { - @SerializedName("listcapabilitiesresponse") - private Capabilities capabilities; + @SerializedName("count") + private int count; - public Capabilities getCapabilities() { - return capabilities; - } - } + @SerializedName("filesystem") + private FileSystem[] fileSystems; - public static final class ListTsmsResponse { + public int getCount() { + return count; + } - @SerializedName("listTsmResponse") - private Tsms tsms; + public FileSystem getFileSystem(int i) { + return fileSystems[i]; + } + } - public int getTsmsCount() { - return tsms.getCount(); - } + public static final class ListPoolsResponse { - public Tsms getTsms() { - return tsms; - } - } + @SerializedName("listHAPoolResponse") + private Pools pools; - public static final class Tsms { + public Pools getPools() { + return pools; + } + } - @SerializedName("count") - private int count; + public static final class Pools { - @SerializedName("listTsm") - private Tsm[] tsms; + @SerializedName("hapool") + private Pool[] pool; - public int getCount() { - return count; - } + @SerializedName("count") + private int count; - public Tsm getTsm(int i) { - return tsms[i]; - } - } + public Pool getPool(int i) { + return pool[i]; + } - public static final class QueryAsyncJobResultResponse { + public int getCount() { + return count; + } + } - @SerializedName("queryasyncjobresultresponse") - private Async async; + public static final class Pool { - public Async getAsync() { - return async; - } - } + @SerializedName("id") + private String uuid; - public static final class Async { + @SerializedName("name") + private String name; - @SerializedName("jobstatus") - private int jobstatus; + @SerializedName("currentAvailableSpace") + private String currentAvailableSpace; - @SerializedName("cmd") - private String cmd; + @SerializedName("availIOPS") + private String availIOPS; - public int getJobStatus() { - return jobstatus; - } + @SerializedName("status") + private String state; - public String getCmd() { - return cmd; - } + @SerializedName("controllerid") + private String controllerid; - } + @SerializedName("gateway") + private String gateway; - public static final class Capabilities { + public String getControllerid() { + return controllerid; + } - @SerializedName("capability") - private HashMap capabilites; + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + + public String getAvailableSpace() { + return currentAvailableSpace; + } + + public String getAvailIOPS() { + return availIOPS; + } + + public String getState() { + return state; + } + + public String getGateway() { + return gateway; + } + } + + public static final class ListInterfacesResponse { + + @SerializedName("listSharedNICsResponse") + private Interfaces interfaces; + + public Interfaces getInterfaces() { + return interfaces; + } + } + + public static final class Interfaces { + + @SerializedName("nic") + private Interface[] interfaces; + + @SerializedName("count") + private int count; + + public Interface getInterface(int i) { + return interfaces[i]; + } + + public int getCount() { + return count; + } + } + + public static final class Interface { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("status") + private String status; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + + public String getStatus() { + return status; + } + } + + public static final class ListiSCSIInitiatorResponse { + + @SerializedName("listInitiatorsResponse") + private Initiators initiators; + + public Initiators getIInitiator() { + return initiators; + } + } + + public static final class Initiators { + + @SerializedName("initiator") + private Initiator[] initiators; + + @SerializedName("count") + private int count; + + public Initiator getInterface(int i) { + return initiators[i]; + } + + public int getCount() { + return count; + } + } + + public static final class Initiator { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("initiatorgroup") + private String initiatorgroup; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + + public String getInitiatorgroup() { + return initiatorgroup; + } + } + + public static final class ListAccountResponse { + + @SerializedName("listAccountResponse") + private Accounts accounts; + + public Accounts getAccounts() { + return accounts; + } + } + + public static final class Accounts { + + @SerializedName("account") + private Account[] Accounts; + + @SerializedName("count") + private int count; + + public Account getAccount(int i) { + return Accounts[i]; + } + + public int getCount() { + return count; + } + } + + public static final class CreateAccountResponse { + + @SerializedName("createaccountresponse") + private Accounts2 accounts; + + public Account getAccount() { + return accounts.getAccount(); + } + } + + public static final class Accounts2 { + + @SerializedName("account2") + private Account Account; + + @SerializedName("count") + private int count; + + public Account getAccount() { + return Account; + } + + public int getCount() { + return count; + } + } + + public static final class Account { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + public String getUuid() { + return uuid; + } + + public String getName() { + return name; + } + } + + public static final class ListTsmsResponse { + + @SerializedName("listTsmResponse") + private Tsms tsms; + + public int getTsmsCount() { + return tsms.getCount(); + } + + public Tsms getTsms() { + return tsms; + } + } + + public static final class Tsms { + + @SerializedName("count") + private int count; + + @SerializedName("listTsm") + private Tsm[] tsms; + + public int getCount() { + return count; + } + + public Tsm getTsm(int i) { + return tsms[i]; + } + } + + public static final class ListVolumeiSCSIServiceResponse { + + @SerializedName("listVolumeiSCSIServiceResponse") + private IscsiVolumeService iscsiVolumes; + + public int getVolumeCount() { + return iscsiVolumes.getCount(); + } + + public IscsiVolumeService getIscsiVolume() { + return iscsiVolumes; + } + } + + public static final class IscsiVolumeService { + + @SerializedName("count") + private int count; + + @SerializedName("iSCSIService") + private IscsiVolume[] iscsiVolumes; + + public int getCount() { + return count; + } + + public IscsiVolume getIscsiVolume(int i) { + return iscsiVolumes[i]; + } + } + + public static final class IscsiVolume { + + @SerializedName("id") + private String uuid; + + @SerializedName("ag_id") + private String agid; + + @SerializedName("ig_id") + private String igid; + + public String getAg_id() { + return agid; + } + + public String getUuid() { + return uuid; + } + + public String getIg_id() { + return igid; + } + } + + public static final class QueryAsyncJobResultResponse { + + @SerializedName("queryasyncjobresultresponse") + private Async async; + + public Async getAsync() { + return async; + } + } + + public static final class Async { + + @SerializedName("jobstatus") + private int jobstatus; + + @SerializedName("jobresult") + private JobId jobresult; + + @SerializedName("cmd") + private String cmd; + + public int getJobStatus() { + return jobstatus; + } + + public JobId getJobResult() { + return jobresult; + } + + public String getCmd() { + return cmd; + } + + } + + public static final class Capabilities { + + @SerializedName("capability") + private HashMap capabilites; + + public String getVersion() { + return capabilites.get("cloudByteVersion"); + } + } + + /* + * + * change Volume IOPS + */ + + public static Answer updateElastistorVolumeQosGroup(String volumeId, Long newIOPS, String graceAllowed) throws Throwable { + + FileSystem fileSystem = listVolume(volumeId); + + String qosid = fileSystem.getQosGroupid(); + + if (qosid != null) { + + UpdateQosGroupCmdResponse qosGroupCmdResponse = updateQosGroupVolume(newIOPS.toString(), qosid, graceAllowed); + + if (qosGroupCmdResponse.getQoSGroup(0).uuid != null) { + return new Answer(null, true, null); + } else { + return new Answer(null, false, "Update Qos Group Failed"); + } + } else { + return new Answer(null, false, "Qos Group id is NULL"); + } + + } + + private static UpdateQosGroupCmdResponse updateQosGroupVolume(String iops, String qosgroupid, String graceAllowed) throws Throwable { + + UpdateQosGroupCmd updateQosGroupCmd = new UpdateQosGroupCmd(); + updateQosGroupCmd.putCommandParameter("id", qosgroupid); + updateQosGroupCmd.putCommandParameter("iops", iops); + updateQosGroupCmd.putCommandParameter("graceallowed", graceAllowed); + + UpdateQosGroupCmdResponse updateQosGroupCmdResponse = (UpdateQosGroupCmdResponse) getElastistorRestClient().executeCommand(updateQosGroupCmd); + + return updateQosGroupCmdResponse; + } + + private static final class UpdateQosGroupCmd extends BaseCommand { + + public UpdateQosGroupCmd() { + super("updateQosGroup", new UpdateQosGroupCmdResponse()); + } + + } + + public static final class UpdateQosGroupCmdResponse { + + @SerializedName("updateqosresponse") + private QoSGroupWrapperChangeVolumeIops qosGroupWrapper; + + public QoSGroup getQoSGroup(int i) { + return qosGroupWrapper.getQosGroup(i); + } + } + + public static final class QoSGroupWrapperChangeVolumeIops { + + @SerializedName("qosgroup") + private QoSGroup qoSGroup[]; + + public QoSGroup getQosGroup(int i) { + + return qoSGroup[i]; + } + + } + + /* + * resize volume + */ + + public static Boolean updateElastistorVolumeSize(String volumeId, Long newSize) throws Throwable { + + Boolean status = false; + + String quotasize = (String.valueOf(newSize / (1024 * 1024 * 1024)) + "G"); + + UpdateFileSystemCmdResponse fileSystemCmdResponse = updateFileSystem(quotasize, volumeId, null, null, null); + + if (fileSystemCmdResponse.getFileSystem(0).uuid != null) { + status = true; + return status; + } + + return status; + } + + public static UpdateFileSystemCmdResponse updateFileSystem(String quotasize, String esvolumeid, String dedeplication, String compression, String sync) throws Throwable { + + UpdateFileSystemCmd fileSystemCmd = new UpdateFileSystemCmd(); + + fileSystemCmd.putCommandParameter("id", esvolumeid); + if (null != quotasize) + fileSystemCmd.putCommandParameter("quotasize", quotasize); + if (null != dedeplication) + fileSystemCmd.putCommandParameter("deduplication", dedeplication); + if (null != compression) + fileSystemCmd.putCommandParameter("compression", compression); + if (null != sync) + fileSystemCmd.putCommandParameter("sync", sync); + + UpdateFileSystemCmdResponse fileSystemCmdResponse = (UpdateFileSystemCmdResponse) getElastistorRestClient().executeCommand(fileSystemCmd); + + return fileSystemCmdResponse; + } + + private static final class UpdateFileSystemCmd extends BaseCommand { + + public UpdateFileSystemCmd() { + super("updateFileSystem", new UpdateFileSystemCmdResponse()); + } + + } + + private static final class UpdateFileSystemCmdResponse { + + @SerializedName("updatefilesystemresponse") + private UpdateFileSystemWrapper fileSystemWrapper; + + public FileSystem getFileSystem(int i) { + + return fileSystemWrapper.getFileSystem(i); + } + } + + public class UpdateFileSystemWrapper { + + @SerializedName("filesystem") + private FileSystem fileSystem[]; + + public FileSystem getFileSystem(int i) { + return fileSystem[i]; + } + + } + /* + * create snapshot + */ + + public static Answer createElastistorVolumeSnapshot(String volumeId, String snapshotName) throws Throwable{ + + CreateCmdResult result = null; + CreateStorageSnapshotCmd snapshotCmd = new CreateStorageSnapshotCmd(); + + snapshotCmd.putCommandParameter("id", volumeId); + snapshotCmd.putCommandParameter("name", snapshotName); + + CreateStorageSnapshotCmdResponse snapshotCmdResponse = (CreateStorageSnapshotCmdResponse) getElastistorRestClient().executeCommand(snapshotCmd); + + if(snapshotCmdResponse.getStorageSnapshot().getId() != null){ + return new Answer(null, true, "snapshot succesfully taken"); + }else{ + return new Answer(null, false, "snapshot failed"); + } + } + + private static final class CreateStorageSnapshotCmd extends BaseCommand { + + public CreateStorageSnapshotCmd() { + super("createStorageSnapshot", new CreateStorageSnapshotCmdResponse() ); + } + + } + + private static final class CreateStorageSnapshotCmdResponse { + + @SerializedName("createStorageSnapshotResponse") + private StorageSnapshotWrapper StorageSnapshot; + + public StorageSnapshot getStorageSnapshot() { + return StorageSnapshot.getStorageSnapshot(); + } + } + + public static final class StorageSnapshotWrapper { + + @SerializedName("StorageSnapshot") + private StorageSnapshot snapshot; + + + + public StorageSnapshot getStorageSnapshot() { + return snapshot; + } + + } + + public static final class StorageSnapshot { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + public String getId(){ + return uuid; + } + + public String getName(){ + return name; + } + } + + // update the TSM storage + public static UpdateTsmStorageCmdResponse updateElastistorTsmStorage(String capacityBytes,String uuid) throws Throwable{ + + Long size = (Long.valueOf(capacityBytes)/(1024 * 1024 * 1024)); + + String quotasize = null; + + if(size > 1024){ + quotasize = (String.valueOf(Long.valueOf(capacityBytes)/(1024)) + "T"); + }else{ + quotasize = String.valueOf(quotasize) + "G"; + } + s_logger.info("elastistor tsm storage is updating to " + quotasize); + UpdateTsmStorageCmd updateTsmStorageCmd = new UpdateTsmStorageCmd(); + + updateTsmStorageCmd.putCommandParameter("id", uuid); + updateTsmStorageCmd.putCommandParameter("quotasize", quotasize); + + UpdateTsmStorageCmdResponse updateTsmStorageCmdResponse = (UpdateTsmStorageCmdResponse) getElastistorRestClient().executeCommand(updateTsmStorageCmd); + + return updateTsmStorageCmdResponse; + } + + private static final class UpdateTsmStorageCmd extends BaseCommand { + + public UpdateTsmStorageCmd() { + super("updateStorage", new UpdateTsmStorageCmdResponse()); + } + + } + + public static final class UpdateTsmStorageCmdResponse { + + @SerializedName("updatedatasetresponse") + private StorageWrapper storageWrapper; + + public Storage getStorage() { + return storageWrapper.getStorage(); + } + } + + public static final class StorageWrapper { + + @SerializedName("storage") + private Storage storage; + + public Storage getStorage() { + return storage; + } + + } + + public static final class Storage { + + @SerializedName("id") + private String uuid; + + @SerializedName("name") + private String name; + + @SerializedName("quota") + private String quota; + + public String getId(){ + return uuid; + } + + public String getName(){ + return name; + } + + public String getsize(){ + return quota; + } + } + + // update the TSM IOPS + public static UpdateTsmCmdResponse updateElastistorTsmIOPS(String capacityIOPs,String uuid) throws Throwable{ + + s_logger.info("elastistor tsm IOPS is updating to " + capacityIOPs); + UpdateTsmCmd updateTsmCmd = new UpdateTsmCmd(); + String throughput = String.valueOf(Long.valueOf(capacityIOPs)*4); + + updateTsmCmd.putCommandParameter("id", uuid); + updateTsmCmd.putCommandParameter("iops", capacityIOPs); + updateTsmCmd.putCommandParameter("throughput", throughput); + + UpdateTsmCmdResponse updateTsmStorageCmdResponse = (UpdateTsmCmdResponse) getElastistorRestClient().executeCommand(updateTsmCmd); + + return updateTsmStorageCmdResponse; + } + + private static final class UpdateTsmCmd extends BaseCommand { + + public UpdateTsmCmd() { + super("updateTsm", new UpdateTsmCmdResponse()); + } + + } + + public static final class UpdateTsmCmdResponse { + + @SerializedName("updateTsmResponse") + private UpdateTsmWrapper tsmWrapper; + + public Tsm getTsm(int i) { + return tsmWrapper.getTsm(i); + } + } + + public static final class UpdateTsmWrapper { + + @SerializedName("count") + private int count; + + @SerializedName("tsm") + private Tsm[] tsms; + + public int getCount() { + return count; + } + + public Tsm getTsm(int i) { + return tsms[i]; + } + } - public String getVersion() { - return capabilites.get("cloudByteVersion"); - } - } } diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java new file mode 100644 index 0000000000..3e75704892 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * 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 org.apache.cloudstack.storage.datastore.util; + +import org.apache.cloudstack.api.response.ListResponse; + +import com.cloud.utils.component.PluggableService; + +public interface ElastistorVolumeApiService extends PluggableService { + + ListResponse listElastistorVolume(ListElastistorVolumeCmd cmd); + + ListResponse listElastistorPools(ListElastistorPoolCmd cmd); + + ListResponse listElastistorInterfaces(ListElastistorInterfaceCmd cmd); +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java new file mode 100644 index 0000000000..891948309f --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java @@ -0,0 +1,206 @@ +/* + * 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 org.apache.cloudstack.storage.datastore.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.provider.ElastistorPrimaryDataStoreProvider; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.ListInterfacesResponse; +import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.ListPoolsResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeDetailsDao; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.dao.UserVmDao; + +@Component +public class ElastistorVolumeApiServiceImpl extends ManagerBase implements ElastistorVolumeApiService { + private static final Logger s_logger = Logger.getLogger(ElastistorVolumeApiServiceImpl.class); + + @Inject + protected VolumeDao _volsDao; + @Inject + protected UserVmDao _userVmDao; + @Inject + protected DiskOfferingDao _diskOfferingDao; + @Inject + private PrimaryDataStoreDao _storagePoolDao; + @Inject + VolumeService volService; + @Inject + VolumeDataFactory volFactory; + @Inject + ElastistorPrimaryDataStoreProvider esProvider; + @Inject + VolumeDetailsDao volumeDetailsDao; + + @Override + public List> getCommands() { + + List> cmdList = new ArrayList>(); + cmdList.add(ListElastistorVolumeCmd.class); + cmdList.add(ListElastistorPoolCmd.class); + cmdList.add(ListElastistorInterfaceCmd.class); + + s_logger.info("Commands were registered successfully with elastistor volume api service. [cmdcount:" + cmdList.size() + "]"); + return cmdList; + + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + _configParams = params; + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public ListResponse listElastistorVolume(ListElastistorVolumeCmd cmd) { + + try { + FileSystem listVolumeResponse = ElastistorUtil.listVolume(cmd.getId()); + + List volumeResponses = new ArrayList(); + + ListElastistorVolumeResponse volumeResponse; + + volumeResponse = new ListElastistorVolumeResponse(); + + volumeResponse.setId(listVolumeResponse.getUuid()); + volumeResponse.setName(listVolumeResponse.getName()); + volumeResponse.setGraceAllowed(listVolumeResponse.getGraceallowed()); + volumeResponse.setDeduplication(listVolumeResponse.getDeduplication()); + volumeResponse.setCompression(listVolumeResponse.getCompression()); + volumeResponse.setSync(listVolumeResponse.getSync()); + // set object name for a better json structure + volumeResponse.setObjectName("elastistorvolume"); + volumeResponses.add(volumeResponse); + + ListResponse response = new ListResponse(); + + response.setResponses(volumeResponses); + + return response; + } catch (Throwable e) { + s_logger.error("Unable to list elastistor volume.", e); + throw new CloudRuntimeException("Unable to list elastistor volume. " + e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public ListResponse listElastistorPools(ListElastistorPoolCmd cmd) { + + try { + ListPoolsResponse listPools = ElastistorUtil.ListElastistorPools(); + + List poolResponses = new ArrayList(); + + ListElastistorPoolResponse elastistorPoolResponse; + + for (int i = 0; i < listPools.getPools().getCount(); i++) { + // Always instantiate inside the loop + elastistorPoolResponse = new ListElastistorPoolResponse(); + + elastistorPoolResponse.setId(listPools.getPools().getPool(i).getUuid()); + elastistorPoolResponse.setName(listPools.getPools().getPool(i).getName()); + elastistorPoolResponse.setAvailIOPS(Long.parseLong(listPools.getPools().getPool(i).getAvailIOPS())); + elastistorPoolResponse.setCurrentAvailableSpace(Long.parseLong(listPools.getPools().getPool(i).getAvailableSpace())); + elastistorPoolResponse.setState(listPools.getPools().getPool(i).getState()); + elastistorPoolResponse.setControllerid(listPools.getPools().getPool(i).getControllerid()); + elastistorPoolResponse.setGateway(listPools.getPools().getPool(i).getGateway()); + + // set object name for a better json structure + elastistorPoolResponse.setObjectName("elastistorpool"); + poolResponses.add(elastistorPoolResponse); + } + + ListResponse response = new ListResponse(); + + response.setResponses(poolResponses); + + return response; + + } catch (Throwable e) { + s_logger.error("Unable to list elastistor pools.", e); + throw new CloudRuntimeException("Unable to list elastistor pools. " + e.getMessage()); + } + + } + + @Override + public ListResponse listElastistorInterfaces(ListElastistorInterfaceCmd cmd) { + try { + ListInterfacesResponse listInterfacesResponse = ElastistorUtil.ListElastistorInterfaces(cmd.getControllerId()); + + List interfaceResponses = new ArrayList(); + + ListElastistorInterfaceResponse interfaceResponse; + + for (int i = 0; i < listInterfacesResponse.getInterfaces().getCount(); i++) { + // Always instantiate inside the loop + interfaceResponse = new ListElastistorInterfaceResponse(); + + interfaceResponse.setId(listInterfacesResponse.getInterfaces().getInterface(i).getUuid()); + interfaceResponse.setName(listInterfacesResponse.getInterfaces().getInterface(i).getName()); + interfaceResponse.setStatus(listInterfacesResponse.getInterfaces().getInterface(i).getStatus()); + + // set object name for a better json structure + interfaceResponse.setObjectName("elastistorInterface"); + interfaceResponses.add(interfaceResponse); + } + + ListResponse response = new ListResponse(); + + response.setResponses(interfaceResponses); + + return response; + } catch (Throwable e) { + s_logger.error("Unable to list elastistor interfaces.", e); + throw new CloudRuntimeException("Unable to list elastistor interfaces. " + e.getMessage()); + } + + } + +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java new file mode 100644 index 0000000000..0dd68692f2 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java @@ -0,0 +1,58 @@ +// Copyright 2012-2013 CloudByte Inc. +package org.apache.cloudstack.storage.datastore.util; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "listElastistorInterface", description = "Lists the network Interfaces of elastistor", responseObject = ListElastistorVolumeResponse.class) +public class ListElastistorInterfaceCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(ListElastistorInterfaceCmd.class.getName()); + private static final String s_name = "listElastistorInterfaceResponse"; + + @Inject + ElastistorVolumeApiService _ElastistorVolumeApiService; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = "controllerid", type = CommandType.STRING, description = "controller id") + private String controllerid; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public String getControllerId() { + return controllerid; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + + ListResponse response = _ElastistorVolumeApiService.listElastistorInterfaces(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + + } + + @Override + public long getEntityOwnerId() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java new file mode 100644 index 0000000000..cefe0d5502 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java @@ -0,0 +1,63 @@ +// 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 org.apache.cloudstack.storage.datastore.util; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class ListElastistorInterfaceResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) + @Param(description = "the id of the NIC") + private String id; + + @SerializedName(ApiConstants.NAME) + @Param(description = "the name of the NIC") + private String name; + + @SerializedName(ApiConstants.STATUS) + @Param(description = "the status of the NIC") + private String status; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return id; + } + +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java new file mode 100644 index 0000000000..4c9f714afa --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java @@ -0,0 +1,61 @@ +// Copyright 2012-2013 CloudByte Inc. +package org.apache.cloudstack.storage.datastore.util; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseCmd.CommandType; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "listElastistorPool", description = "Lists the pools of elastistor", + responseObject = ListElastistorPoolResponse.class) +public class ListElastistorPoolCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(ListElastistorPoolCmd.class.getName()); + private static final String s_name = "listElastistorPoolResponse"; + + @Inject + ElastistorVolumeApiService _ElastistorVolumeApiService; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "the ID of the Pool") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + + ListResponse response = _ElastistorVolumeApiService.listElastistorPools(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + + } + + @Override + public long getEntityOwnerId() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java new file mode 100644 index 0000000000..4b238bc0dc --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java @@ -0,0 +1,114 @@ +// 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 org.apache.cloudstack.storage.datastore.util; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class ListElastistorPoolResponse extends BaseResponse { + @SerializedName("id") + @Param(description = "the ID of the storage pool") + private String id; + + @SerializedName("name") + @Param(description = "the name of the storage pool") + private String name; + + @SerializedName(ApiConstants.STATE) + @Param(description = "the state of the storage pool") + private String state; + + @SerializedName(ApiConstants.SIZE) + @Param(description = "the current available space of the pool") + private Long currentAvailableSpace; + + @SerializedName(ApiConstants.MAX_IOPS) + @Param(description = "available iops of the pool") + private Long availIOPS; + + @SerializedName("controllerid") + @Param(description = "controller of the pool") + private String controllerid; + + @SerializedName("gateway") + @Param(description = "default gateway of the pool") + private String gateway; + + @Override + public String getObjectId() { + return this.getId(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Long getCurrentAvailableSpace() { + return currentAvailableSpace; + } + + public void setCurrentAvailableSpace(Long currentAvailableSpace) { + this.currentAvailableSpace = currentAvailableSpace; + } + + public Long getAvailIOPS() { + return availIOPS; + } + + public void setAvailIOPS(Long availIOPS) { + this.availIOPS = availIOPS; + } + + public String getControllerid() { + return controllerid; + } + + public void setControllerid(String controllerid) { + this.controllerid = controllerid; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java new file mode 100644 index 0000000000..985eeb94e8 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java @@ -0,0 +1,59 @@ +// Copyright 2012-2013 CloudByte Inc. +package org.apache.cloudstack.storage.datastore.util; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "listElastistorVolume", description = "Lists the volumes of elastistor", responseObject = ListElastistorVolumeResponse.class) +public class ListElastistorVolumeCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(ListElastistorVolumeCmd.class.getName()); + private static final String s_name = "listElastistorVolumeResponse"; + + @Inject + ElastistorVolumeApiService _ElastistorVolumeApiService; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true, description = "the ID of the account") + private String id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public String getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + + ListResponse response = _ElastistorVolumeApiService.listElastistorVolume(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + + } + + @Override + public long getEntityOwnerId() { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java new file mode 100644 index 0000000000..a9838dd1b0 --- /dev/null +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java @@ -0,0 +1,99 @@ +// 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 org.apache.cloudstack.storage.datastore.util; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class ListElastistorVolumeResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) + @Param(description = "the id of the volume") + private String id; + + @SerializedName(ApiConstants.NAME) + @Param(description = "the name of the volume") + private String name; + + @SerializedName("graceallowed") + @Param(description = "graceallowed") + private String graceAllowed; + + @SerializedName("deduplication") + @Param(description = "deduplication") + private String deduplication; + + @SerializedName("compression") + @Param(description = "compression") + private String compression; + + @SerializedName("sync") + @Param(description = "syncronization") + private String sync; + + public String getGraceAllowed() { + return graceAllowed; + } + + public void setGraceAllowed(String graceAllowed) { + this.graceAllowed = graceAllowed; + } + + public String getDeduplication() { + return deduplication; + } + + public void setDeduplication(String deduplication) { + this.deduplication = deduplication; + } + + public String getCompression() { + return compression; + } + + public void setCompression(String compression) { + this.compression = compression; + } + + public String getSync() { + return sync; + } + + public void setSync(String sync) { + this.sync = sync; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return id; + } + +} From 1e4695b9aa5e42f26b84b47349fd81e567deb7e9 Mon Sep 17 00:00:00 2001 From: sailajamada Date: Fri, 18 Jul 2014 09:55:22 +0530 Subject: [PATCH 104/819] Fixing vGPU BVT testcase to skip the test on unsupported hypervisors --- .../smoke/test_deploy_vgpu_enabled_vm.py | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/test/integration/smoke/test_deploy_vgpu_enabled_vm.py b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py index 2188c7f216..aca597142d 100644 --- a/test/integration/smoke/test_deploy_vgpu_enabled_vm.py +++ b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py @@ -42,14 +42,45 @@ class TestDeployvGPUenabledVM(cloudstackTestCase): Test deploy a vGPU enabled VM into a user account """ @classmethod - def setUpClass(cls): - testClient = super(TestDeployvGPUenabledVM, cls).getClsTestClient() + def setUpClass(self): + testClient = super(TestDeployvGPUenabledVM, self).getClsTestClient() + self.apiclient = testClient.getApiClient() + self.testdata = self.testClient.getParsedTestDataConfig() #Need to add check whether zone containing the xen hypervisor or not as well - hypervisor = testClient.getHypervisorInfo() - if hypervisor.lower() != XEN_SERVER.lower(): - raise unittest.skipTest("GPU feature is supported only on XenServer") - + hosts = list_hosts( + self.apiclient, + hypervisor="XenServer" + ) + if hosts is None: + raise unittest.SkipTest("There are no XenServers available. GPU feature is supported only on XenServer.Check listhosts response") + else: + gpuhosts=0 + for ghost in hosts : + if ghost.hypervisorversion >= "6.2.0": + sshClient = SshClient(host=ghost.ipaddress, port=22, user='root',passwd=self.testdata["xen_host_password"]) + if ghost.hypervisorversion == "6.2.0": + res = sshClient.execute("xe patch-list uuid=0850b186-4d47-11e3-a720-001b2151a503") + if len(res) == 0: + continue + res = sshClient.execute("xe vgpu-type-list model-name=\"GRID K120Q\"") + if len(res) != 0 : + gpuhosts=gpuhosts+1 + else: + continue + if gpuhosts == 0: + raise unittest.SkipTest("No XenServer available with GPU Drivers installed") + self.domain = get_domain(self.apiclient) + self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) + #Creating Account + self.account = Account.create( + self.apiclient, + self.testdata["account"], + domainid=self.domain.id + ) + self._cleanup = [ + self.account + ] def setUp(self): self.testdata = self.testClient.getParsedTestDataConfig()["vgpu"] self.apiclient = self.testClient.getApiClient() @@ -75,7 +106,7 @@ def setUp(self): self.testdata["vgpu140q"]["zoneid"] = self.zone.id self.testdata["vgpu140q"]["template"] = self.template.id - self.testdata["service_offerings"]["vgpu260qwin"]["serviceofferingdetails"] = [{'pciDevice': 'VGPU'}, + self.testdata["service_offerings"]["vgpu260qwin"]["serviceofferingdetails"] = [{'pciDevice': 'Group of NVIDIA Corporation GK107GL [GRID K1] GPUs'}, {'vgpuType':'GRID K120Q'}] #create a service offering self.service_offering = ServiceOffering.create( From 5651a13cfde96b91dd40858490c4a450321624ef Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 17 Jul 2014 12:13:48 +0200 Subject: [PATCH 105/819] Remove duplicated code --- .../VirtualRoutingResource.java | 44 +++---------------- .../resource/LibvirtComputingResource.java | 23 ++++------ 2 files changed, 14 insertions(+), 53 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 00501e3847..1c08446bc5 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -193,7 +193,6 @@ private Answer applyConfig(NetworkElementCommand cmd, List cfg) { } } - private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { StringBuffer buff = new StringBuffer(); @@ -226,7 +225,7 @@ private GetRouterAlertsAnswer execute(GetRouterAlertsCommand cmd) { } } - protected Answer execute(CheckRouterCommand cmd) { + private Answer execute(CheckRouterCommand cmd) { final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.RVR_CHECK, null); if (!result.isSuccess()) { return new CheckRouterAnswer(cmd, result.getDetails()); @@ -234,7 +233,7 @@ protected Answer execute(CheckRouterCommand cmd) { return new CheckRouterAnswer(cmd, result.getDetails(), true); } - protected Answer execute(GetDomRVersionCmd cmd) { + private Answer execute(GetDomRVersionCmd cmd) { final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VERSION, null); if (!result.isSuccess()) { return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed"); @@ -246,7 +245,6 @@ protected Answer execute(GetDomRVersionCmd cmd) { return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } - public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; @@ -270,44 +268,12 @@ public boolean configure(final String name, final Map params) th return true; } - public String connect(final String ipAddress) { + public boolean connect(final String ipAddress) { return connect(ipAddress, _port); } - public String connect(final String ipAddress, final int port) { - for (int i = 0; i <= _retry; i++) { - SocketChannel sch = null; - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to connect to " + ipAddress); - } - sch = SocketChannel.open(); - sch.configureBlocking(true); - - final InetSocketAddress addr = new InetSocketAddress(ipAddress, port); - sch.connect(addr); - return null; - } catch (final IOException e) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Could not connect to " + ipAddress); - } - } finally { - if (sch != null) { - try { - sch.close(); - } catch (final IOException e) { - } - } - } - try { - Thread.sleep(_sleep); - } catch (final InterruptedException e) { - } - } - - s_logger.debug("Unable to logon to " + ipAddress); - - return "Unable to connect"; + public boolean connect(final String ipAddress, final int port) { + return connect(ipAddress, port, _sleep); } public boolean connect(final String ipAddress, int retry, int sleep) { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index d4d663c94b..2ebab78093 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -1822,10 +1822,10 @@ private String getResizeScriptType(KVMStoragePool pool, KVMPhysicalDisk vol) { if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) { return "CLVM"; } else if ((poolType == StoragePoolType.NetworkFilesystem - || poolType == StoragePoolType.SharedMountPoint - || poolType == StoragePoolType.Filesystem - || poolType == StoragePoolType.Gluster) - && volFormat == PhysicalDiskFormat.QCOW2 ) { + || poolType == StoragePoolType.SharedMountPoint + || poolType == StoragePoolType.Filesystem + || poolType == StoragePoolType.Gluster) + && volFormat == PhysicalDiskFormat.QCOW2 ) { return "QCOW2"; } return null; @@ -2141,7 +2141,7 @@ private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cm protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connect conn; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); IpAddressTO pubIP = cmd.getIpAddress(); try { @@ -2179,7 +2179,6 @@ protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connect conn; - int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { @@ -2295,12 +2294,10 @@ protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) { int nicNum = 0; for (IpAddressTO ip : ips) { - boolean newNic = false; if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress()); broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++); - newNic = true; } nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri()); @@ -3441,12 +3438,11 @@ private Answer execute(RebootCommand cmd) { protected Answer execute(RebootRouterCommand cmd) { RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd); - String result = _virtRouterResource.connect(cmd.getPrivateIpAddress()); - if (result == null) { + if (_virtRouterResource.connect(cmd.getPrivateIpAddress())) { networkUsage(cmd.getPrivateIpAddress(), "create", null); return answer; } else { - return new Answer(cmd, false, result); + return new Answer(cmd, false, "Failed to connect to virtual router " + cmd.getVmName()); } } @@ -4057,9 +4053,8 @@ protected CheckSshAnswer execute(CheckSshCommand cmd) { s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); } - String result = _virtRouterResource.connect(privateIp, cmdPort); - if (result != null) { - return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result); + if (!_virtRouterResource.connect(privateIp, cmdPort)) { + return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + " because of a connection failure"); } if (s_logger.isDebugEnabled()) { From a963fd34b55b7b69a65745ae0f875f6d712b69d6 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 18 Jul 2014 09:27:40 +0200 Subject: [PATCH 106/819] CLOUDSTACK-7111 Empty commandlist must return a succes --- .../agent/resource/virtualnetwork/VirtualRoutingResource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 1c08446bc5..5c1ee0d0d9 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -168,6 +168,10 @@ private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, int private Answer applyConfig(NetworkElementCommand cmd, List cfg) { + if (cfg.isEmpty()) { + return new Answer(cmd, true, "Nothing to do"); + } + List results = new ArrayList(); List details = new ArrayList(); boolean finalResult = false; From 733a7ba8c113bb95bb77009c858d8503a9658df4 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 18 Jul 2014 10:18:19 +0200 Subject: [PATCH 107/819] Put in a note that will hopefully prevent a bunch of systemvm build failures --- .../appliance/definitions/systemvm64template/definition.rb | 7 +++++++ tools/appliance/definitions/systemvmtemplate/definition.rb | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/tools/appliance/definitions/systemvm64template/definition.rb b/tools/appliance/definitions/systemvm64template/definition.rb index f9308a0558..bee7db7c66 100644 --- a/tools/appliance/definitions/systemvm64template/definition.rb +++ b/tools/appliance/definitions/systemvm64template/definition.rb @@ -1,3 +1,10 @@ +# +# NOTE: Before changing the version of the debian image make +# sure it is added to the userContent of jenkins.buildacloud.org +# and the copy task is updated on the systemvm builds +# This will prevent the inevitable build failure once the iso is +# removed from the debian mirrors +# Veewee::Definition.declare({ :cpu_count => '1', :memory_size=> '256', diff --git a/tools/appliance/definitions/systemvmtemplate/definition.rb b/tools/appliance/definitions/systemvmtemplate/definition.rb index fcaab4d0c3..ab65f53aaa 100644 --- a/tools/appliance/definitions/systemvmtemplate/definition.rb +++ b/tools/appliance/definitions/systemvmtemplate/definition.rb @@ -1,3 +1,10 @@ +# +# NOTE: Before changing the version of the debian image make +# sure it is added to the userContent of jenkins.buildacloud.org +# and the copy task is updated on the systemvm builds +# This will prevent the inevitable build failure once the iso is +# removed from the debian mirrors +# Veewee::Definition.declare({ :cpu_count => '1', :memory_size=> '256', From 0069037573247e2cbe545e8d01d609040444e453 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 16 Jul 2014 15:33:13 +0530 Subject: [PATCH 108/819] CLOUDSTACK-7113: Ability to reset password when Router VM is stopped With this improvement password reset also happens when router is in stopped state on resetPasswordCmd and restoreVM --- .../network/element/VirtualRouterElement.java | 20 ++++++++++- .../src/com/cloud/vm/UserVmManagerImpl.java | 35 +++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 3fcf5783a5..fd15ee35ed 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -74,6 +74,7 @@ import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; +import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; @@ -89,6 +90,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; @@ -681,7 +683,23 @@ public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfi @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; - return _routerMgr.savePasswordToRouter(network, nic, uservm, routers); + // If any router is running then send save password command otherwise save the password in DB + for (VirtualRouter router : routers) { + if (router.getState() == State.Running) { + return _routerMgr.savePasswordToRouter(network, nic, uservm, routers); + } + } + String password = (String) uservm.getParameter(VirtualMachineProfile.Param.VmPassword); + String password_encrypted = DBEncryptionUtil.encrypt(password); + UserVmVO userVmVO = _userVmDao.findById(vm.getId()); + + _userVmDao.loadDetails(userVmVO); + userVmVO.setDetail("password", password_encrypted); + _userVmDao.saveDetails(userVmVO); + + userVmVO.setUpdateParameters(true); + _userVmDao.update(userVmVO.getId(), userVmVO); + return true; } @Override diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index d0bc1867b8..2de6f867d6 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -261,6 +261,7 @@ import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.net.NetUtils; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.InstanceGroupDao; import com.cloud.vm.dao.InstanceGroupVMMapDao; @@ -3439,7 +3440,11 @@ public Pair> startVirtualMach String password = "saved_password"; if (template.getEnablePassword()) { - password = generateRandomPassword(); + if (vm.getDetail("password") != null) { + password = DBEncryptionUtil.decrypt(vm.getDetail("password")); + } else { + password = generateRandomPassword(); + } } if (!validPassword(password)) { @@ -3479,6 +3484,9 @@ public Pair> startVirtualMach if (template.getEnablePassword()) { vm.setPassword((String)vmParamPair.second().get(VirtualMachineProfile.Param.VmPassword)); vm.setUpdateParameters(false); + if (vm.getDetail("password") != null) { + _vmDetailsDao.remove(_vmDetailsDao.findDetail(vm.getId(), "password").getId()); + } _vmDao.update(vm.getId(), vm); } } @@ -4721,8 +4729,11 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) } } + Map params = null; + String password = null; + if (template.getEnablePassword()) { - String password = generateRandomPassword(); + password = generateRandomPassword(); boolean result = resetVMPasswordInternal(vmId, password); if (result) { vm.setPassword(password); @@ -4738,7 +4749,25 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) if (needRestart) { try { - _itMgr.start(vm.getUuid(), null); + if (vm.getDetail("password") != null) { + params = new HashMap(); + params.put(VirtualMachineProfile.Param.VmPassword, password); + } + _itMgr.start(vm.getUuid(), params); + vm = _vmDao.findById(vmId); + if (template.getEnablePassword()) { + // this value is not being sent to the backend; need only for api + // display purposes + vm.setPassword(password); + if (vm.isUpdateParameters()) { + vm.setUpdateParameters(false); + _vmDao.loadDetails(vm); + if (vm.getDetail("password") != null) { + _vmDetailsDao.remove(_vmDetailsDao.findDetail(vm.getId(), "password").getId()); + } + _vmDao.update(vm.getId(), vm); + } + } } catch (Exception e) { s_logger.debug("Unable to start VM " + vm.getUuid(), e); CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage()); From 6c2acda5a3e4d295c20ff06573dcdf96c1962408 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 18 Jul 2014 11:38:29 +0200 Subject: [PATCH 109/819] Fixup licenses and enfore the license check in this plugin --- plugins/storage/volume/cloudbyte/pom.xml | 43 ++++++++++--- .../module.properties | 3 + ...pring-storage-volume-cloudbyte-context.xml | 30 +++++---- .../ElastistorPrimaryDataStoreDriver.java | 45 +++++++------ .../ElastistorPrimaryDataStoreLifeCycle.java | 40 ++++++------ .../provider/ElastistorHostListener.java | 19 ++++++ .../ElastistorPrimaryDataStoreProvider.java | 42 ++++++------ .../datastore/util/ElastistorUtil.java | 64 +++++++++---------- .../util/ElastistorVolumeApiService.java | 37 +++++------ .../util/ElastistorVolumeApiServiceImpl.java | 42 ++++++------ .../util/ListElastistorInterfaceCmd.java | 20 +++++- .../util/ListElastistorInterfaceResponse.java | 3 + .../datastore/util/ListElastistorPoolCmd.java | 20 +++++- .../util/ListElastistorPoolResponse.java | 3 + .../util/ListElastistorVolumeCmd.java | 20 +++++- .../util/ListElastistorVolumeResponse.java | 3 + 16 files changed, 277 insertions(+), 157 deletions(-) diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index b9496e5ac6..8ef0c29ca4 100755 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -1,13 +1,23 @@ - + 4.0.0 @@ -66,6 +76,19 @@ + + com.mycila + license-maven-plugin + + + cloudstack-checklicence + process-classes + + check + + + + diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties index 730e376c92..92cd58fc33 100755 --- a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties +++ b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties @@ -1,3 +1,4 @@ +# # 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 @@ -14,5 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# + name=storage-volume-cloudbyte parent=storage \ No newline at end of file diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml index 4a564826f9..ee4b9a3d08 100755 --- a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml +++ b/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml @@ -1,20 +1,22 @@ callback) { String iqn = null; @@ -134,7 +137,7 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet } String protocoltype = null; - StoragePoolVO dataStoreVO = (StoragePoolVO) _storagePoolDao.findById(storagePoolId); + StoragePoolVO dataStoreVO = _storagePoolDao.findById(storagePoolId); String desc = diskOffering.getDisplayText(); if (desc.toLowerCase().contains("iscsi")) { @@ -197,6 +200,7 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet callback.complete(result); } + @Override public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { String errMsg = null; @@ -350,6 +354,7 @@ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, Stora return volumeSize; } + @Override public ChapInfo getChapInfo(VolumeInfo volumeInfo) { return null; } diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java index 8dbf03ab05..1778d43be4 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java @@ -1,21 +1,22 @@ -/* - * 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. - */ +// +// 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 org.apache.cloudstack.storage.datastore.lifecycle; import java.util.ArrayList; @@ -25,6 +26,8 @@ import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; @@ -41,7 +44,6 @@ import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.UpdateTsmCmdResponse; import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.UpdateTsmStorageCmdResponse; import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java index c68e51d633..c2624eaa25 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java @@ -1,3 +1,22 @@ +// +// 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. +// + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java index f0b0943964..5affa1cf34 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java @@ -1,21 +1,22 @@ -/* - * 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. - */ +// +// 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 org.apache.cloudstack.storage.datastore.provider; import java.util.HashSet; @@ -24,6 +25,9 @@ import javax.inject.Inject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; @@ -35,8 +39,6 @@ import org.apache.cloudstack.storage.datastore.driver.ElastistorPrimaryDataStoreDriver; import org.apache.cloudstack.storage.datastore.lifecycle.ElastistorPrimaryDataStoreLifeCycle; import org.apache.cloudstack.storage.datastore.util.ElastistorUtil; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java index 4e9cef3e7f..7f2da72702 100755 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java @@ -1,21 +1,21 @@ -/* - * 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. - */ +// +// 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 org.apache.cloudstack.storage.datastore.util; @@ -37,13 +37,9 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.http.auth.InvalidCredentialsException; import org.apache.log4j.Logger; -import com.cloud.agent.api.Answer; -import com.cloud.utils.exception.CloudRuntimeException; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; import com.sun.jersey.api.client.Client; @@ -53,6 +49,11 @@ import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.core.util.MultivaluedMapImpl; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; + +import com.cloud.agent.api.Answer; +import com.cloud.utils.exception.CloudRuntimeException; + public class ElastistorUtil { private static final Logger s_logger = Logger.getLogger(ElastistorUtil.class); @@ -566,7 +567,6 @@ public static Volumeiscsioptions updateElastistorIscsiVolume(String volumeid, St ListiSCSIInitiatorResponse initiatorResponse = (ListiSCSIInitiatorResponse) getElastistorRestClient().executeCommand(initiatorCmd); - String intiatorgroup; String IG_Id; if (initiatorResponse.getIInitiator().getInterface(0).getInitiatorgroup().equalsIgnoreCase("ALL")) { IG_Id = initiatorResponse.getIInitiator().getInterface(0).getUuid(); @@ -612,8 +612,6 @@ public static boolean deleteElastistorTsm(String tsmid, boolean managed) throws s_logger.info("elastistor pool is NOT a managed storage , hence deleting the volume then tsm"); String esvolumeid = null; - String estsmid = null; - ListTsmsResponse listTsmsResponse = listTsm(tsmid); if (listTsmsResponse.getTsmsCount() != 0) { @@ -923,14 +921,12 @@ private static FileSystem queryAsyncVolumeJobResult(String jobid) throws Throwab */ private static String convertCapacityBytes(Long capacityBytes) { - String quotasize; - if ((1099511627776L) > capacityBytes && (capacityBytes > (1073741824))) { - return quotasize = (String.valueOf(capacityBytes / (1024 * 1024 * 1024)) + "G"); + return (String.valueOf(capacityBytes / (1024 * 1024 * 1024)) + "G"); } else { int temp1 = (int) (capacityBytes / (1024 * 1024 * 1024)); int temp2 = temp1 / 1024; - return quotasize = (String.valueOf(temp2) + "T"); + return (String.valueOf(temp2) + "T"); } } @@ -1046,9 +1042,9 @@ private static final class ElastiCenterClient { private String queryparamresponse = "response"; public ElastiCenterClient(String address, String key) throws InvalidCredentialsException, InvalidParameterException, SSLHandshakeException, ServiceUnavailableException { - this.elastiCenterAddress = address; - this.apiKey = key; - this.initialize(); + elastiCenterAddress = address; + apiKey = key; + initialize(); } public void initialize() throws InvalidParameterException, SSLHandshakeException, InvalidCredentialsException, ServiceUnavailableException { @@ -1067,13 +1063,16 @@ public void initialize() throws InvalidParameterException, SSLHandshakeException // Create a trust manager that does not validate certificate // chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + @Override public X509Certificate[] getAcceptedIssuers() { return null; } + @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { } + @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; @@ -2415,7 +2414,6 @@ public FileSystem getFileSystem(int i) { public static Answer createElastistorVolumeSnapshot(String volumeId, String snapshotName) throws Throwable{ - CreateCmdResult result = null; CreateStorageSnapshotCmd snapshotCmd = new CreateStorageSnapshotCmd(); snapshotCmd.putCommandParameter("id", volumeId); diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java index 3e75704892..08dcb4333f 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java @@ -1,21 +1,22 @@ -/* - * 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. - */ +// +// 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 org.apache.cloudstack.storage.datastore.util; import org.apache.cloudstack.api.response.ListResponse; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java index 891948309f..709c1fe426 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java @@ -1,21 +1,22 @@ -/* - * 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. - */ +// +// 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 org.apache.cloudstack.storage.datastore.util; import java.util.ArrayList; @@ -25,6 +26,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; @@ -33,8 +37,6 @@ import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem; import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.ListInterfacesResponse; import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.ListPoolsResponse; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.VolumeDao; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java index 0dd68692f2..a100f439be 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java @@ -1,4 +1,22 @@ -// Copyright 2012-2013 CloudByte Inc. +// +// 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 org.apache.cloudstack.storage.datastore.util; import javax.inject.Inject; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java index cefe0d5502..63f9fa0291 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java @@ -1,3 +1,4 @@ +// // 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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package org.apache.cloudstack.storage.datastore.util; import org.apache.cloudstack.api.ApiConstants; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java index 4c9f714afa..d3701b784b 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java @@ -1,4 +1,22 @@ -// Copyright 2012-2013 CloudByte Inc. +// +// 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 org.apache.cloudstack.storage.datastore.util; import javax.inject.Inject; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java index 4b238bc0dc..b842ecd2ae 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java @@ -1,3 +1,4 @@ +// // 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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package org.apache.cloudstack.storage.datastore.util; import org.apache.cloudstack.api.ApiConstants; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java index 985eeb94e8..d2b89e388d 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java @@ -1,4 +1,22 @@ -// Copyright 2012-2013 CloudByte Inc. +// +// 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 org.apache.cloudstack.storage.datastore.util; import javax.inject.Inject; diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java index a9838dd1b0..b251d7a3a3 100644 --- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java +++ b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java @@ -1,3 +1,4 @@ +// // 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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package org.apache.cloudstack.storage.datastore.util; import org.apache.cloudstack.api.ApiConstants; From c1aed5558365363c07e594300952230a7be9d45f Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 18 Jul 2014 11:52:27 +0200 Subject: [PATCH 110/819] More rat fixes --- .../ServerResource/.nuget/NuGet.targets | 20 +++++++++++++++++++ .../hypervisors/hyperv/conf/agent.properties | 17 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets index a56da2432d..b7cd8ddf9b 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/NuGet.targets @@ -1,4 +1,24 @@ + $(MSBuildProjectDirectory)\..\ diff --git a/plugins/hypervisors/hyperv/conf/agent.properties b/plugins/hypervisors/hyperv/conf/agent.properties index 4e61451b0f..fe3798ffbb 100644 --- a/plugins/hypervisors/hyperv/conf/agent.properties +++ b/plugins/hypervisors/hyperv/conf/agent.properties @@ -1,3 +1,20 @@ +# 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. + #Storage #Tue Feb 12 10:08:17 GMT 2013 local.storage.path=E\:\\Disks\\Disks From 2f293f42d567b1218cb083250707eeffc5324dc3 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Fri, 18 Jul 2014 17:51:02 +0530 Subject: [PATCH 111/819] CLOUDSTACK-7129: Non-admin user can use deleteNetwork with shared networks fix ensures only admin users can delete shared network --- server/src/com/cloud/network/NetworkServiceImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index c5d71348a2..b154fd9028 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1838,6 +1838,11 @@ public boolean deleteNetwork(long networkId, boolean forced) { Account owner = _accountMgr.getAccount(network.getAccountId()); + // Only Admin can delete Shared networks + if (network.getGuestType() == GuestType.Shared && !_accountMgr.isAdmin(caller.getId())) { + throw new InvalidParameterValueException("Only Admins can delete network with guest type " + GuestType.Shared); + } + // Perform permission check _accountMgr.checkAccess(caller, null, true, network); From 5f87056e950e0cae042d0c836f10a091800b8dbc Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Fri, 18 Jul 2014 01:14:42 -0400 Subject: [PATCH 112/819] CLOUDSTACK-7024: Resolved cleanup issue in test script --- test/integration/component/test_project_usage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index 5e0dda5aff..e8ed1b193d 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -720,7 +720,7 @@ def setUpClass(cls): account=cls.account.name, domainid=cls.account.domainid ) - cls._cleanup.append(cls.account) + cls._cleanup.insert(-1, cls.project) cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"]) From 24da72f37395a6bb612ea1d073db0155289cf000 Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Fri, 18 Jul 2014 02:52:20 -0400 Subject: [PATCH 113/819] CLOUDSTACK-7130: Adding BugId to failed test cases --- test/integration/smoke/test_volumes.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 7fbcc21647..c6c0accb20 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -113,7 +113,7 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") def test_01_create_volume(self): """Test Volume creation for all Disk Offerings (incl. custom) """ @@ -343,7 +343,7 @@ def tearDown(self): cleanup_resources(self.apiClient, self.cleanup) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") def test_02_attach_volume(self): """Attach a created Volume to a Running VM """ @@ -389,7 +389,7 @@ def test_02_attach_volume(self): (self.virtual_machine.ipaddress, e)) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") def test_03_download_attached_volume(self): """Download a Volume attached to a VM """ @@ -411,7 +411,7 @@ def test_03_download_attached_volume(self): with self.assertRaises(Exception): self.apiClient.extractVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") def test_04_delete_attached_volume(self): """Delete a Volume attached to a VM """ @@ -432,7 +432,7 @@ def test_04_delete_attached_volume(self): with self.assertRaises(Exception): self.apiClient.deleteVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") def test_05_detach_volume(self): """Detach a Volume attached to a VM """ @@ -474,7 +474,7 @@ def test_05_detach_volume(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") def test_06_download_detached_volume(self): """Download a Volume unattached to an VM """ @@ -511,7 +511,7 @@ def test_06_download_detached_volume(self): % (extract_vol.url, self.volume.id) ) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") def test_07_resize_fail(self): """Test resize (negative) non-existent volume""" # Verify the size is the new size is what we wanted it to be. @@ -729,7 +729,7 @@ def test_08_resize_volume(self): time.sleep(30) return - @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false") + @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false", BugId="CLOUDSTACK-7130") def test_09_delete_detached_volume(self): """Delete a Volume unattached to an VM """ From 9fb93fe5b3d330d75cc5a58613beea92e9138372 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 18 Jul 2014 12:03:10 -0700 Subject: [PATCH 114/819] CLOUDSTACK-7110: introduced by c1116142a3cd356e1e8da5404be150a07752b5d5, if it's a data volume, mgt server doesn't send image format to agent --- .../kvm/storage/KVMStorageProcessor.java | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 22575ee8ee..9b1c9debc7 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -351,7 +351,7 @@ public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { - s_logger.debug("Failed to create volume: " + e.toString()); + s_logger.debug("Failed to create volume: ", e); return new CopyCmdAnswer(e.toString()); } } @@ -403,6 +403,7 @@ public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { newVol.setPath(volumeName); return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { + s_logger.debug("Failed to ccopyVolumeFromImageCacheToPrimary: ", e); return new CopyCmdAnswer(e.toString()); } finally { if (secondaryStoragePool != null) { @@ -448,6 +449,7 @@ public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { newVol.setFormat(destFormat); return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { + s_logger.debug("Failed to copyVolumeFromPrimaryToSecondary: ", e); return new CopyCmdAnswer(e.toString()); } finally { if (secondaryStoragePool != null) { @@ -554,7 +556,7 @@ public Answer createTemplateFromVolume(CopyCommand cmd) { newTemplate.setName(templateName); return new CopyCmdAnswer(newTemplate); } catch (Exception e) { - s_logger.debug("Failed to create template from volume: " + e.toString()); + s_logger.debug("Failed to createTemplateFromVolume: ", e); return new CopyCmdAnswer(e.toString()); } finally { if (secondaryStorage != null) { @@ -754,10 +756,10 @@ public Answer backupSnapshot(CopyCommand cmd) { newSnapshot.setPhysicalSize(size); return new CopyCmdAnswer(newSnapshot); } catch (LibvirtException e) { - s_logger.debug("Failed to backup snapshot: " + e.toString()); + s_logger.debug("Failed to backup snapshot: ", e); return new CopyCmdAnswer(e.toString()); } catch (CloudRuntimeException e) { - s_logger.debug("Failed to backup snapshot: " + e.toString()); + s_logger.debug("Failed to backup snapshot: ", e); return new CopyCmdAnswer(e.toString()); } finally { try { @@ -1008,11 +1010,11 @@ public Answer attachVolume(AttachCommand cmd) { return new AttachAnswer(disk); } catch (LibvirtException e) { - s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e); storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath()); return new AttachAnswer(e.toString()); } catch (InternalErrorException e) { - s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e); return new AttachAnswer(e.toString()); } } @@ -1034,10 +1036,10 @@ public Answer dettachVolume(DettachCommand cmd) { return new DettachAnswer(disk); } catch (LibvirtException e) { - s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e); return new DettachAnswer(e.toString()); } catch (InternalErrorException e) { - s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e); return new DettachAnswer(e.toString()); } } @@ -1053,18 +1055,23 @@ public Answer createVolume(CreateObjectCommand cmd) { try { primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); disksize = volume.getSize(); - - vol = primaryPool.createPhysicalDisk(volume.getUuid(), PhysicalDiskFormat.valueOf(volume.getFormat().toString().toUpperCase()), + PhysicalDiskFormat format; + if (volume.getFormat() == null) { + format = primaryPool.getDefaultFormat(); + } else { + format = PhysicalDiskFormat.valueOf(volume.getFormat().toString().toUpperCase()); + } + vol = primaryPool.createPhysicalDisk(volume.getUuid(), format, volume.getProvisioningType(), disksize); VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(vol.getName()); newVol.setSize(volume.getSize()); - newVol.setFormat(ImageFormat.valueOf(vol.getFormat().toString().toUpperCase())); + newVol.setFormat(ImageFormat.valueOf(format.toString().toUpperCase())); return new CreateObjectAnswer(newVol); } catch (Exception e) { - s_logger.debug("Failed to create volume: " + e.toString()); + s_logger.debug("Failed to create volume: ", e); return new CreateObjectAnswer(e.toString()); } } @@ -1164,7 +1171,7 @@ public Answer createSnapshot(CreateObjectCommand cmd) { newSnapshot.setPath(disk.getPath() + File.separator + snapshotName); return new CreateObjectAnswer(newSnapshot); } catch (LibvirtException e) { - s_logger.debug("Failed to manage snapshot: " + e.toString()); + s_logger.debug("Failed to manage snapshot: ", e); return new CreateObjectAnswer("Failed to manage snapshot: " + e.toString()); } } @@ -1184,7 +1191,7 @@ public Answer deleteVolume(DeleteCommand cmd) { pool.deletePhysicalDisk(vol.getPath()); return new Answer(null); } catch (CloudRuntimeException e) { - s_logger.debug("Failed to delete volume: " + e.toString()); + s_logger.debug("Failed to delete volume: ", e); return new Answer(null, false, e.toString()); } } @@ -1229,6 +1236,7 @@ public Answer createVolumeFromSnapshot(CopyCommand cmd) { return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { + s_logger.debug("Failed to createVolumeFromSnapshot: ", e); return new CopyCmdAnswer(e.toString()); } } From 51c14106d8858769ac8f3cc0d8f3f357254c0509 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 18 Jul 2014 12:07:36 -0700 Subject: [PATCH 115/819] CLOUDSTACK-7123: set the timeout to 60s, when run the file command --- .../src/org/apache/cloudstack/utils/template/TemplateUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java b/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java index bad94def68..a3f3a682a5 100644 --- a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java +++ b/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java @@ -34,7 +34,7 @@ public static String checkTemplateFormat(String path, String url) { if (isCompressedExtension(url)) { command = "file -z "; } - String output = Script.runSimpleBashScript(command + path + " | cut -d: -f2", 1000); + String output = Script.runSimpleBashScript(command + path + " | cut -d: -f2", 60000); // vmdk if ((output.contains("VMware") || output.contains("data")) && isCorrectExtension(url, "vmdk")) { From cfcc4a076dd740d6deed48084132946a55ed08d1 Mon Sep 17 00:00:00 2001 From: amoghvk Date: Thu, 17 Jul 2014 14:16:35 -0700 Subject: [PATCH 116/819] CLOUDSTACK-6358: KVM mappings for CentOS 6.x and RHEL 6.x --- server/src/com/cloud/hypervisor/KVMGuru.java | 2 +- setup/db/db/schema-430to440.sql | 78 ++++++++++++++------ 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/com/cloud/hypervisor/KVMGuru.java index 287b0d2f1e..80279ad1f9 100644 --- a/server/src/com/cloud/hypervisor/KVMGuru.java +++ b/server/src/com/cloud/hypervisor/KVMGuru.java @@ -62,7 +62,7 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId()); GuestOSHypervisorVO guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion()); if (guestOsMapping == null) { - to.setPlatformEmulator(null); + to.setPlatformEmulator("Other"); } else { to.setPlatformEmulator(guestOsMapping.getGuestOsName()); } diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 607c5068db..cff38d0a69 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -1689,6 +1689,62 @@ CREATE TABLE `cloud`.`network_acl_item_cidrs` ( ALTER TABLE `cloud`.`load_balancer_healthcheck_policies` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; ALTER TABLE `cloud`.`load_balancer_stickiness_policies` ADD COLUMN `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the policy can be displayed to the end user'; +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.6', 141, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.6', 142, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.7', 161, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.7', 162, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.8', 173, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.8', 174, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.9', 175, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5.9', 176, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.0', 143, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.0', 144, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.1', 177, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.1', 178, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.2', 179, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.2', 180, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.3', 171, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.3', 172, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.4', 181, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.4', 182, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.5', 227, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 6.5', 228, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.6', 149, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.6', 150, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.7', 189, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.7', 190, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.8', 191, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.8', 192, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.9', 193, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 5.9', 194, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.1', 195, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.1', 196, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.2', 197, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.2', 198, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.3', 199, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.3', 204, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.4', 205, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.4', 206, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 136, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 137, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 12.04', 164, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 156, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 157, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 72, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 15, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 133, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 132, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 69, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 70, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows Server 2008', 54, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 2000', 105, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows NT', 64, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 3.1', 65, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 160, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 225, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 226, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 139, now(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 140, now(), 0); INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'rhel5Guest', 149, now(), 0); INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '4.0', 'windows8Server64Guest', 168, now(), 0); @@ -2438,25 +2494,3 @@ CREATE TABLE `cloud`.`snapshot_policy_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_snapshot_policy_details__snapshot_policy_id` FOREIGN KEY `fk_snapshot_policy_details__snapshot_policy_id`(`policy_id`) REFERENCES `snapshot_policy`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'CentOS 5 (64-bit)', 140, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 136, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Red Hat Enterprise Linux 6.0', 137, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 12.04', 164, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 156, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Ubuntu 10.10', 157, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 72, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 5', 15, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 133, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Debian GNU/Linux 6', 132, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 69, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other Linux', 70, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows Server 2008', 54, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 2000', 105, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows NT', 64, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Windows 3.1', 65, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 160, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 225, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'FreeBSD 10', 226, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 139, now(), 0); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'KVM', 'default', 'Other PV', 140, now(), 0); From 1bb3ea8b7a7447e2ad444b403facbcee67ffde4f Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 18 Jul 2014 15:38:59 -0700 Subject: [PATCH 117/819] CLOUDSTACK-6918: iterate through pending works in cancel maitenance --- server/src/com/cloud/storage/StoragePoolAutomationImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java index 8ff759df10..59bd2a5465 100644 --- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java +++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java @@ -372,7 +372,6 @@ public boolean cancelMaintain(DataStore store) { _storagePoolWorkDao.update(work.getId(), work); } } - return true; } catch (Exception e) { s_logger.debug("Failed start vm", e); throw new CloudRuntimeException(e.toString()); From 849049a2f0eac8f889dbb96bd77ea569e8901a48 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Fri, 18 Jul 2014 16:40:09 -0600 Subject: [PATCH 118/819] KVM: Allow changing VM video card via agent.properties. This change in LibvirtVMDef can also be leveraged to add the option to service offering or template hardware selection (as nic and disk types do). --- .../resource/LibvirtComputingResource.java | 10 +++++++++ .../hypervisor/kvm/resource/LibvirtVMDef.java | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 2ebab78093..627c1fdac6 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -230,6 +230,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; @@ -450,6 +451,8 @@ protected String getDefaultScriptsDir() { protected String _guestCpuMode; protected String _guestCpuModel; protected boolean _noKvmClock; + protected String _videoHw; + protected int _videoRam; private final Map _pifs = new HashMap(); private final Map _vmStats = new ConcurrentHashMap(); @@ -800,6 +803,10 @@ public boolean configure(String name, Map params) throws Configu _noMemBalloon = true; } + _videoHw = (String) params.get("vm.video.hardware"); + value = (String) params.get("vm.video.ram"); + _videoRam = NumbersUtil.parseInt(value, 0); + value = (String)params.get("host.reserved.mem.mb"); _dom0MinMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024; @@ -3747,6 +3754,9 @@ So if getMinSpeed() returns null we fall back to getSpeed(). devices.addDevice(vserial); } + VideoDef videoCard = new VideoDef(_videoHw, _videoRam); + devices.addDevice(videoCard); + ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); devices.addDevice(console); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 8084035d84..6b29e9cf94 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -1060,6 +1060,28 @@ public String toString() { } } + public static class VideoDef { + private String _videoModel; + private int _videoRam; + + public VideoDef(String videoModel, int videoRam) { + _videoModel = videoModel; + _videoRam = videoRam; + } + + @Override + public String toString() { + StringBuilder videoBuilder = new StringBuilder(); + if (_videoModel != null && !_videoModel.isEmpty() && _videoRam != 0){ + videoBuilder.append("\n"); + return videoBuilder.toString(); + } + return ""; + } + } + public static class VirtioSerialDef { private final String _name; private String _path; From d05549e16b9b892a52d64d6915770f804b019a05 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 18 Jul 2014 16:05:54 -0700 Subject: [PATCH 119/819] XS task object may disappear, change the log level --- .../xenserver/resource/CitrixResourceBase.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 5881d6809a..a2b96259e4 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -676,8 +676,7 @@ protected String callHostPluginAsync(Connection conn, String plugin, try { task.destroy(conn); } catch (Exception e1) { - s_logger.warn("unable to destroy task(" + task.toString() - + ") on host(" + _host.uuid + ") due to ", e1); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); } } } @@ -3502,8 +3501,8 @@ protected VDI cloudVDIcopy(Connection conn, VDI vdi, SR sr, int wait) throws Exc if (task != null) { try { task.destroy(conn); - } catch (Exception e1) { - s_logger.warn("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to ", e1); + } catch (Exception e) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e.toString()); } } } @@ -3542,7 +3541,7 @@ protected String callHostPluginAsync(Connection conn, String plugin, String cmd, try { task.destroy(conn); } catch (Exception e1) { - s_logger.warn("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to ", e1); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); } } } From 88f866645b1aa3f373691a43586f2aa56150b0c3 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Fri, 18 Jul 2014 17:30:18 -0700 Subject: [PATCH 120/819] fix iptables chain name too long (must be under 30 chars) --- scripts/vm/hypervisor/xenserver/vmops | 12 +- scripts/vm/hypervisor/xenserver/vmops.orig | 1495 ++++++++++++++++++++ 2 files changed, 1505 insertions(+), 2 deletions(-) create mode 100755 scripts/vm/hypervisor/xenserver/vmops.orig diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 2fd0619536..539d7decd4 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -250,6 +250,8 @@ def chain_name(vm_name): if vm_name.startswith('i-') or vm_name.startswith('r-'): if vm_name.endswith('untagged'): return '-'.join(vm_name.split('-')[:-1]) + if len(vm_name) > 28: + vm_name = vm_name[0:27] return vm_name def chain_name_def(vm_name): @@ -257,11 +259,17 @@ def chain_name_def(vm_name): if vm_name.endswith('untagged'): return '-'.join(vm_name.split('-')[:-2]) + "-def" return '-'.join(vm_name.split('-')[:-1]) + "-def" + + if len(vm_name) > 28: + vm_name = vm_name[0:27] return vm_name def egress_chain_name(vm_name): - return chain_name(vm_name) + "-eg" - + name = chain_name(vm_name) + "-eg" + if len(name) > 28: + name = name[0:27] + return name + @echo def can_bridge_firewall(session, args): try: diff --git a/scripts/vm/hypervisor/xenserver/vmops.orig b/scripts/vm/hypervisor/xenserver/vmops.orig new file mode 100755 index 0000000000..3f25a2e7f9 --- /dev/null +++ b/scripts/vm/hypervisor/xenserver/vmops.orig @@ -0,0 +1,1495 @@ +#!/usr/bin/python +# 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. + +# Version @VERSION@ +# +# A plugin for executing script needed by vmops cloud + +import os, sys, time +import XenAPIPlugin +if os.path.exists("/opt/xensource/sm"): + sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"]) +if os.path.exists("/usr/lib/xcp/sm"): + sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) +import base64 +import socket +import stat +import tempfile +import util +import subprocess +import zlib +import cloudstack_pluginlib as lib +import logging +from util import CommandException + +lib.setup_logging("/var/log/cloud/vmops.log") + +def echo(fn): + def wrapped(*v, **k): + name = fn.__name__ + logging.debug("#### VMOPS enter %s ####" % name ) + res = fn(*v, **k) + logging.debug("#### VMOPS exit %s ####" % name ) + return res + return wrapped + +@echo +def add_to_VCPUs_params_live(session, args): + key = args['key'] + value = args['value'] + vmname = args['vmname'] + try: + cmd = ["bash", "/opt/cloud/bin/add_to_vcpus_params_live.sh", vmname, key, value] + txt = util.pread2(cmd) + except: + return 'false' + return 'true' + +@echo +def setup_iscsi(session, args): + uuid=args['uuid'] + try: + cmd = ["bash", "/opt/cloud/bin/setup_iscsi.sh", uuid] + txt = util.pread2(cmd) + except: + txt = '' + return txt + + +@echo +def getgateway(session, args): + mgmt_ip = args['mgmtIP'] + try: + cmd = ["bash", "/opt/cloud/bin/network_info.sh", "-g", mgmt_ip] + txt = util.pread2(cmd) + except: + txt = '' + + return txt + +@echo +def preparemigration(session, args): + uuid = args['uuid'] + try: + cmd = ["/opt/cloud/bin/make_migratable.sh", uuid] + util.pread2(cmd) + txt = 'success' + except: + logging.debug("Catch prepare migration exception" ) + txt = '' + + return txt + +@echo +def setIptables(session, args): + try: + cmd = ["/bin/bash", "/opt/cloud/bin/setupxenserver.sh"] + txt = util.pread2(cmd) + txt = 'success' + except: + logging.debug(" setIptables execution failed " ) + txt = '' + + return txt + +@echo +def pingdomr(session, args): + host = args['host'] + port = args['port'] + socket.setdefaulttimeout(3) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.connect((host,int(port))) + txt = 'success' + except: + txt = '' + + s.close() + + return txt + +@echo +def kill_copy_process(session, args): + namelabel = args['namelabel'] + try: + cmd = ["bash", "/opt/cloud/bin/kill_copy_process.sh", namelabel] + txt = util.pread2(cmd) + except: + txt = 'false' + return txt + +@echo +def pingxenserver(session, args): + txt = 'success' + return txt + +def pingtest(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/cloud/bin/pingtest.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + txt = 'success' + except: + logging.debug(" pingtest failed " ) + txt = '' + + return txt + +@echo +def setLinkLocalIP(session, args): + brName = args['brName'] + try: + cmd = ["ip", "route", "del", "169.254.0.0/16"] + txt = util.pread2(cmd) + except: + txt = '' + try: + cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] + txt = util.pread2(cmd) + except: + try: + cmd = ['cat', '/etc/xensource/network.conf'] + result = util.pread2(cmd) + except: + return 'can not cat network.conf' + + if result.lower().strip() == "bridge": + try: + cmd = ["brctl", "addbr", brName] + txt = util.pread2(cmd) + except: + pass + + else: + try: + cmd = ["ovs-vsctl", "add-br", brName] + txt = util.pread2(cmd) + except: + pass + + try: + cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"] + txt = util.pread2(cmd) + except: + pass + try: + cmd = ["ip", "route", "add", "169.254.0.0/16", "dev", brName, "src", "169.254.0.1"] + txt = util.pread2(cmd) + except: + txt = '' + txt = 'success' + return txt + +@echo +def createFile(session, args): + file_path = args['filepath'] + file_contents = args['filecontents'] + + try: + f = open(file_path, "w") + f.write(file_contents) + f.close() + txt = 'success' + except: + logging.debug(" failed to create HA proxy cfg file ") + txt = '' + + return txt + +@echo +def createFileInDomr(session, args): + file_path = args['filepath'] + file_contents = args['filecontents'] + domrip = args['domrip'] + try: + tmpfile = util.pread2(['mktemp']).strip() + f = open(tmpfile, "w") + f.write(file_contents) + f.close() + target = "root@" + domrip + ":" + file_path + txt = util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + util.pread2(['rm',tmpfile]) + txt = 'succ#' + txt + except: + logging.debug("failed to create file " + file_path + " in VR, contain: " + file_contents) + txt = 'fail#' + txt + return txt + +@echo +def deleteFile(session, args): + file_path = args["filepath"] + + try: + if os.path.isfile(file_path): + os.remove(file_path) + txt = 'success' + except: + logging.debug(" failed to remove HA proxy cfg file ") + txt = '' + + return txt + +def chain_name(vm_name): + if vm_name.startswith('i-') or vm_name.startswith('r-'): + if vm_name.endswith('untagged'): + return '-'.join(vm_name.split('-')[:-1]) + return vm_name + +def chain_name_def(vm_name): + if vm_name.startswith('i-'): + if vm_name.endswith('untagged'): + return '-'.join(vm_name.split('-')[:-2]) + "-def" + return '-'.join(vm_name.split('-')[:-1]) + "-def" + return vm_name + +def egress_chain_name(vm_name): + return chain_name(vm_name) + "-eg" + +@echo +def can_bridge_firewall(session, args): + try: + util.pread2(['ebtables', '-V']) + util.pread2(['ipset', '-V']) + cmd = ['cat', '/etc/xensource/network.conf'] + result = util.pread2(cmd) + if result.lower().strip() != "bridge": + return 'false' + + except: + return 'false' + + try: + util.pread2(['iptables', '-N', 'BRIDGE-FIREWALL']) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) + except: + logging.debug('Chain BRIDGE-FIREWALL already exists') + + try: + util.pread2(['iptables', '-N', 'BRIDGE-DEFAULT-FIREWALL']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-j', 'BRIDGE-DEFAULT-FIREWALL']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + except: + logging.debug('Chain BRIDGE-DEFAULT-FIREWALL already exists') + + result = 'true' + try: + util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) + except: + try: + util.pread2(['iptables', '-I', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '-j', 'BRIDGE-FIREWALL']) + util.pread2(['iptables', '-A', 'FORWARD', '-j', 'DROP']) + except: + return 'false' + default_ebtables_rules() + allow_egress_traffic(session) + if not os.path.exists('/var/run/cloud'): + os.makedirs('/var/run/cloud') + if not os.path.exists('/var/cache/cloud'): + os.makedirs('/var/cache/cloud') + #get_ipset_keyword() + + cleanup_rules_for_dead_vms(session) + cleanup_rules(session, args) + + return result + +@echo +def default_ebtables_rules(): + try: + util.pread2(['ebtables', '-N', 'DEFAULT_EBTABLES']) + util.pread2(['ebtables', '-A', 'FORWARD', '-j' 'DEFAULT_EBTABLES']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'ACCEPT']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'ACCEPT']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Request', '-j', 'ACCEPT']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Reply', '-j', 'ACCEPT']) + # deny mac broadcast and multicast + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Broadcast', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Multicast', '-j', 'DROP']) + # deny ip broadcast and multicast + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '224.0.0.0/4', '-j', 'DROP']) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-j', 'RETURN']) + # deny ipv6 + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv6', '-j', 'DROP']) + # deny vlan + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', '802_1Q', '-j', 'DROP']) + # deny all others (e.g., 802.1d, CDP) + util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-j', 'DROP']) + except: + logging.debug('Chain DEFAULT_EBTABLES already exists') + + +@echo +def allow_egress_traffic(session): + devs = [] + for pif in session.xenapi.PIF.get_all(): + pif_rec = session.xenapi.PIF.get_record(pif) + dev = pif_rec.get('device') + devs.append(dev + "+") + for d in devs: + try: + util.pread2(['/bin/bash', '-c', "iptables -n -L FORWARD | grep '%s '" % d]) + except: + try: + util.pread2(['iptables', '-I', 'FORWARD', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', d, '-j', 'ACCEPT']) + except: + logging.debug("Failed to add FORWARD rule through to %s" % d) + return 'false' + return 'true' + + +def ipset(ipsetname, proto, start, end, ips): + try: + util.pread2(['ipset', '-N', ipsetname, 'iptreemap']) + except: + logging.debug("ipset chain already exists" + ipsetname) + + result = True + ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000) + + try: + util.pread2(['ipset', '-N', ipsettmp, 'iptreemap']) + except: + logging.debug("Failed to create temp ipset, reusing old name= " + ipsettmp) + try: + util.pread2(['ipset', '-F', ipsettmp]) + except: + logging.debug("Failed to clear old temp ipset name=" + ipsettmp) + return False + + try: + for ip in ips: + try: + util.pread2(['ipset', '-A', ipsettmp, ip]) + except CommandException, cex: + if cex.reason.rfind('already in set') == -1: + raise + except: + logging.debug("Failed to program ipset " + ipsetname) + util.pread2(['ipset', '-F', ipsettmp]) + util.pread2(['ipset', '-X', ipsettmp]) + return False + + try: + util.pread2(['ipset', '-W', ipsettmp, ipsetname]) + except: + logging.debug("Failed to swap ipset " + ipsetname) + result = False + + try: + util.pread2(['ipset', '-F', ipsettmp]) + util.pread2(['ipset', '-X', ipsettmp]) + except: + # if the temporary name clashes next time we'll just reuse it + logging.debug("Failed to delete temp ipset " + ipsettmp) + + return result + +@echo +def destroy_network_rules_for_vm(session, args): + vm_name = args.pop('vmName') + vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + if vm_name.startswith('i-') or vm_name.startswith('r-') or vm_name.startswith('l-'): + try: + util.pread2(['iptables', '-F', vmchain_default]) + util.pread2(['iptables', '-X', vmchain_default]) + except: + logging.debug("Ignoring failure to delete chain " + vmchain_default) + + destroy_ebtables_rules(vmchain) + destroy_arptables_rules(vmchain) + + try: + util.pread2(['iptables', '-F', vmchain]) + util.pread2(['iptables', '-X', vmchain]) + except: + logging.debug("Ignoring failure to delete ingress chain " + vmchain) + + + try: + util.pread2(['iptables', '-F', vmchain_egress]) + util.pread2(['iptables', '-X', vmchain_egress]) + except: + logging.debug("Ignoring failure to delete egress chain " + vmchain_egress) + + remove_rule_log_for_vm(vm_name) + remove_secip_log_for_vm(vm_name) + + if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: + return 'true' + + try: + setscmd = "ipset --save | grep " + vmchain + " | grep '^-N' | awk '{print $2}'" + setsforvm = util.pread2(['/bin/bash', '-c', setscmd]).split('\n') + for set in setsforvm: + if set != '': + util.pread2(['ipset', '-F', set]) + util.pread2(['ipset', '-X', set]) + except: + logging.debug("Failed to destroy ipsets for %" % vm_name) + + + return 'true' + +@echo +def destroy_ebtables_rules(vm_chain): + + delcmd = "ebtables-save | grep " + vm_chain + " | sed 's/-A/-D/'" + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'ebtables') + util.pread2(dc) + except: + logging.debug("Ignoring failure to delete ebtables rules for vm " + vm_chain) + try: + util.pread2(['ebtables', '-F', vm_chain]) + util.pread2(['ebtables', '-X', vm_chain]) + except: + logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_chain) + +@echo +def destroy_arptables_rules(vm_chain): + delcmd = "arptables -vL FORWARD | grep " + vm_chain + " | sed 's/-i any//' | sed 's/-o any//' | awk '{print $1,$2,$3,$4}' " + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'arptables') + dc.insert(1, '-D') + dc.insert(2, 'FORWARD') + util.pread2(dc) + except: + logging.debug("Ignoring failure to delete arptables rules for vm " + vm_chain) + + try: + util.pread2(['arptables', '-F', vm_chain]) + util.pread2(['arptables', '-X', vm_chain]) + except: + logging.debug("Ignoring failure to delete arptables chain for vm " + vm_chain) + +@echo +def default_ebtables_antispoof_rules(vm_chain, vifs, vm_ip, vm_mac): + if vm_mac == 'ff:ff:ff:ff:ff:ff': + logging.debug("Ignoring since mac address is not valid") + return 'true' + + try: + util.pread2(['ebtables', '-N', vm_chain]) + except: + try: + util.pread2(['ebtables', '-F', vm_chain]) + except: + logging.debug("Failed to create ebtables antispoof chain, skipping") + return 'true' + + # note all rules for packets into the bridge (-i) precede all output rules (-o) + # always start after the first rule in the FORWARD chain that jumps to DEFAULT_EBTABLES chain + try: + for vif in vifs: + util.pread2(['ebtables', '-I', 'FORWARD', '2', '-i', vif, '-j', vm_chain]) + util.pread2(['ebtables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) + except: + logging.debug("Failed to program default ebtables FORWARD rules for %s" % vm_chain) + return 'false' + + try: + for vif in vifs: + # only allow source mac that belongs to the vm + try: + util.pread2(['ebtables', '-t', 'nat', '-I', 'PREROUTING', '-i', vif, '-s', '!' , vm_mac, '-j', 'DROP']) + except: + util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) + + # do not allow fake dhcp responses + util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'DROP']) + # do not allow snooping of dhcp requests + util.pread2(['ebtables', '-A', vm_chain, '-o', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'DROP']) + except: + logging.debug("Failed to program default ebtables antispoof rules for %s" % vm_chain) + return 'false' + + return 'true' + +@echo +def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac): + if vm_mac == 'ff:ff:ff:ff:ff:ff': + logging.debug("Ignoring since mac address is not valid") + return 'true' + + try: + util.pread2(['arptables', '-N', vm_chain]) + except: + try: + util.pread2(['arptables', '-F', vm_chain]) + except: + logging.debug("Failed to create arptables rule, skipping") + return 'true' + + # note all rules for packets into the bridge (-i) precede all output rules (-o) + try: + for vif in vifs: + util.pread2(['arptables', '-I', 'FORWARD', '-i', vif, '-j', vm_chain]) + util.pread2(['arptables', '-A', 'FORWARD', '-o', vif, '-j', vm_chain]) + except: + logging.debug("Failed to program default arptables rules in FORWARD chain vm=" + vm_chain) + return 'false' + + try: + for vif in vifs: + #accept arp replies into the bridge as long as the source mac and ips match the vm + util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts + #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination + util.pread2(['arptables', '-A', vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN']) + #accept any arp requests to this vm as long as the request is for this vm's ip + util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp replies to this vm as long as the mac and ip matches + util.pread2(['arptables', '-A', vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT']) + util.pread2(['arptables', '-A', vm_chain, '-j', 'DROP']) + + except: + logging.debug("Failed to program default arptables rules") + return 'false' + + return 'true' + + +@echo +def network_rules_vmSecondaryIp(session, args): + vm_name = args.pop('vmName') + vm_mac = args.pop('vmMac') + ip_secondary = args.pop('vmSecIp') + action = args.pop('action') + logging.debug("vmMac = "+ vm_mac) + logging.debug("vmName = "+ vm_name) + #action = "-A" + logging.debug("action = "+ action) + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + vm_vifs = vm_rec.get('VIFs') + vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs] + domid = vm_rec.get('domid') + except: + logging.debug("### Failed to get domid or vif list for vm ##" + vm_name) + return 'false' + + if domid == '-1': + logging.debug("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vifs = ["vif" + domid + "." + v for v in vifnums] + #vm_name = '-'.join(vm_name.split('-')[:-1]) + vmchain = chain_name(vm_name) + add_to_ipset(vmchain, [ip_secondary], action) + + #add arptables rules for the secondary ip + arp_rules_vmip(vmchain, vifs, [ip_secondary], vm_mac, action) + + return 'true' + +@echo +def default_network_rules_systemvm(session, args): + try: + util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) + except: + can_bridge_firewall(session, args) + + vm_name = args.pop('vmName') + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + vm_vifs = vm_rec.get('VIFs') + vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs] + domid = vm_rec.get('domid') + except: + logging.debug("### Failed to get domid or vif list for vm ##" + vm_name) + return 'false' + + if domid == '-1': + logging.debug("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vifs = ["vif" + domid + "." + v for v in vifnums] + #vm_name = '-'.join(vm_name.split('-')[:-1]) + vmchain = chain_name(vm_name) + + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + + try: + util.pread2(['iptables', '-N', vmchain]) + except: + util.pread2(['iptables', '-F', vmchain]) + + for vif in vifs: + try: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) + util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', 'RETURN']) + except: + logging.debug("Failed to program default rules") + return 'false' + + + util.pread2(['iptables', '-A', vmchain, '-j', 'ACCEPT']) + + if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False: + logging.debug("Failed to log default network rules for systemvm, ignoring") + return 'true' + +@echo +def create_ipset_forvm (ipsetname): + result = True + try: + logging.debug("Creating ipset chain .... " + ipsetname) + util.pread2(['ipset', '-F', ipsetname]) + util.pread2(['ipset', '-X', ipsetname]) + util.pread2(['ipset', '-N', ipsetname, 'iphash']) + except: + logging.debug("ipset chain not exists creating.... " + ipsetname) + util.pread2(['ipset', '-N', ipsetname, 'iphash']) + + return result + +@echo +def add_to_ipset(ipsetname, ips, action): + result = True + for ip in ips: + try: + logging.debug("vm ip " + ip) + util.pread2(['ipset', action, ipsetname, ip]) + except: + logging.debug("vm ip alreday in ip set" + ip) + continue + + return result + +@echo +def arp_rules_vmip (vm_chain, vifs, ips, vm_mac, action): + try: + if action == "-A": + action = "-I" + for vif in vifs: + for vm_ip in ips: + #accept any arp requests to this vm as long as the request is for this vm's ip + util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp replies to this vm as long as the mac and ip matches + util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept arp replies into the bridge as long as the source mac and ips match the vm + util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts + #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination + util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN']) + except: + logging.debug("Failed to program arptables rules for ip") + return 'false' + + return 'true' + + +@echo +def default_network_rules(session, args): + vm_name = args.pop('vmName') + vm_ip = args.pop('vmIP') + vm_id = args.pop('vmID') + vm_mac = args.pop('vmMAC') + sec_ips = args.pop("secIps") + action = "-A" + + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + logging.debug("### Failed to get record for vm " + vm_name) + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + domid = vm_rec.get('domid') + except: + logging.debug("### Failed to get domid for vm " + vm_name) + return 'false' + if domid == '-1': + logging.debug("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + + + vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + destroy_ebtables_rules(vmchain) + + + try: + util.pread2(['iptables', '-N', vmchain]) + except: + util.pread2(['iptables', '-F', vmchain]) + + try: + util.pread2(['iptables', '-N', vmchain_egress]) + except: + util.pread2(['iptables', '-F', vmchain_egress]) + + try: + util.pread2(['iptables', '-N', vmchain_default]) + except: + util.pread2(['iptables', '-F', vmchain_default]) + + vmipset = vm_name + #create ipset and add vm ips to that ip set + if create_ipset_forvm(vmipset) == False: + logging.debug(" failed to create ipset for rule " + str(tokens)) + return 'false' + + #add primary nic ip to ipset + if add_to_ipset(vmipset, [vm_ip], action ) == False: + logging.debug(" failed to add vm " + vm_ip + " ip to set ") + return 'false' + + #add secodnary nic ips to ipset + secIpSet = "1" + ips = sec_ips.split(':') + ips.pop() + if ips[0] == "0": + secIpSet = "0"; + + if secIpSet == "1": + logging.debug("Adding ipset for secondary ips") + add_to_ipset(vmipset, ips, action) + if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False: + logging.debug("Failed to log default network rules, ignoring") + + keyword = '--' + get_ipset_keyword() + + try: + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + + #don't let vm spoof its ip address + for v in vifs: + #util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', '!', keyword, vmipset, 'src', '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-m', 'set', '!', keyword, vmipset, 'dst', '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-j', vmchain_egress]) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) + except: + logging.debug("Failed to program default rules for vm " + vm_name) + return 'false' + + default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + #add default arp rules for secondary ips; + if secIpSet == "1": + logging.debug("Adding arp rules for sec ip") + arp_rules_vmip(vmchain, vifs, ips, vm_mac, action) + + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) + + if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False: + logging.debug("Failed to log default network rules, ignoring") + + logging.debug("Programmed default rules for vm " + vm_name) + return 'true' + +@echo +def check_domid_changed(session, vmName): + curr_domid = '-1' + try: + vm = session.xenapi.VM.get_by_name_label(vmName) + if len(vm) != 1: + logging.debug("### Could not get record for vm ## " + vmName) + else: + vm_rec = session.xenapi.VM.get_record(vm[0]) + curr_domid = vm_rec.get('domid') + except: + logging.debug("### Failed to get domid for vm ## " + vmName) + + + logfilename = "/var/run/cloud/" + vmName +".log" + if not os.path.exists(logfilename): + return ['-1', curr_domid] + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno, _vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno,_vmMac] = line.split(',') + except ValueError,v: + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = line.split(',') + break + + return [curr_domid, old_domid] + +@echo +def delete_rules_for_vm_in_bridge_firewall_chain(vmName): + vm_name = vmName + vmchain = chain_name_def(vm_name) + + delcmd = "iptables-save | grep '\-A BRIDGE-FIREWALL' | grep " + vmchain + " | sed 's/-A/-D/'" + delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n') + delcmds.pop() + for cmd in delcmds: + try: + dc = cmd.split(' ') + dc.insert(0, 'iptables') + dc.pop() + util.pread2(filter(None, dc)) + except: + logging.debug("Ignoring failure to delete rules for vm " + vmName) + + +@echo +def network_rules_for_rebooted_vm(session, vmName): + vm_name = vmName + [curr_domid, old_domid] = check_domid_changed(session, vm_name) + + if curr_domid == old_domid: + return True + + if old_domid == '-1': + return True + + if curr_domid == '-1': + return True + + logging.debug("Found a rebooted VM -- reprogramming rules for " + vm_name) + + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) + if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: + default_network_rules_systemvm(session, {"vmName":vm_name}) + return True + + vif = "vif" + curr_domid + ".0" + tap = "tap" + curr_domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + vmchain = chain_name(vm_name) + vmchain_default = chain_name_def(vm_name) + + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + + #change antispoof rule in vmchain + try: + delcmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | sed 's/!--set/! --set/' | sed 's/-A/-D/'" + delcmd2 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | sed 's/!--set/! --set/'| sed 's/-A/-D/'" + inscmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-in | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' | sed 's/!--set/! --set/'" + inscmd2 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-in | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' | sed 's/!--set/! --set/'" + inscmd3 = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev-out | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' | sed 's/!--set/! --set/'" + inscmd4 = "iptables-save| grep '\-A " + vmchain_default + "' | grep physdev-out | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' | sed 's/!--set/! --set/'" + + ipts = [] + for cmd in [delcmd, delcmd2, inscmd, inscmd2, inscmd3, inscmd4]: + cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n') + cmds.pop() + for c in cmds: + ipt = c.split(' ') + ipt.insert(0, 'iptables') + ipt.pop() + ipts.append(ipt) + + for ipt in ipts: + try: + util.pread2(filter(None,ipt)) + except: + logging.debug("Failed to rewrite antispoofing rules for vm " + vm_name) + except: + logging.debug("No rules found for vm " + vm_name) + + destroy_ebtables_rules(vmchain) + destroy_arptables_rules(vmchain) + [vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain) + default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + + #check wether the vm has secondary ips + if is_secondary_ips_set(vm_name) == True: + vmips = get_vm_sec_ips(vm_name) + #add arp rules for the secondaryp ip + for ip in vmips: + arp_rules_vmip(vmchain, vifs, [ip], vm_mac, "-A") + + + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) + rewrite_rule_log_for_vm(vm_name, curr_domid) + return True + + + +@echo +def get_vm_sec_ips(vm_name): + logfilename = "/var/run/cloud/" + vm_name +".ip" + + lines = (line.rstrip() for line in open(logfilename)) + for line in lines: + try: + [_vmName,_vmIP,_vmID] = line.split(',') + break + except ValueError,v: + [_vmName,_vmIP,_vmID] = line.split(',') + + _vmIPS = _vmIP.split(":")[:-1] + return _vmIPS + +@echo +def is_secondary_ips_set(vm_name): + logfilename = "/var/run/cloud/" + vm_name +".ip" + if not os.path.exists(logfilename): + return False + + return True + +@echo +def rewrite_rule_log_for_vm(vm_name, new_domid): + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + write_rule_log_for_vm(_vmName, _vmID, _vmIP, new_domid, _signature, '-1', _vmMac) + +def get_rule_log_for_vm(session, vmName): + vm_name = vmName; + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return '' + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno]) + +@echo +def get_vm_mac_ip_from_log(vm_name): + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '0.0.0.0', '-1', '_', '-1','ff:ff:ff:ff:ff:ff'] + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + return ['_', '_'] + + lines = (line.rstrip() for line in open(logfilename)) + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',') + break + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + + return [ _vmIP, _vmMac] + +@echo +def get_rule_logs_for_vms(session, args): + host_uuid = args.pop('host_uuid') + try: + thishost = session.xenapi.host.get_by_uuid(host_uuid) + hostrec = session.xenapi.host.get_record(thishost) + vms = hostrec.get('resident_VMs') + except: + logging.debug("Failed to get host from uuid " + host_uuid) + return ' ' + + result = [] + try: + for name in [session.xenapi.VM.get_name_label(x) for x in vms]: + if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-', 'l-'] ]: + continue + network_rules_for_rebooted_vm(session, name) + if name.startswith('i-'): + log = get_rule_log_for_vm(session, name) + result.append(log) + except: + logging.debug("Failed to get rule logs, better luck next time!") + + return ";".join(result) + +@echo +def cleanup_rules_for_dead_vms(session): + try: + vms = session.xenapi.VM.get_all() + cleaned = 0 + for vm_name in [session.xenapi.VM.get_name_label(x) for x in vms]: + if 1 in [ vm_name.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-'] ]: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + continue + vm_rec = session.xenapi.VM.get_record(vm[0]) + state = vm_rec.get('power_state') + if state != 'Running' and state != 'Paused': + logging.debug("vm " + vm_name + " is not running, cleaning up") + destroy_network_rules_for_vm(session, {'vmName':vm_name}) + cleaned = cleaned+1 + + logging.debug("Cleaned up rules for " + str(cleaned) + " vms") + except: + logging.debug("Failed to cleanup rules for dead vms!") + + +@echo +def cleanup_rules(session, args): + instance = args.get('instance') + if not instance: + instance = 'VM' + resident_vms = [] + try: + hostname = util.pread2(['/bin/bash', '-c', 'hostname']).split('\n') + if len(hostname) < 1: + raise Exception('Could not find hostname of this host') + thishost = session.xenapi.host.get_by_name_label(hostname[0]) + if len(thishost) < 1: + raise Exception("Could not find host record from hostname %s of this host"%hostname[0]) + hostrec = session.xenapi.host.get_record(thishost[0]) + vms = hostrec.get('resident_VMs') + resident_vms = [session.xenapi.VM.get_name_label(x) for x in vms] + logging.debug('cleanup_rules: found %s resident vms on this host %s' % (len(resident_vms)-1, hostname[0])) + + chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/'| sed 's/-eg//' | sort|uniq" % instance + chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n') + vmchains = [ch for ch in chains if 1 in [ ch.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-']]] + logging.debug('cleanup_rules: found %s iptables chains for vms on this host %s' % (len(vmchains), hostname[0])) + cleaned = 0 + cleanup = [] + for chain in vmchains: + vmname = chain + if vmname not in resident_vms: + vmname = chain + "-untagged" + if vmname not in resident_vms: + logging.debug("vm " + chain + " is not running on this host, cleaning up") + cleanup.append(chain) + + for vm_name in cleanup: + destroy_network_rules_for_vm(session, {'vmName':vm_name}) + + logging.debug("Cleaned up rules for " + str(len(cleanup)) + " chains") + return str(len(cleanup)) + except Exception, ex: + logging.debug("Failed to cleanup rules, reason= " + str(ex)) + return '-1'; + +@echo +def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): + vm_name = vmName; + logfilename = "/var/run/cloud/" + vm_name +".log" + if not os.path.exists(logfilename): + logging.debug("Failed to find logfile %s" %logfilename) + return [True, True, True] + + lines = (line.rstrip() for line in open(logfilename)) + + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff'] + try: + for line in lines: + try: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno, _vmMac] = line.split(',') + except ValueError,v: + [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',') + break + except: + logging.debug("Failed to parse log file for vm " + vmName) + remove_rule_log_for_vm(vmName) + return [True, True, True] + + reprogramDefault = False + if (domID != _domID) or (vmID != _vmID) or (vmIP != _vmIP): + logging.debug("Change in default info set of vm %s" % vmName) + return [True, True, True] + else: + logging.debug("No change in default info set of vm %s" % vmName) + + reprogramChain = False + rewriteLog = True + if (int(seqno) > int(_seqno)): + if (_signature != signature): + reprogramChain = True + logging.debug("Seqno increased from %s to %s: reprogamming "\ + "ingress rules for vm %s" % (_seqno, seqno, vmName)) + else: + logging.debug("Seqno increased from %s to %s: but no change "\ + "in signature for vm: skip programming ingress "\ + "rules %s" % (_seqno, seqno, vmName)) + elif (int(seqno) < int(_seqno)): + logging.debug("Seqno decreased from %s to %s: ignoring these "\ + "ingress rules for vm %s" % (_seqno, seqno, vmName)) + rewriteLog = False + elif (signature != _signature): + logging.debug("Seqno %s stayed the same but signature changed from "\ + "%s to %s for vm %s" % (seqno, _signature, signature, vmName)) + rewriteLog = True + reprogramChain = True + else: + logging.debug("Seqno and signature stayed the same: %s : ignoring these "\ + "ingress rules for vm %s" % (seqno, vmName)) + rewriteLog = False + + return [reprogramDefault, reprogramChain, rewriteLog] + +@echo +def write_secip_log_for_vm (vmName, secIps, vmId): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" + logging.debug("Writing log to " + logfilename) + logf = open(logfilename, 'w') + output = ','.join([vmName, secIps, vmId]) + result = True + + try: + logf.write(output) + logf.write('\n') + except: + logging.debug("Failed to write to rule log file " + logfilename) + result = False + + logf.close() + + return result + +@echo +def remove_secip_log_for_vm(vmName): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" + + result = True + try: + os.remove(logfilename) + except: + logging.debug("Failed to delete rule log file " + logfilename) + result = False + + return result + +@echo +def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'): + vm_name = vmName + logfilename = "/var/run/cloud/" + vm_name +".log" + logging.debug("Writing log to " + logfilename) + logf = open(logfilename, 'w') + output = ','.join([vmName, vmID, vmIP, domID, signature, seqno, vmMac]) + result = True + try: + logf.write(output) + logf.write('\n') + except: + logging.debug("Failed to write to rule log file " + logfilename) + result = False + + logf.close() + + return result + +@echo +def remove_rule_log_for_vm(vmName): + vm_name = vmName + logfilename = "/var/run/cloud/" + vm_name +".log" + + result = True + try: + os.remove(logfilename) + except: + logging.debug("Failed to delete rule log file " + logfilename) + result = False + + return result + +@echo +def inflate_rules (zipped): + return zlib.decompress(base64.b64decode(zipped)) + +@echo +def cache_ipset_keyword(): + tmpname = 'ipsetqzvxtmp' + try: + util.pread2(['/bin/bash', '-c', 'ipset -N ' + tmpname + ' iptreemap']) + except: + util.pread2(['/bin/bash', '-c', 'ipset -F ' + tmpname]) + + try: + util.pread2(['/bin/bash', '-c', 'iptables -A INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) + util.pread2(['/bin/bash', '-c', 'iptables -D INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT']) + keyword = 'set' + except: + keyword = 'match-set' + + try: + util.pread2(['/bin/bash', '-c', 'ipset -X ' + tmpname]) + except: + pass + + cachefile = "/var/cache/cloud/ipset.keyword" + logging.debug("Writing ipset keyword to " + cachefile) + cachef = open(cachefile, 'w') + try: + cachef.write(keyword) + cachef.write('\n') + except: + logging.debug("Failed to write to cache file " + cachef) + + cachef.close() + return keyword + +@echo +def get_ipset_keyword(): + cachefile = "/var/cache/cloud/ipset.keyword" + keyword = 'match-set' + + if not os.path.exists(cachefile): + logging.debug("Failed to find ipset keyword cachefile %s" %cachefile) + keyword = cache_ipset_keyword() + else: + lines = (line.rstrip() for line in open(cachefile)) + for line in lines: + keyword = line + break + + return keyword + +@echo +def network_rules(session, args): + try: + vm_name = args.get('vmName') + vm_ip = args.get('vmIP') + vm_id = args.get('vmID') + vm_mac = args.get('vmMAC') + signature = args.pop('signature') + seqno = args.pop('seqno') + sec_ips = args.get("secIps") + deflated = 'false' + + try: + util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) + except: + can_bridge_firewall(session, args) + + if 'deflated' in args: + deflated = args.pop('deflated') + + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + logging.debug("### Could not get record for vm ## " + vm_name) + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + domid = vm_rec.get('domid') + except: + logging.debug("### Failed to get domid for vm ## " + vm_name) + return 'false' + if domid == '-1': + logging.debug("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass + + + reason = 'seqno_change_or_sig_change' + [reprogramDefault, reprogramChain, rewriteLog] = \ + check_rule_log_for_vm (vm_name, vm_id, vm_ip, domid, signature, seqno) + + if not reprogramDefault and not reprogramChain: + logging.debug("No changes detected between current state and received state") + reason = 'seqno_same_sig_same' + if rewriteLog: + reason = 'seqno_increased_sig_same' + write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) + logging.debug("Programming network rules for vm %s seqno=%s signature=%s guestIp=%s,"\ + " do nothing, reason=%s" % (vm_name, seqno, signature, vm_ip, reason)) + return 'true' + + if not reprogramChain: + logging.debug("###Not programming any ingress rules since no changes detected?") + return 'true' + + if reprogramDefault: + logging.debug("Change detected in vmId or vmIp or domId, resetting default rules") + default_network_rules(session, args) + reason = 'domid_change' + + rules = args.pop('rules') + if deflated.lower() == 'true': + rules = inflate_rules (rules) + keyword = '--' + get_ipset_keyword() + lines = rules.split(' ') + + logging.debug("Programming network rules for vm %s seqno=%s numrules=%s signature=%s guestIp=%s,"\ + " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason)) + + cmds = [] + egressrules = 0 + for line in lines: + tokens = line.split(':') + if len(tokens) != 5: + continue + type = tokens[0] + protocol = tokens[1] + start = tokens[2] + end = tokens[3] + cidrs = tokens.pop(); + ips = cidrs.split(",") + ips.pop() + allow_any = False + + if type == 'E': + vmchain = egress_chain_name(vm_name) + action = "RETURN" + direction = "dst" + egressrules = egressrules + 1 + else: + vmchain = chain_name(vm_name) + action = "ACCEPT" + direction = "src" + if '0.0.0.0/0' in ips: + i = ips.index('0.0.0.0/0') + del ips[i] + allow_any = True + range = start + ":" + end + if ips: + ipsetname = vmchain + "_" + protocol + "_" + start + "_" + end + if start == "-1": + ipsetname = vmchain + "_" + protocol + "_any" + + if ipset(ipsetname, protocol, start, end, ips) == False: + logging.debug(" failed to create ipset for rule " + str(tokens)) + + if protocol == 'all': + iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] + elif protocol != 'icmp': + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action] + else: + range = start + "/" + end + if start == "-1": + range = "any" + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-m', 'set', keyword, ipsetname, direction, '-j', action] + + cmds.append(iptables) + logging.debug(iptables) + + if allow_any and protocol != 'all': + if protocol != 'icmp': + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', action] + else: + range = start + "/" + end + if start == "-1": + range = "any" + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-j', action] + cmds.append(iptables) + logging.debug(iptables) + + vmchain = chain_name(vm_name) + try: + util.pread2(['iptables', '-F', vmchain]) + except: + logging.debug("Ignoring failure to delete chain " + vmchain) + util.pread2(['iptables', '-N', vmchain]) + + egress_vmchain = egress_chain_name(vm_name) + try: + util.pread2(['iptables', '-F', egress_vmchain]) + except: + logging.debug("Ignoring failure to delete chain " + egress_vmchain) + util.pread2(['iptables', '-N', egress_vmchain]) + + + for cmd in cmds: + util.pread2(cmd) + + if egressrules == 0 : + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'RETURN']) + else: + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'DROP']) + + util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) + + if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) == False: + return 'false' + + return 'true' + except: + logging.debug("Failed to network rule !") + +if __name__ == "__main__": + XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, + "getgateway": getgateway, "preparemigration": preparemigration, + "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, + "createFile": createFile, "deleteFile": deleteFile, + "network_rules":network_rules, + "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, + "destroy_network_rules_for_vm":destroy_network_rules_for_vm, + "default_network_rules_systemvm":default_network_rules_systemvm, + "network_rules_vmSecondaryIp":network_rules_vmSecondaryIp, + "get_rule_logs_for_vms":get_rule_logs_for_vms, + "add_to_VCPUs_params_live":add_to_VCPUs_params_live, + "setLinkLocalIP":setLinkLocalIP, + "cleanup_rules":cleanup_rules, + "createFileInDomr":createFileInDomr, + "kill_copy_process":kill_copy_process}) From 08d7b46be748794773df1f549d3b3dc98068861f Mon Sep 17 00:00:00 2001 From: Mike Tutkowski Date: Fri, 18 Jul 2014 12:02:52 -0600 Subject: [PATCH 121/819] Update to volume-resize logic --- .../SolidFirePrimaryDataStoreDriver.java | 2 +- .../cloud/storage/VolumeApiServiceImpl.java | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java index 5a23fcf399..2228c59f72 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java @@ -423,7 +423,7 @@ public void resize(DataObject dataObject, AsyncCompletionCallback 0) { volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName); } volume.setSize(newSize); - - /** @todo let the storage driver know the CloudStack volume within the storage volume in question has a new size */ } if (newDiskOfferingId != null) { From d4428a93a8df233d5564ae4870649de1d9912f28 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Sun, 20 Jul 2014 18:14:55 +0100 Subject: [PATCH 122/819] Allow for length of password on VMs to be set via global settings Conflicts: server/src/com/cloud/vm/UserVmManagerImpl.java setup/db/db/schema-430to440.sql --- .../src/com/cloud/server/ManagementServerImpl.java | 3 ++- server/src/com/cloud/vm/UserVmManagerImpl.java | 14 +++++++------- setup/db/db/schema-430to440.sql | 2 ++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d822b5961c..99b12732fe 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -895,7 +895,8 @@ protected Map getConfigs() { @Override public String generateRandomPassword() { - return PasswordGenerator.generateRandomPassword(6); + Integer passwordLength = Integer.parseInt(_configDao.getValue("vm.password.length")); + return PasswordGenerator.generateRandomPassword(passwordLength); } @Override diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 2de6f867d6..174f85b2b0 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.server.ManagementService; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -482,6 +483,9 @@ public enum UserVmCloneType { @Inject VolumeOrchestrationService volumeMgr; + @Inject + ManagementService _mgr; + @Override public UserVmVO getVirtualMachine(long vmId) { return _vmDao.findById(vmId); @@ -643,7 +647,7 @@ public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableExce String password = null; String sshPublicKey = s.getPublicKey(); if (template != null && template.getEnablePassword()) { - password = generateRandomPassword(); + password = _mgr.generateRandomPassword(); } boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password); @@ -3362,10 +3366,6 @@ public void finalizeStop(VirtualMachineProfile profile, Answer answer) { } } - public String generateRandomPassword() { - return PasswordGenerator.generateRandomPassword(6); - } - @Override public Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { @@ -3443,7 +3443,7 @@ public Pair> startVirtualMach if (vm.getDetail("password") != null) { password = DBEncryptionUtil.decrypt(vm.getDetail("password")); } else { - password = generateRandomPassword(); + password = _mgr.generateRandomPassword(); } } @@ -4733,7 +4733,7 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) String password = null; if (template.getEnablePassword()) { - password = generateRandomPassword(); + password = _mgr.generateRandomPassword(); boolean result = resetVMPasswordInternal(vmId, password); if (result) { vm.setPassword(password); diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index cff38d0a69..fdf7300d0a 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -2494,3 +2494,5 @@ CREATE TABLE `cloud`.`snapshot_policy_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_snapshot_policy_details__snapshot_policy_id` FOREIGN KEY `fk_snapshot_policy_details__snapshot_policy_id`(`policy_id`) REFERENCES `snapshot_policy`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Secure', 'DEFAULT', 'management-server', 'vm.password.length', '6', 'Specifies the length of a randomly generated password', '6') ON DUPLICATE KEY UPDATE category='Secure'; From 8716376b4af4f520b2f245db36c488859664d9fc Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Wed, 25 Jun 2014 20:01:54 +0100 Subject: [PATCH 123/819] remove unused import --- server/src/com/cloud/vm/UserVmManagerImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 174f85b2b0..5b4f648f67 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -244,7 +244,6 @@ import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.PasswordGenerator; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.RSAHelper; From b6a1d11c90b7f3ea7eb8bebb812db665cf33b094 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Sun, 29 Jun 2014 18:58:07 +0100 Subject: [PATCH 124/819] CLOUDSTACK-7005 - Failed to start MS with latest 4.4 RPM builds Conflicts: setup/db/db/schema-430to440.sql --- setup/db/db/schema-430to440.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index fdf7300d0a..a99ec28a23 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -2495,4 +2495,4 @@ CREATE TABLE `cloud`.`snapshot_policy_details` ( CONSTRAINT `fk_snapshot_policy_details__snapshot_policy_id` FOREIGN KEY `fk_snapshot_policy_details__snapshot_policy_id`(`policy_id`) REFERENCES `snapshot_policy`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Secure', 'DEFAULT', 'management-server', 'vm.password.length', '6', 'Specifies the length of a randomly generated password', '6') ON DUPLICATE KEY UPDATE category='Secure'; +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.password.length', '6', 'Specifies the length of a randomly generated password', '6') ON DUPLICATE KEY UPDATE category='Advanced'; From 8b2efee61c0104b4588e33340606c619b4cf3346 Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Wed, 16 Jul 2014 17:42:14 +0530 Subject: [PATCH 125/819] Fixed coverity reported issues in UserVmManagerImpl --- .../src/com/cloud/vm/UserVmManagerImpl.java | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 5b4f648f67..90f37ef902 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -519,13 +519,14 @@ public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws Re Account caller = CallContext.current().getCallingAccount(); Long vmId = cmd.getId(); UserVmVO userVm = _vmDao.findById(cmd.getId()); - _vmDao.loadDetails(userVm); // Do parameters input validation if (userVm == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + cmd.getId()); } + _vmDao.loadDetails(userVm); + VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId()); if (template == null || !template.getEnablePassword()) { throw new InvalidParameterValueException("Fail to reset password for the virtual machine, the template is not password enabled"); @@ -682,7 +683,7 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance); - if (template != null && template.getEnablePassword()) { + if (template.getEnablePassword()) { vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password); } @@ -855,7 +856,7 @@ public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map 2147483647)) { + if ((cpuNumber == null) || (NumbersUtil.parseInt(cpuNumber, -1) <= 0)) { throw new InvalidParameterValueException("Invalid cpu cores value, specify a value between 1 and 2147483647"); } } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) { @@ -865,7 +866,7 @@ public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map 2147483647)) { + if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) { throw new InvalidParameterValueException("Invalid cpu speed value, specify a value between 1 and 2147483647"); } } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) { @@ -875,7 +876,7 @@ public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map 2147483647)) { + if (memory == null || (NumbersUtil.parseInt(memory, -1) < 32)) { throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and 2147483647 MB"); } } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) { @@ -1151,9 +1152,8 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th NicProfile existing = null; List nicProfiles = _networkMgr.getNicProfiles(vmInstance); for (NicProfile nicProfile : nicProfiles) { - if (nicProfile.isDefaultNic() && nicProfile.getNetworkId() == existingdefaultnet.getId()) { + if (nicProfile.isDefaultNic() && existingdefaultnet != null && nicProfile.getNetworkId() == existingdefaultnet.getId()) { existing = nicProfile; - continue; } } @@ -1192,7 +1192,7 @@ public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) th existingVO.setDeviceId(existingID); nic = _nicDao.persist(nic); - existingVO = _nicDao.persist(existingVO); + _nicDao.persist(existingVO); newdefault = _networkModel.getDefaultNetworkForVm(vmId); if (newdefault.getId() == existingdefaultnet.getId()) { @@ -1271,8 +1271,8 @@ public HashMap> getVmDiskStatistics(long hostId, St return null; } - for (String vmName : vmDiskStatsByName.keySet()) { - vmDiskStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmDiskStatsByName.get(vmName)); + for (Map.Entry> entry: vmDiskStatsByName.entrySet()) { + vmDiskStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue()); } } @@ -1443,8 +1443,8 @@ public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString()); details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString()); List detailList = new ArrayList(); - for (String key : details.keySet()) { - UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key), true); + for (Map.Entry entry: details.entrySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true); detailList.add(detailVO); } _uservmDetailsDao.saveDetails(detailList); @@ -1457,8 +1457,8 @@ public void removeCustomOfferingDetails(long vmId) { details.remove(UsageEventVO.DynamicParameters.cpuSpeed.name()); details.remove(UsageEventVO.DynamicParameters.memory.name()); List detailList = new ArrayList(); - for (String key : details.keySet()) { - UserVmDetailVO detailVO = new UserVmDetailVO(vmId, key, details.get(key), true); + for(Map.Entry entry: details.entrySet()) { + UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true); detailList.add(detailVO); } _uservmDetailsDao.saveDetails(detailList); @@ -1491,8 +1491,8 @@ public HashMap getVirtualMachineStatistics(long hostId, Stri return null; } - for (String vmName : vmStatsByName.keySet()) { - vmStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmStatsByName.get(vmName)); + for (Map.Entry entry : vmStatsByName.entrySet()) { + vmStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue()); } } @@ -1507,7 +1507,7 @@ public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationE Account caller = CallContext.current().getCallingAccount(); // Verify input parameters - final UserVmVO vm = _vmDao.findById(vmId.longValue()); + final UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); @@ -1679,7 +1679,7 @@ public boolean expunge(UserVmVO vm, long callerUserId, Account caller) { } // Only if vm is not expunged already, cleanup it's resources - if (vm != null && vm.getRemoved() == null) { + if (vm.getRemoved() == null) { // Cleanup vm resources - all the PF/LB/StaticNat rules // associated with vm s_logger.debug("Starting cleaning up vm " + vm + " resources..."); @@ -1852,12 +1852,12 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx Account caller = CallContext.current().getCallingAccount(); // Input validation and permission checks - UserVmVO vmInstance = _vmDao.findById(id.longValue()); + UserVmVO vmInstance = _vmDao.findById(id); if (vmInstance == null) { throw new InvalidParameterValueException("unable to find virtual machine with id " + id); } - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, vmInstance); + _accountMgr.checkAccess(caller, null, true, vmInstance); //If the flag is specified and is changed if (isDisplayVm != null && isDisplayVm != vmInstance.isDisplayVm()) { @@ -2075,7 +2075,7 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE Long vmId = cmd.getId(); // Verify input parameters - UserVmVO vmInstance = _vmDao.findById(vmId.longValue()); + UserVmVO vmInstance = _vmDao.findById(vmId); if (vmInstance == null) { throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } @@ -3014,10 +3014,8 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap } _vmDao.persist(vm); - if (customParameters != null && customParameters.size() > 0) { - for (String key : customParameters.keySet()) { - vm.setDetail(key, customParameters.get(key)); - } + for (String key : customParameters.keySet()) { + vm.setDetail(key, customParameters.get(key)); } _vmDao.saveDetails(vm); @@ -3103,7 +3101,7 @@ private void validateUserData(String userData, HTTPMethod httpmethod) { } } - if (decodedUserData.length < 1) { + if (decodedUserData == null || decodedUserData.length < 1) { throw new InvalidParameterValueException("User data is too short"); } } @@ -3511,9 +3509,6 @@ public UserVm destroyVm(long vmId) throws ResourceUnavailableException, Concurre return vm; } - // _accountMgr.checkAccess(caller, null, true, vm); - User userCaller = _userDao.findById(userId); - boolean status; State vmState = vm.getState(); @@ -4152,6 +4147,11 @@ public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinatio long srcHostId = vm.getHostId(); Host srcHost = _resourceMgr.getHost(srcHostId); + + if(srcHost == null ){ + throw new InvalidParameterValueException("Cannot migrate VM, there is not Host with id: " + srcHostId); + } + // Check if src and destination hosts are valid and migrating to same host if (destinationHost.getId() == srcHostId) { throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please" + " specify valid destination host to migrate the VM"); @@ -4697,9 +4697,7 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) newVol = volumeMgr.allocateDuplicateVolume(root, null); } // 1. Save usage event and update resource count for user vm volumes - if (vm instanceof UserVm) { - _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); - } + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); //2. Create Usage event for the newly created volume UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), templateId, newVol.getSize()); _usageEventDao.persist(usageEvent); From 60fb60a91107f2a1ea55a4b39634bbe0ca059fad Mon Sep 17 00:00:00 2001 From: Damodar Date: Mon, 21 Jul 2014 09:31:15 +0530 Subject: [PATCH 126/819] Corrected the error message in egress rule add command --- .../api/command/user/firewall/CreateEgressFirewallRuleCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java index 90aed5e507..1a0cfaed60 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java @@ -242,7 +242,7 @@ public void create() { continue; } if (!NetUtils.isNetworkAWithinNetworkB(cidr, guestCidr)) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, cidr + "is not within the guest cidr " + guestCidr); + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, cidr + " is not within the guest cidr " + guestCidr); } } } From 43dffaad5fd197c87a8dab087066f677a095dee7 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Mon, 21 Jul 2014 12:05:55 +0530 Subject: [PATCH 127/819] Revert "CLOUDSTACK-7107: Disabling failed test case" This reverts commit 186606a0bf82402e7755cd7998f133023cc96c6c. --- test/integration/smoke/test_primary_storage.py | 2 +- test/integration/smoke/test_vm_life_cycle.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 7a4f8d61d8..66aec59b8a 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -51,7 +51,7 @@ def tearDown(self): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false", BugId="7074") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") def test_01_primary_storage_nfs(self): """Test primary storage pools - XEN, KVM, VMWare """ diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index 259c63d896..13868301bb 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -471,7 +471,7 @@ def test_07_restore_vm(self): return - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false", BugId="7107") + @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false") def test_08_migrate_vm(self): """Test migrate VM """ From 03de9cc33507400e0e06ccd84a36334a4660ef4e Mon Sep 17 00:00:00 2001 From: Suresh Ramamurthy Date: Mon, 21 Jul 2014 09:40:45 +0200 Subject: [PATCH 128/819] CLOUDSTACK-6845 : NuageVsp Network plugin Signed-off-by: Hugo Trippaers --- api/src/com/cloud/event/EventTypes.java | 7 + api/src/com/cloud/network/Network.java | 3 + api/src/com/cloud/network/Networks.java | 3 +- .../com/cloud/network/PhysicalNetwork.java | 2 +- .../classes/resources/messages.properties | 5 + .../resources/messages_zh_CN.properties | 5 + client/pom.xml | 20 + client/tomcatconf/commands.properties.in | 7 + .../hypervisor/kvm/resource/OvsVifDriver.java | 4 + .../vmware/resource/VmwareResource.java | 13 + .../resource/CitrixResourceBase.java | 11 +- plugins/network-elements/nuage-vsp/pom.xml | 48 ++ .../META-INF/cloudstack/vsp/module.properties | 21 + .../cloudstack/vsp/spring-vsp-context.xml | 41 ++ .../cloud/agent/api/StartupVspCommand.java | 29 + .../cloud/agent/api/VspResourceAnswer.java | 42 ++ .../cloud/agent/api/VspResourceCommand.java | 82 +++ .../api/element/ApplyAclRuleVspAnswer.java | 34 ++ .../api/element/ApplyAclRuleVspCommand.java | 82 +++ .../api/element/ApplyStaticNatVspAnswer.java | 34 ++ .../api/element/ApplyStaticNatVspCommand.java | 63 +++ .../api/element/ShutDownVpcVspAnswer.java | 34 ++ .../api/element/ShutDownVpcVspCommand.java | 48 ++ .../agent/api/guru/DeallocateVmVspAnswer.java | 34 ++ .../api/guru/DeallocateVmVspCommand.java | 91 +++ .../api/guru/ImplementNetworkVspAnswer.java | 35 ++ .../api/guru/ImplementNetworkVspCommand.java | 124 ++++ .../agent/api/guru/ReleaseVmVspAnswer.java | 34 ++ .../agent/api/guru/ReleaseVmVspCommand.java | 54 ++ .../api/guru/ReserveVmInterfaceVspAnswer.java | 44 ++ .../guru/ReserveVmInterfaceVspCommand.java | 115 ++++ .../agent/api/guru/TrashNetworkVspAnswer.java | 34 ++ .../api/guru/TrashNetworkVspCommand.java | 60 ++ .../cloud/agent/api/sync/SyncVspAnswer.java | 34 ++ .../cloud/agent/api/sync/SyncVspCommand.java | 42 ++ .../api/commands/AddNuageVspDeviceCmd.java | 179 ++++++ .../api/commands/DeleteNuageVspDeviceCmd.java | 105 ++++ .../IssueNuageVspResourceRequestCmd.java | 215 +++++++ .../api/commands/ListNuageVspDevicesCmd.java | 107 ++++ .../com/cloud/api/commands/VspConstants.java | 35 ++ .../api/response/NuageVspDeviceResponse.java | 105 ++++ .../response/NuageVspResourceResponse.java | 41 ++ .../com/cloud/network/NuageVspDeviceVO.java | 98 ++++ .../com/cloud/network/dao/NuageVspDao.java | 36 ++ .../cloud/network/dao/NuageVspDaoImpl.java | 52 ++ .../network/element/NuageVspElement.java | 534 ++++++++++++++++++ .../guru/NuageVspGuestNetworkGuru.java | 416 ++++++++++++++ .../network/manager/NuageVspManager.java | 55 ++ .../network/manager/NuageVspManagerImpl.java | 353 ++++++++++++ .../network/resource/NuageVspResource.java | 467 +++++++++++++++ .../com/cloud/network/sync/NuageVspSync.java | 26 + .../cloud/network/sync/NuageVspSyncImpl.java | 72 +++ .../vsp/acs/NuageVspPluginClientLoader.java | 46 ++ .../vsp/acs/client/NuageVspApiClient.java | 30 + .../vsp/acs/client/NuageVspElementClient.java | 36 ++ .../vsp/acs/client/NuageVspGuruClient.java | 44 ++ .../vsp/acs/client/NuageVspSyncClient.java | 27 + .../network/element/NuageVspElementTest.java | 280 +++++++++ .../guru/NuageVspGuestNetworkGuruTest.java | 386 +++++++++++++ .../network/manager/NuageVspManagerTest.java | 111 ++++ .../resource/NuageVspResourceTest.java | 252 +++++++++ .../cloud/network/sync/NuageVspSyncTest.java | 73 +++ plugins/pom.xml | 11 + .../src/com/cloud/api/ApiResponseHelper.java | 2 +- .../ConfigurationManagerImpl.java | 3 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 3 +- setup/db/db/schema-440to450.sql | 12 + test/integration/component/test_nuage_vsp.py | 312 ++++++++++ tools/apidoc/gen_toc.py | 1 + ui/dictionary.jsp | 5 + ui/scripts/configuration.js | 21 +- ui/scripts/docs.js | 29 + ui/scripts/system.js | 481 +++++++++++++++- ui/scripts/ui-custom/zoneWizard.js | 5 +- .../vmware/mo/HypervisorHostHelper.java | 54 +- 75 files changed, 6424 insertions(+), 35 deletions(-) create mode 100644 plugins/network-elements/nuage-vsp/pom.xml create mode 100644 plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties create mode 100644 plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java create mode 100644 plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java create mode 100644 plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java create mode 100644 plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java create mode 100644 plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java create mode 100644 plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java create mode 100644 plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java create mode 100644 plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java create mode 100644 plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java create mode 100644 plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java create mode 100644 plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java create mode 100644 test/integration/component/test_nuage_vsp.py diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 71bfdb6854..411f620d16 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -428,6 +428,9 @@ public class EventTypes { public static final String EVENT_EXTERNAL_OVS_CONTROLLER_ADD = "PHYSICAL.OVSCONTROLLER.ADD"; public static final String EVENT_EXTERNAL_OVS_CONTROLLER_DELETE = "PHYSICAL.OVSCONTROLLER.DELETE"; + // external network mapping events + public static final String EVENT_EXTERNAL_VSP_VSD_ADD = "PHYSICAL.NUAGE.VSD.ADD"; + public static final String EVENT_EXTERNAL_VSP_VSD_DELETE = "PHYSICAL.NUAGE.VSD.DELETE"; // AutoScale public static final String EVENT_COUNTER_CREATE = "COUNTER.CREATE"; public static final String EVENT_COUNTER_DELETE = "COUNTER.DELETE"; @@ -824,6 +827,10 @@ public class EventTypes { entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_DELETE, "NvpController"); entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController"); + // external network mapping events + entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_ADD, "NuageVsp"); + entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_DELETE, "NuageVsp"); + // AutoScale entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class); entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class); diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 885bffef98..0a08f28104 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -132,6 +132,9 @@ public static class Provider { // add new Ovs provider public static final Provider Ovs = new Provider("Ovs", false); public static final Provider Opendaylight = new Provider("Opendaylight", false); + // add Nuage Vsp Providers + public static final Provider NuageVsp = new Provider("NuageVsp", false); + public static final Provider NuageVspVpc = new Provider("NuageVspVpc", false); private final String name; private final boolean isExternal; diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index 1e4d229464..1ad33509fb 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -109,7 +109,8 @@ public URI toUri(T value) { } } }, - UnDecided(null, null), OpenDaylight("opendaylight", String.class); + UnDecided(null, null), OpenDaylight("opendaylight", String.class), + Vsp("vsp", String.class),; private final String scheme; private final Class type; diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 8cc214e894..024b3cedec 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -33,7 +33,7 @@ public enum State { } public enum IsolationMethod { - VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN; + VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN, VSP; } public enum BroadcastDomainRange { diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index b192cb0e78..bb75b08a27 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -327,6 +327,7 @@ label.add.new.SRX=Add new SRX label.add.new.PA=Add new Palo Alto label.add.new.tier=Add new tier label.add.NiciraNvp.device=Add Nvp Controller +label.add.NuageVsp.device=Add Nuage Virtualized Services Directory (VSD) label.add.physical.network=Add physical network label.add.pod=Add Pod label.add.port.forwarding.rule=Add port forwarding rule @@ -387,6 +388,7 @@ label.anti.affinity.group=Anti-affinity Group label.anti.affinity.groups=Anti-affinity Groups label.anti.affinity=Anti-affinity label.api.key=API Key +label.api.version=API Version label.apply=Apply label.assign.to.load.balancer=Assigning instance to load balancer label.assign=Assign @@ -501,6 +503,7 @@ label.delete.F5=Delete F5 label.delete.gateway=delete gateway label.delete.NetScaler=Delete NetScaler label.delete.NiciraNvp=Remove Nvp Controller +label.delete.NuageVsp=Remove Nuage VSD label.delete.project=Delete project label.delete.SRX=Delete SRX label.delete.PA=Delete Palo Alto @@ -1009,6 +1012,7 @@ label.restart.network=Restart network label.restart.required=Restart required label.restart.vpc=restart VPC label.restore=Restore +label.retry.interval=Retry Interval label.review=Review label.revoke.project.invite=Revoke invitation label.role=Role @@ -1631,6 +1635,7 @@ message.configuring.storage.traffic=Configuring storage traffic message.confirm.action.force.reconnect=Please confirm that you want to force reconnect this host. message.confirm.delete.F5=Please confirm that you would like to delete F5 message.confirm.delete.NetScaler=Please confirm that you would like to delete NetScaler +message.confirm.delete.NuageVsp=Please confirm that you would like to delete Nuage Virtualized Services Directory message.confirm.delete.SRX=Please confirm that you would like to delete SRX message.confirm.delete.PA=Please confirm that you would like to delete Palo Alto message.confirm.destroy.router=Please confirm that you would like to destroy this router diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties index 1ec4e9537a..d7a0ca9ba6 100644 --- a/client/WEB-INF/classes/resources/messages_zh_CN.properties +++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties @@ -297,6 +297,7 @@ label.add.new.SRX=\u6dfb\u52a0\u65b0 SRX label.add.new.tier=\u6dfb\u52a0\u65b0\u5c42 label.add.nfs.secondary.staging.store=\u6dfb\u52a0 NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.add.NiciraNvp.device=\u6dfb\u52a0 Nvp \u63a7\u5236\u5668 +label.add.NuageVsp.device=\u6DFB\u52A0 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 (VSD) label.add.OpenDaylight.device=\u6dfb\u52a0 OpenDaylight \u63a7\u5236\u5668 label.add.PA.device=\u6dfb\u52a0 Palo Alto \u8bbe\u5907 label.add.physical.network=\u6dfb\u52a0\u7269\u7406\u7f51\u7edc @@ -355,6 +356,7 @@ label.anti.affinity.groups=\u53cd\u5173\u8054\u6027\u7ec4 label.anti.affinity.group=\u53cd\u5173\u8054\u6027\u7ec4 label.anti.affinity=\u53cd\u5173\u8054\u6027 label.api.key=API \u5bc6\u94a5 +label.api.version=API \u7248\u672C label.apply=\u5e94\u7528 label.app.name=CloudStack label.archive.alerts=\u5b58\u6863\u8b66\u62a5 @@ -508,6 +510,7 @@ label.delete.F5=\u5220\u9664 F5 label.delete.gateway=\u5220\u9664\u7f51\u5173 label.delete.NetScaler=\u5220\u9664 NetScaler label.delete.NiciraNvp=\u79fb\u9664 Nvp \u63a7\u5236\u5668 +label.delete.NuageVsp=\u5220\u9664 Nuage VSD label.delete.OpenDaylight.device=\u5220\u9664 OpenDaylight \u63a7\u5236\u5668 label.delete.PA=\u5220\u9664 Palo Alto label.delete.portable.ip.range=\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 @@ -1142,6 +1145,7 @@ label.restart.network=\u91cd\u65b0\u542f\u52a8\u7f51\u7edc label.restart.required=\u9700\u8981\u91cd\u65b0\u542f\u52a8 label.restart.vpc=\u91cd\u65b0\u542f\u52a8 VPC label.restore=\u8fd8\u539f +label.retry.interval=\u91cd\u8bd5\u95f4\u9694 label.review=\u6838\u5bf9 label.revoke.project.invite=\u64a4\u9500\u9080\u8bf7 label.role=\u89d2\u8272 @@ -1607,6 +1611,7 @@ message.confirm.dedicate.zone=\u662f\u5426\u8981\u5c06\u6b64\u8d44\u6e90\u57df\u message.confirm.delete.ciscovnmc.resource=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 CiscoVNMC \u8d44\u6e90 message.confirm.delete.F5=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 F5 message.confirm.delete.NetScaler=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 NetScaler +message.confirm.delete.NuageVsp=\u8BF7\u786E\u8BA4\u5220\u9664 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 message.confirm.delete.PA=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 Palo Alto message.confirm.delete.secondary.staging.store=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u3002 message.confirm.delete.SRX=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 SRX diff --git a/client/pom.xml b/client/pom.xml index 46933d92c0..1621a05bab 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -105,6 +105,11 @@ cloud-plugin-network-netscaler ${project.version} + + org.apache.cloudstack + cloud-plugin-network-vsp + ${project.version} + org.apache.cloudstack cloud-plugin-network-ovs @@ -943,6 +948,21 @@ + + nuagevsp + + + noredist + + + + + org.apache.cloudstack + cloud-plugin-network-vsp + ${project.version} + + + srx diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index b9ac27b0ba..aa03949fa4 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -618,6 +618,13 @@ listBigSwitchVnsDevices=1 addStratosphereSsp=1 deleteStratoshereSsp=1 +#### nuage vsp commands + +addNuageVspDevice=1 +deleteNuageVspDevice=1 +listNuageVspDevices=1 +issueNuageVspResourceRequest=15 + #### host simulator commands configureSimulator=1 diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java index 8e4c7106b9..1420682006 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java @@ -93,6 +93,10 @@ public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throw String brName = "OVSTunnel" + vnetId; s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + brName); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); + } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vsp) { + intf.setVirtualPortInterfaceId(nic.getUuid()); + String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private"); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); } else { intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 0922765928..7b73b19e34 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -931,6 +931,7 @@ private PlugNicAnswer execute(PlugNicCommand cmd) { deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); vmConfigSpec.getDeviceChange().add(deviceConfigSpec); + setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo); if (!vmMo.configureVm(vmConfigSpec)) { throw new Exception("Failed to configure devices when running PlugNicCommand"); } @@ -1900,11 +1901,23 @@ private static void configNvpExtraOption(List extraOptions, Virtual newVal.setKey("nvp.iface-id." + nicNum); newVal.setValue(nicTo.getUuid()); extraOptions.add(newVal); + setNuageVspVrIpInExtraConfig(extraOptions, nicTo); } nicNum++; } } + private static void setNuageVspVrIpInExtraConfig(List extraOptions, NicTO nicTo) { + URI broadcastUri = nicTo.getBroadcastUri(); + if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) { + String path = broadcastUri.getPath(); + OptionValue newVal = new OptionValue(); + newVal.setKey("vsp.vr-ip." + nicTo.getMac()); + newVal.setValue(path.substring(1)); + extraOptions.add(newVal); + } + } + private static void configCustomExtraOption(List extraOptions, VirtualMachineTO vmSpec) { // we no longer to validation anymore for (Map.Entry entry : vmSpec.getDetails().entrySet()) { diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index a2b96259e4..71aa01e6b6 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1037,7 +1037,8 @@ protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException, assert (BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Vlan); long vlan = Long.parseLong(BroadcastDomainType.getValue(uri)); return enableVlanNetwork(conn, vlan, network); - } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal) { + } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal || + type == BroadcastDomainType.Vsp) { return network.getNetwork(); } else if (uri != null && type == BroadcastDomainType.Vswitch) { String header = uri.toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length()); @@ -1105,6 +1106,13 @@ protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO // when bridge is setup for distributed routing vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid()); + // Nuage Vsp needs Virtual Router IP to be passed in the otherconfig + // get the virtual router IP information from broadcast uri + URI broadcastUri = nic.getBroadcastUri(); + if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) { + String path = broadcastUri.getPath(); + vifr.otherConfig.put("vsp-vr-ip", path.substring(1)); + } vifr.network = getNetwork(conn, nic); if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) { @@ -1302,6 +1310,7 @@ protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host vmr.nameLabel = vmSpec.getName(); vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY; vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY; + vmr.otherConfig.put("vm_uuid", vmSpec.getUuid()); if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { //scaling is allowed diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml new file mode 100644 index 0000000000..694ebf026e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + cloud-plugin-network-vsp + Apache CloudStack Plugin - Nuage VSP + + org.apache.cloudstack + cloudstack-plugins + 4.5.0-SNAPSHOT + ../../pom.xml + + + + + com.mycila + license-maven-plugin + + + cloudstack-checklicence + process-classes + + check + + + + + + + \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties new file mode 100644 index 0000000000..e51229e199 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties @@ -0,0 +1,21 @@ +# +# 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. +# + +name=vsp +parent=network \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml new file mode 100644 index 0000000000..c579789e5e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java new file mode 100644 index 0000000000..6dba8820a8 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java @@ -0,0 +1,29 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api; + +import com.cloud.host.Host; + +public class StartupVspCommand extends StartupCommand { + + public StartupVspCommand() { + super(Host.Type.L2Networking); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java new file mode 100644 index 0000000000..9327809a0e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.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.agent.api; + +public class VspResourceAnswer extends Answer { + + String _resourceInfo; + + public VspResourceAnswer(Command cmd, String resourceInfo, String details) { + super(cmd, true, details); + this._resourceInfo = resourceInfo; + } + + public VspResourceAnswer(VspResourceCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public VspResourceAnswer(VspResourceCommand cmd, Exception e) { + super(cmd, e); + } + + public String getResourceInfo() { + return this._resourceInfo; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java new file mode 100644 index 0000000000..f7e1417aed --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java @@ -0,0 +1,82 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api; + +public class VspResourceCommand extends Command { + + String _method; + String _resource; + String _resourceId; + String _childResource; + Object _entityDetails; + String _resourceFilter; + String _proxyUserUuid; + String _proxyUserDomainuuid; + + public VspResourceCommand(String method, String resource, String resourceId, String childResource, Object entityDetails, String resourceFilter, String proxyUserUuid, + String proxyUserDomainuuid) { + super(); + this._method = method; + this._resource = resource; + this._resourceId = resourceId; + this._childResource = childResource; + this._entityDetails = entityDetails; + this._resourceFilter = resourceFilter; + this._proxyUserUuid = proxyUserUuid; + this._proxyUserDomainuuid = proxyUserDomainuuid; + } + + public String getRequestType() { + return _method; + } + + public String getResource() { + return _resource; + } + + public String getResourceId() { + return _resourceId; + } + + public String getChildResource() { + return _childResource; + } + + public Object getEntityDetails() { + return _entityDetails; + } + + public String getResourceFilter() { + return _resourceFilter; + } + + public String getProxyUserUuid() { + return _proxyUserUuid; + } + + public String getProxyUserDomainuuid() { + return _proxyUserDomainuuid; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java new file mode 100644 index 0000000000..2b41266f02 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ApplyAclRuleVspAnswer extends Answer { + + public ApplyAclRuleVspAnswer(ApplyAclRuleVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ApplyAclRuleVspAnswer(ApplyAclRuleVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java new file mode 100644 index 0000000000..5376466937 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java @@ -0,0 +1,82 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Command; + +public class ApplyAclRuleVspCommand extends Command { + + String _networkUuid; + String _networkDomainUuid; + String _vpcOrSubnetUuid; + boolean _isL3Network; + List> _aclRules; + boolean _isVpc; + long _networkId; + + public ApplyAclRuleVspCommand(String networkUuid, String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> aclRules, boolean isVpc, + long networkId) { + super(); + this._networkUuid = networkUuid; + this._networkDomainUuid = networkDomainUuid; + this._vpcOrSubnetUuid = vpcOrSubnetUuid; + this._isL3Network = isL3Network; + this._aclRules = aclRules; + this._isVpc = isVpc; + this._networkId = networkId; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getVpcOrSubnetUuid() { + return _vpcOrSubnetUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public List> getAclRules() { + return _aclRules; + } + + public boolean isVpc() { + return _isVpc; + } + + public long getNetworkId() { + return this._networkId; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java new file mode 100644 index 0000000000..c40c1a312f --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ApplyStaticNatVspAnswer extends Answer { + + public ApplyStaticNatVspAnswer(ApplyStaticNatVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ApplyStaticNatVspAnswer(ApplyStaticNatVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java new file mode 100644 index 0000000000..b013634e37 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java @@ -0,0 +1,63 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Command; + +public class ApplyStaticNatVspCommand extends Command { + + String _networkDomainUuid; + String _vpcOrSubnetUuid; + boolean _isL3Network; + List> _staticNatDetails; + + public ApplyStaticNatVspCommand(String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> staticNatDetails) { + super(); + this._networkDomainUuid = networkDomainUuid; + this._vpcOrSubnetUuid = vpcOrSubnetUuid; + this._isL3Network = isL3Network; + this._staticNatDetails = staticNatDetails; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getVpcOrSubnetUuid() { + return _vpcOrSubnetUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public List> getStaticNatDetails() { + return _staticNatDetails; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java new file mode 100644 index 0000000000..592216e12e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ShutDownVpcVspAnswer extends Answer { + + public ShutDownVpcVspAnswer(ShutDownVpcVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ShutDownVpcVspAnswer(ShutDownVpcVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java new file mode 100644 index 0000000000..fc05559514 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java @@ -0,0 +1,48 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.element; + +import com.cloud.agent.api.Command; + +public class ShutDownVpcVspCommand extends Command { + + String _domainUuid; + String _vpcUuid; + + public ShutDownVpcVspCommand(String domainUuid, String vpcUuid) { + super(); + this._domainUuid = domainUuid; + this._vpcUuid = vpcUuid; + } + + public String getDomainUuid() { + return _domainUuid; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java new file mode 100644 index 0000000000..57ecf296cd --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class DeallocateVmVspAnswer extends Answer { + + public DeallocateVmVspAnswer(Command command, Exception e) { + super(command, e); + } + + public DeallocateVmVspAnswer(DeallocateVmVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java new file mode 100644 index 0000000000..19c904f9f2 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java @@ -0,0 +1,91 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class DeallocateVmVspCommand extends Command { + + String _networkUuid; + String _nicFrmDdUuid; + String _nicMacAddress; + String _nicIp4Address; + boolean _isL3Network; + String _vpcUuid; + String _networksDomainUuid; + String _vmInstanceName; + String _vmUuid; + + public DeallocateVmVspCommand(String networkUuid, String nicFrmDdUuid, String nicMacAddress, String nicIp4Address, boolean isL3Network, String vpcUuid, + String networksDomainUuid, String vmInstanceName, String vmUuid) { + super(); + this._networkUuid = networkUuid; + this._nicFrmDdUuid = nicFrmDdUuid; + this._nicMacAddress = nicMacAddress; + this._nicIp4Address = nicIp4Address; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + this._networksDomainUuid = networksDomainUuid; + this._vmInstanceName = vmInstanceName; + this._vmUuid = vmUuid; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getNicFrmDdUuid() { + return _nicFrmDdUuid; + } + + public String getNicMacAddress() { + return _nicMacAddress; + } + + public String getNicIp4Address() { + return _nicIp4Address; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public String getNetworksDomainUuid() { + return _networksDomainUuid; + } + + public String getVmInstanceName() { + return _vmInstanceName; + } + + public String getVmUuid() { + return _vmUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java new file mode 100644 index 0000000000..87e7b32826 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java @@ -0,0 +1,35 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ImplementNetworkVspAnswer extends Answer { + + public ImplementNetworkVspAnswer(Command command, Exception e) { + super(command, e); + } + + public ImplementNetworkVspAnswer(ImplementNetworkVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java new file mode 100644 index 0000000000..0ffbda42a3 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java @@ -0,0 +1,124 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import java.util.Collection; + +import com.cloud.agent.api.Command; + +public class ImplementNetworkVspCommand extends Command { + + String _networkDomainName; + String _networkDomainPath; + String _networkDomainUuid; + String _networkAccountName; + String _networkAccountUuid; + String _networkName; + String _networkCidr; + String _networkGateway; + String _networkUuid; + boolean _isL3Network; + String _vpcName; + String _vpcUuid; + boolean _defaultEgressPolicy; + Collection _ipAddressRange; + + public ImplementNetworkVspCommand(String networkDomainName, String networkDomainPath, String networkDomainUuid, String networkAccountName, String networkAccountUuid, + String networkName, String networkCidr, String networkGateway, String networkUuid, boolean isL3Network, String vpcName, String vpcUuid, boolean defaultEgressPolicy, + Collection ipAddressRange) { + super(); + this._networkDomainName = networkDomainName; + this._networkDomainPath = networkDomainPath; + this._networkDomainUuid = networkDomainUuid; + this._networkAccountName = networkAccountName; + this._networkAccountUuid = networkAccountUuid; + this._networkName = networkName; + this._networkCidr = networkCidr; + this._networkGateway = networkGateway; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcName = vpcName; + this._vpcUuid = vpcUuid; + this._defaultEgressPolicy = defaultEgressPolicy; + this._ipAddressRange = ipAddressRange; + } + + public String getNetworkDomainName() { + return _networkDomainName; + } + + public String getNetworkDomainPath() { + return _networkDomainPath; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getNetworkAccountName() { + return _networkAccountName; + } + + public String getNetworkAccountUuid() { + return _networkAccountUuid; + } + + public String getNetworkName() { + return _networkName; + } + + public String getNetworkCidr() { + return _networkCidr; + } + + public String getNetworkGateway() { + return _networkGateway; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcName() { + return _vpcName; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public boolean isDefaultEgressPolicy() { + return _defaultEgressPolicy; + } + + public Collection getIpAddressRange() { + return _ipAddressRange; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java new file mode 100644 index 0000000000..8bc8e4c4da --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ReleaseVmVspAnswer extends Answer { + + public ReleaseVmVspAnswer(Command command, Exception e) { + super(command, e); + } + + public ReleaseVmVspAnswer(ReleaseVmVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java new file mode 100644 index 0000000000..9a6a4d7cbb --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java @@ -0,0 +1,54 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class ReleaseVmVspCommand extends Command { + + String _networkUuid; + String _vmUuid; + String _vmInstanceName; + + public ReleaseVmVspCommand(String networkUuid, String vmUuid, String vmInstanceName) { + super(); + this._networkUuid = networkUuid; + this._vmUuid = vmUuid; + this._vmInstanceName = vmInstanceName; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getVmUuid() { + return _vmUuid; + } + + public String getVmInstanceName() { + return _vmInstanceName; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java new file mode 100644 index 0000000000..8fabbef037 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java @@ -0,0 +1,44 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ReserveVmInterfaceVspAnswer extends Answer { + + public List> _interfaceDetails; + + public ReserveVmInterfaceVspAnswer(Command cmd, List> interfaceDetails, String details) { + super(cmd, true, details); + this._interfaceDetails = interfaceDetails; + } + + public ReserveVmInterfaceVspAnswer(Command cmd, Exception e) { + super(cmd, e); + } + + public List> getInterfaceDetails() { + return this._interfaceDetails; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java new file mode 100644 index 0000000000..6844bf9d1b --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java @@ -0,0 +1,115 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class ReserveVmInterfaceVspCommand extends Command { + + String _nicUuid; + String _nicMacAddress; + String _networkUuid; + boolean _isL3Network; + String _vpcUuid; + String _networkDomainUuid; + String _networksAccountUuid; + boolean _isDomainRouter; + String _domainRouterIp; + String _vmInstanceName; + String _vmUuid; + String _vmUserName; + String _vmUserDomainName; + + public ReserveVmInterfaceVspCommand(String nicUuid, String nicMacAddress, String networkUuid, boolean isL3Network, String vpcUuid, String networkDomainUuid, + String networksAccountUuid, boolean isDomainRouter, String domainRouterIp, String vmInstanceName, String vmUuid, String vmUserName, String vmUserDomainName) { + super(); + this._nicUuid = nicUuid; + this._nicMacAddress = nicMacAddress; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + this._networkDomainUuid = networkDomainUuid; + this._networksAccountUuid = networksAccountUuid; + this._isDomainRouter = isDomainRouter; + this._domainRouterIp = domainRouterIp; + this._vmInstanceName = vmInstanceName; + this._vmUuid = vmUuid; + this._vmUserName = vmUserName; + this._vmUserDomainName = vmUserDomainName; + } + + public String getNicUuid() { + return _nicUuid; + } + + public String getNicMacAddress() { + return _nicMacAddress; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getNetworksAccountUuid() { + return _networksAccountUuid; + } + + public boolean isDomainRouter() { + return _isDomainRouter; + } + + public String _getDomainRouterIp() { + return _domainRouterIp; + } + + public String _getVmInstanceName() { + return _vmInstanceName; + } + + public String _getVmUuid() { + return _vmUuid; + } + + public String _getVmUserName() { + return _vmUserName; + } + + public String _getVmUserDomainName() { + return _vmUserDomainName; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java new file mode 100644 index 0000000000..0c0c0d2eee --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class TrashNetworkVspAnswer extends Answer { + + public TrashNetworkVspAnswer(Command command, Exception e) { + super(command, e); + } + + public TrashNetworkVspAnswer(TrashNetworkVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java new file mode 100644 index 0000000000..e10e9beb00 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java @@ -0,0 +1,60 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class TrashNetworkVspCommand extends Command { + + String _domainUuid; + String _networkUuid; + boolean _isL3Network; + String _vpcUuid; + + public TrashNetworkVspCommand(String domainUuid, String networkUuid, boolean isL3Network, String vpcUuid) { + super(); + this._domainUuid = domainUuid; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + } + + public String getDomainUuid() { + return _domainUuid; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java new file mode 100644 index 0000000000..52848e558a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java @@ -0,0 +1,34 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.agent.api.sync; + +import com.cloud.agent.api.Answer; + +public class SyncVspAnswer extends Answer { + + public SyncVspAnswer(SyncVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public SyncVspAnswer(SyncVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java new file mode 100644 index 0000000000..8ccd84db55 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.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.agent.api.sync; + +import com.cloud.agent.api.Command; + +public class SyncVspCommand extends Command { + + String _nuageVspEntity; + + public SyncVspCommand(String nuageVspEntity) { + super(); + this._nuageVspEntity = nuageVspEntity; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getNuageVspEntity() { + return _nuageVspEntity; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java new file mode 100644 index 0000000000..19f2d09b39 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java @@ -0,0 +1,179 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.event.EventTypes; +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.NuageVspDeviceVO; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "addNuageVspDevice", responseObject = NuageVspDeviceResponse.class, description = "Adds a Nuage VSP device") +public class AddNuageVspDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "addnuagevspdeviceresponse"; + + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = BaseCmd.CommandType.UUID, entityType = PhysicalNetworkResponse.class, + required = true, description = "the ID of the physical network in to which Nuage VSP is added") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_PORT, type = CommandType.INTEGER, required = true, description = "the port to communicate to Nuage VSD") + private int port; + + @Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "the hostname of the Nuage VSD") + private String hostName; + + @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "the user name of the CMS user in Nuage VSD") + private String userName; + + @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "the password of CMS user in Nuage VSD") + private String password; + + @Parameter(name = VspConstants.NUAGE_VSP_API_VERSION, type = CommandType.STRING, required = true, description = "the version of the API to use to communicate to Nuage VSD") + private String apiVersion; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RETRY_COUNT, type = CommandType.INTEGER, required = true, description = "the number of retries on failure to communicate to Nuage VSD") + private int apiRetryCount; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RETRY_INTERVAL, type = CommandType.LONG, required = true, description = "the time to wait after failure before retrying to communicate to Nuage VSD") + private long apiRetryInterval; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public String getUserName() { + return userName; + } + + public String getPassword() { + return password; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public int getApiRetryCount() { + return apiRetryCount; + } + + public void setApiRetryCount(int apiRetryCount) { + this.apiRetryCount = apiRetryCount; + } + + public long getApiRetryInterval() { + return apiRetryInterval; + } + + public void setApiRetryInterval(long apiRetryInterval) { + this.apiRetryInterval = apiRetryInterval; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + NuageVspDeviceVO nuageVspDeviceVO = _nuageVspManager.addNuageVspDevice(this); + if (nuageVspDeviceVO != null) { + NuageVspDeviceResponse response = _nuageVspManager.createNuageVspDeviceResponse(nuageVspDeviceVO); + response.setObjectName("nuagevspdevice"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Nuage VSP device due to internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_VSP_VSD_ADD; + } + + @Override + public String getEventDescription() { + return "Adding a Nuage VSD"; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java new file mode 100644 index 0000000000..ae81c847bf --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java @@ -0,0 +1,105 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "deleteNuageVspDevice", responseObject = SuccessResponse.class, description = "delete a nuage vsp device") +public class DeleteNuageVspDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "deletenuagevspdeviceresponse"; + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = VspConstants.NUAGE_VSP_DEVICE_ID, type = CommandType.UUID, entityType = NuageVspDeviceResponse.class, required = true, description = "Nuage device ID") + private Long nuageVspDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNuageVspDeviceId() { + return nuageVspDeviceId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result = _nuageVspManager.deleteNuageVspDevice(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Nuage device."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_VSP_VSD_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting Nuage VSD"; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java new file mode 100644 index 0000000000..f0e3ff8fd8 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java @@ -0,0 +1,215 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.NetworkOfferingResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.VspResourceAnswer; +import com.cloud.agent.api.VspResourceCommand; +import com.cloud.api.response.NuageVspResourceResponse; +import com.cloud.domain.dao.DomainDao; +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.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +@APICommand(name = "issueNuageVspResourceRequest", responseObject = NuageVspResourceResponse.class, description = "Issues a Nuage VSP REST API resource request") +public class IssueNuageVspResourceRequestCmd extends BaseCmd { + private static final Logger s_logger = Logger.getLogger(IssueNuageVspResourceRequestCmd.class.getName()); + private static final String s_name = "nuagevspresourceresponse"; + + @Inject + protected AccountManager _accountMgr; + @Inject + protected DomainDao _domainDao; + @Inject + protected NuageVspDao _nuageConfigDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, required = true, description = "the network offering id") + private Long networkOfferingId; + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the Zone ID for the network") + private Long zoneId; + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the ID of the physical network in to which Nuage VSP Controller is added") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_METHOD, type = CommandType.STRING, required = true, description = "the Nuage VSP REST API method type") + private String method; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE, type = CommandType.STRING, required = true, description = "the resource in Nuage VSP") + private String resource; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE_ID, type = CommandType.STRING, description = "the ID of the resource in Nuage VSP") + private String resourceId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_CHILD_RESOURCE, type = CommandType.STRING, description = "the child resource in Nuage VSP") + private String childResource; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE_FILTER, type = CommandType.STRING, description = "the resource filter in Nuage VSP") + private String resourceFilter; + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + public Long getNetworkOfferingId() { + return networkOfferingId; + } + + public Long getZoneId() { + Long physicalNetworkId = getPhysicalNetworkId(); + + if (physicalNetworkId == null && zoneId == null) { + throw new InvalidParameterValueException("Zone id is required"); + } + + return zoneId; + } + + public Long getPhysicalNetworkId() { + if (physicalNetworkId != null) { + return physicalNetworkId; + } + + NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, networkOfferingId); + if (offering == null) { + throw new InvalidParameterValueException("Unable to find network offering by id " + networkOfferingId); + } + + if (zoneId == null) { + throw new InvalidParameterValueException("ZoneId is required as physicalNetworkId is null"); + } + return _networkService.findPhysicalNetworkId(zoneId, offering.getTags(), offering.getTrafficType()); + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getChildResource() { + return childResource; + } + + public void setChildResource(String childResource) { + this.childResource = childResource; + } + + public String getResourceFilter() { + return resourceFilter; + } + + public void setResourceFilter(String resourceFilter) { + this.resourceFilter = resourceFilter; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + long accountId = CallContext.current().getCallingAccount().getAccountId(); + Account account = _accountMgr.getAccount(accountId); + + List nuageVspDevices = _nuageConfigDao.listByPhysicalNetwork(getPhysicalNetworkId()); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + HostVO nuageVspHost = _hostDao.findById(config.getHostId()); + VspResourceCommand cmd = new VspResourceCommand(method, resource, resourceId, childResource, null, resourceFilter, null, null); + VspResourceAnswer answer = (VspResourceAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("VspResourceCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, answer.getDetails()); + } + } else { + NuageVspResourceResponse response = new NuageVspResourceResponse(); + response.setResourceInfo(StringUtils.isBlank(answer.getResourceInfo()) ? "" : answer.getResourceInfo()); + response.setObjectName("nuagevspresource"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + } else { + String errorMessage = "No Nuage VSP Controller configured on physical network " + getPhysicalNetworkId(); + s_logger.error(errorMessage); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMessage); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java new file mode 100644 index 0000000000..46797e0af0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java @@ -0,0 +1,107 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; + +import com.cloud.api.response.NuageVspDeviceResponse; +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.NuageVspDeviceVO; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "listNuageVspDevices", responseObject = NuageVspDeviceResponse.class, description = "Lists Nuage VSP devices") +public class ListNuageVspDevicesCmd extends BaseListCmd { + private static final String s_name = "listnuagevspdeviceresponse"; + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the Physical Network ID") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_DEVICE_ID, type = CommandType.UUID, entityType = NuageVspDeviceResponse.class, description = "the Nuage VSP device ID") + private Long nuageVspDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNuageVspDeviceId() { + return nuageVspDeviceId; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + List nuageDevices = _nuageVspManager.listNuageVspDevices(this); + ListResponse response = new ListResponse(); + List nuageDevicesResponse = new ArrayList(); + + if (nuageDevices != null && !nuageDevices.isEmpty()) { + for (NuageVspDeviceVO nuageDeviceVO : nuageDevices) { + NuageVspDeviceResponse nuageDeviceResponse = _nuageVspManager.createNuageVspDeviceResponse(nuageDeviceVO); + nuageDevicesResponse.add(nuageDeviceResponse); + } + } + + response.setResponses(nuageDevicesResponse); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java new file mode 100644 index 0000000000..237289064a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java @@ -0,0 +1,35 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +public class VspConstants { + public static final String NUAGE_VSP_DEVICE_ID = "vspdeviceid"; + public static final String NUAGE_VSP_DEVICE_NAME = "nuagedevicename"; + public static final String NUAGE_VSP_API_PORT = "port"; + public static final String NUAGE_VSP_API_VERSION = "apiversion"; + public static final String NUAGE_VSP_API_RETRY_COUNT = "retrycount"; + public static final String NUAGE_VSP_API_RETRY_INTERVAL = "retryinterval"; + public static final String NUAGE_VSP_API_METHOD = "method"; + public static final String NUAGE_VSP_API_RESOURCE = "resource"; + public static final String NUAGE_VSP_API_RESOURCE_ID = "resourceid"; + public static final String NUAGE_VSP_API_CHILD_RESOURCE = "childresource"; + public static final String NUAGE_VSP_API_RESOURCE_FILTER = "resourcefilter"; + public static final String NUAGE_VSP_API_RESOURCE_INFO = "resourceinfo"; +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java new file mode 100644 index 0000000000..b0bbcc8ebc --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java @@ -0,0 +1,105 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.response; + +import com.cloud.api.commands.VspConstants; +import com.cloud.network.NuageVspDeviceVO; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@EntityReference(value = NuageVspDeviceVO.class) +public class NuageVspDeviceResponse extends BaseResponse { + @SerializedName(VspConstants.NUAGE_VSP_DEVICE_ID) + @Param(description = "the device id of the Nuage VSD") + private String id; + + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) + @Param(description = "the ID of the physical network to which this Nuage VSP belongs to") + private String physicalNetworkId; + + @SerializedName(ApiConstants.PROVIDER) + @Param(description = "the service provider name corresponding to this Nuage VSP device") + private String providerName; + + @SerializedName(VspConstants.NUAGE_VSP_DEVICE_NAME) + @Param(description = "the name of the Nuage VSP device") + private String deviceName; + + @SerializedName(VspConstants.NUAGE_VSP_API_PORT) + @Param(description = "the port to communicate to Nuage VSD") + private int port; + + @SerializedName(ApiConstants.HOST_NAME) + @Param(description = "the hostname of the Nuage VSD") + private String hostName; + + @SerializedName(VspConstants.NUAGE_VSP_API_VERSION) + @Param(description = "the version of the API to use to communicate to Nuage VSD") + private String apiVersion; + + @SerializedName(VspConstants.NUAGE_VSP_API_RETRY_COUNT) + @Param(description = "the number of retries on failure to communicate to Nuage VSD") + private int apiRetryCount; + + @SerializedName(VspConstants.NUAGE_VSP_API_RETRY_INTERVAL) + @Param(description = "the time to wait after failure before retrying to communicate to Nuage VSD") + private long apiRetryInterval; + + public void setId(String vspDetailsId) { + this.id = vspDetailsId; + } + + public void setPhysicalNetworkId(String physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public void setPort(int port) { + this.port = port; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public void setApiRetryCount(int apiRetryCount) { + this.apiRetryCount = apiRetryCount; + } + + public void setApiRetryInterval(long apiRetryInterval) { + this.apiRetryInterval = apiRetryInterval; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java new file mode 100644 index 0000000000..8e620ed4c3 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java @@ -0,0 +1,41 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.response; + +import com.cloud.api.commands.VspConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class NuageVspResourceResponse extends BaseResponse { + @SerializedName(VspConstants.NUAGE_VSP_API_RESOURCE_INFO) + @Param(description = "the details of the Nuage VSP resource") + private String resourceInfo; + + public String getResourceInfo() { + return resourceInfo; + } + + public void setResourceInfo(String resourceInfo) { + this.resourceInfo = resourceInfo; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java new file mode 100644 index 0000000000..00cb1e4dc7 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java @@ -0,0 +1,98 @@ +// +// 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; + +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 org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "external_nuage_vsp_devices") +public class NuageVspDeviceVO implements InternalIdentity { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "host_id") + private long hostId; + + @Column(name = "physical_network_id") + private long physicalNetworkId; + + @Column(name = "provider_name") + private String providerName; + + @Column(name = "device_name") + private String deviceName; + + public NuageVspDeviceVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public NuageVspDeviceVO(long hostId, long physicalNetworkId, + String providerName, String deviceName){ + super(); + this.hostId = hostId; + this.physicalNetworkId = physicalNetworkId; + this.providerName = providerName; + this.deviceName = deviceName; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + public long getHostId() { + return hostId; + } + + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getProviderName() { + return providerName; + } + + public String getDeviceName() { + return deviceName; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java new file mode 100644 index 0000000000..6cf7e1a5f6 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java @@ -0,0 +1,36 @@ +// +// 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.dao; + +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.db.GenericDao; + +import java.util.List; + +public interface NuageVspDao extends GenericDao { + /** + * List all the Nuage Vsp devices added in to this physical network + * + * @param physicalNetworkId physical Network Id + * @return list of NuageVspDeviceVO for this physical network. + */ + List listByPhysicalNetwork(long physicalNetworkId); + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java new file mode 100644 index 0000000000..bc55f434c0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java @@ -0,0 +1,52 @@ +// +// 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.dao; + +import javax.ejb.Local; + +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; + +import java.util.List; + +@Component +@Local(value = NuageVspDao.class) +public class NuageVspDaoImpl extends GenericDaoBase + implements NuageVspDao { + + protected final SearchBuilder physicalNetworkIdSearch; + + public NuageVspDaoImpl() { + physicalNetworkIdSearch = createSearchBuilder(); + physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ); + physicalNetworkIdSearch.done(); + } + + @Override + public List listByPhysicalNetwork(long physicalNetworkId) { + SearchCriteria sc = physicalNetworkIdSearch.create(); + sc.setParameters("physicalNetworkId", physicalNetworkId); + return search(sc, null); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java new file mode 100644 index 0000000000..06f9733fc0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java @@ -0,0 +1,534 @@ +// +// 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 javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupVspCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.Domain; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.CloudException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.FirewallRuleType; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; +import com.cloud.utils.component.AdapterBase; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicDao; + +@Local(value = {NetworkElement.class, ConnectivityProvider.class, IpDeployer.class, SourceNatServiceProvider.class, StaticNatServiceProvider.class, FirewallServiceProvider.class, + DhcpServiceProvider.class, NetworkACLServiceProvider.class}) +public class NuageVspElement extends AdapterBase implements ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, + DhcpServiceProvider, NetworkACLServiceProvider, ResourceStateAdapter { + + private static final Logger s_logger = Logger.getLogger(NuageVspElement.class); + + private static final Map> capabilities = setCapabilities(); + + public static final ExternalNetworkDeviceManager.NetworkDevice NuageVspDevice = new ExternalNetworkDeviceManager.NetworkDevice("NuageVsp", Provider.NuageVsp.getName()); + + @Inject + ResourceManager _resourceMgr; + @Inject + HostDao _hostDao; + @Inject + NetworkModel _networkModel; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + NetworkDao _networkDao; + @Inject + protected DomainDao _domainDao; + @Inject + protected DataCenterDao _dcDao; + @Inject + IPAddressDao _ipAddressDao; + @Inject + VlanDao _vlanDao; + @Inject + NicDao _nicDao; + @Inject + VpcDao _vpcDao; + @Inject + NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; + @Inject + AgentManager _agentMgr; + @Inject + NetworkOfferingDao _ntwkOfferingDao; + + @Override + public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { + return false; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // L2 Support : SDN provisioning + capabilities.put(Service.Connectivity, null); + + // L3 Support : Generic + capabilities.put(Service.Gateway, null); + + // L3 Support : SourceNat + Map sourceNatCapabilities = new HashMap(); + sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount"); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + // L3 support : StaticNat + capabilities.put(Service.StaticNat, null); + + // Set capabilities for Firewall service + Map firewallCapabilities = new HashMap(); + firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); + firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); + firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all"); + firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress"); + firewallCapabilities.put(Capability.MultipleIps, "true"); + capabilities.put(Service.Firewall, firewallCapabilities); + + // L3 Support : DHCP + Map dhcpCapabilities = new HashMap(); + capabilities.put(Service.Dhcp, dhcpCapabilities); + + //add network ACL capability + Map networkACLCapabilities = new HashMap(); + networkACLCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp"); + capabilities.put(Network.Service.NetworkACL, networkACLCapabilities); + + return capabilities; + } + + @Override + public Provider getProvider() { + return Provider.NuageVsp; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _resourceMgr.registerResourceStateAdapter(name, this); + return true; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + s_logger.debug("Entering NuageElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")"); + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + return true; + } + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return false; + } + + @Override + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean verifyServicesCombination(Set services) { + // This element can only function in a NuageVsp based + // SDN network, so Connectivity needs to be present here + if (!services.contains(Service.Connectivity)) { + s_logger.warn("Unable to support services combination without Connectivity service provided by Nuage VSP."); + return false; + } + + if ((services.contains(Service.StaticNat)) && (!services.contains(Service.SourceNat))) { + s_logger.warn("Unable to provide StaticNat without the SourceNat service."); + return false; + } + + if (services.contains(Service.Vpn) || services.contains(Service.Dns) || services.contains(Service.Lb) || services.contains(Service.PortForwarding) + || services.contains(Service.SecurityGroup)) { + // NuageVsp doesn't implement any of these services, and we don't + // want anyone else to do it for us. So if these services + // exist, we can't handle it. + s_logger.warn("Unable to support services combination. The services list contains service(s) not supported by Nuage VSP."); + return false; + } + + return true; + } + + protected boolean canHandle(Network network, Service service) { + + if (network.getBroadcastDomainType() != Networks.BroadcastDomainType.Vsp) { + return false; + } + + if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) { + s_logger.debug("NuageElement is not a provider for network " + network.getDisplayText()); + return false; + } + + if (service != null) { + if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { + s_logger.debug("NuageElement can't provide the " + service.getName() + " service on network " + network.getDisplayText()); + return false; + } + } + + return true; + } + + @Override + public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + return true; + } + + @Override + public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + return true; + } + + @Override + public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException { + return true; + } + + @Override + public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { + //Check if the network is associated to a VPC + Long vpcId = config.getVpcId(); + String vpcOrSubnetUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcOrSubnetUuid = vpcObj.getUuid(); + } else { + vpcOrSubnetUuid = config.getUuid(); + } + Domain networkDomain = _domainDao.findById(config.getDomainId()); + + long networkOfferingId = _ntwkOfferingDao.findById(config.getNetworkOfferingId()).getId(); + boolean isL3Network = isL3Network(networkOfferingId); + + List> sourceNatDetails = new ArrayList>(); + for (StaticNat staticNat : rules) { + Map sourceNatDetail = new HashMap(); + IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId()); + VlanVO sourceNatVan = _vlanDao.findById(sourceNatIp.getVlanId()); + NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId()); + //Just get all the information about the sourceNat which will be used by NuageVsp + //client to process the request + sourceNatDetail.put("sourceNatIpUuid", sourceNatIp.getUuid()); + sourceNatDetail.put("sourceNatIpAddress", sourceNatIp.getAddress().addr()); + sourceNatDetail.put("nicMacAddress", nicVO == null ? null : nicVO.getMacAddress()); + sourceNatDetail.put("isRevoke", staticNat.isForRevoke()); + sourceNatDetail.put("sourceNatVlanUuid", sourceNatVan.getUuid()); + sourceNatDetail.put("sourceNatVlanGateway", sourceNatVan.getVlanGateway()); + sourceNatDetail.put("sourceNatVlanNetmask", sourceNatVan.getVlanNetmask()); + sourceNatDetails.add(sourceNatDetail); + } + try { + try { + HostVO nuageVspHost = getNuageVspHost(config.getPhysicalNetworkId()); + ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(networkDomain.getUuid(), vpcOrSubnetUuid, isL3Network, sourceNatDetails); + ApplyStaticNatVspAnswer answer = (ApplyStaticNatVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ApplyStaticNatNuageVspCommand for network " + config.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ResourceUnavailableException(answer.getDetails(), Network.class, config.getId()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to apply static Nat in Vsp " + e.getMessage()); + } + } catch (Exception e) { + throw new ResourceUnavailableException("Failed to apply Static NAT in VSP", Network.class, config.getId(), e); + } + + return true; + } + + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + @Override + public boolean applyFWRules(Network network, List rules) throws ResourceUnavailableException { + s_logger.debug("Handling applyFWRules for network " + network.getName() + " with " + rules.size() + " FWRules"); + if (rules != null && rules.size() == 1 && rules.iterator().next().getType().equals(FirewallRuleType.System)) { + s_logger.debug("Default ACL added by CS as system is ignored for network " + network.getName() + " with rule " + rules); + return true; + } + return applyACLRules(network, rules, false); + } + + @Override + public boolean applyNetworkACLs(Network network, List rules) throws ResourceUnavailableException { + s_logger.debug("Handling applyNetworkACLs for network " + network.getName() + " with " + rules.size() + " Network ACLs"); + if (rules == null || rules.isEmpty()) { + s_logger.debug("No rules to apply. So, delete all the existing ACL in VSP from Subnet with uuid " + network.getUuid()); + } else { + s_logger.debug("New rules has to applied. So, delete all the existing ACL in VSP from Subnet with uuid " + network.getUuid()); + } + applyACLRules(network, rules, true); + return true; + } + + protected boolean applyACLRules(Network network, List rules, boolean isVpc) throws ResourceUnavailableException { + Domain networksDomain = _domainDao.findById(network.getDomainId()); + NetworkOfferingVO networkOferringVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); + try { + Long vpcId = network.getVpcId(); + String vpcOrSubnetUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcOrSubnetUuid = vpcObj.getUuid(); + } else { + vpcOrSubnetUuid = network.getUuid(); + } + boolean egressDefaultPolicy = networkOferringVO.getEgressDefaultPolicy(); + List> aclRules = new ArrayList>(); + for (InternalIdentity acl : rules) { + aclRules.add(getACLRuleDetails(acl, egressDefaultPolicy)); + } + + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(network.getUuid(), networksDomain.getUuid(), vpcOrSubnetUuid, isL3Network(networkOferringVO.getId()), aclRules, + isVpc, network.getId()); + ApplyAclRuleVspAnswer answer = (ApplyAclRuleVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ApplyAclRuleNuageVspCommand for network " + network.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ResourceUnavailableException(answer.getDetails(), Network.class, network.getId()); + } + } + + } catch (Exception e1) { + throw new ResourceUnavailableException(e1.getMessage(), Network.class, network.getId()); + } + + return true; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { + if (!(startup[0] instanceof StartupVspCommand)) { + return null; + } + host.setType(Host.Type.L2Networking); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (!(host.getType() == Host.Type.L2Networking)) { + return null; + } + return new DeleteHostAnswer(true); + } + + protected HostVO getNuageVspHost(Long physicalNetworkId) throws CloudException { + HostVO nuageVspHost; + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + nuageVspHost = _hostDao.findById(config.getHostId()); + _hostDao.loadDetails(nuageVspHost); + } else { + throw new CloudException("Nuage VSD is not configured on physical network " + physicalNetworkId); + } + return nuageVspHost; + } + + protected boolean isL3Network(Long offeringId) { + return _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.SourceNat) + || _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.StaticNat); + } + + private Map getACLRuleDetails(Object aclRule, boolean egressDefaultPolicy) { + Map aclDetails = new HashMap(); + if (aclRule instanceof FirewallRule) { + FirewallRule firewallRule = (FirewallRule)aclRule; + aclDetails.put("sourceCidrList", firewallRule.getSourceCidrList()); + aclDetails.put("uuid", firewallRule.getUuid()); + aclDetails.put("protocol", firewallRule.getProtocol()); + aclDetails.put("startPort", firewallRule.getSourcePortStart()); + aclDetails.put("endPort", firewallRule.getSourcePortEnd()); + aclDetails.put("state", firewallRule.getState().name()); + aclDetails.put("trafficType", firewallRule.getTrafficType().name()); + if (firewallRule.getSourceIpAddressId() != null) { + //add the source IP + IPAddressVO ipaddress = _ipAddressDao.findById(((FirewallRule)aclRule).getSourceIpAddressId()); + aclDetails.put("sourceIpAddress", ipaddress != null ? ipaddress.getVmIp() + "/32" : null); + } + if (firewallRule.getTrafficType().equals(FirewallRule.TrafficType.Egress) && egressDefaultPolicy) { + aclDetails.put("action", "Deny"); + } else { + aclDetails.put("action", "Allow"); + } + aclDetails.put("priority", -1); + aclDetails.put("type", "Firewall"); + } else { + NetworkACLItem networkAcl = (NetworkACLItem)aclRule; + aclDetails.put("sourceCidrList", networkAcl.getSourceCidrList()); + aclDetails.put("uuid", networkAcl.getUuid()); + aclDetails.put("protocol", networkAcl.getProtocol()); + aclDetails.put("startPort", networkAcl.getSourcePortStart()); + aclDetails.put("endPort", networkAcl.getSourcePortEnd()); + aclDetails.put("state", networkAcl.getState().name()); + aclDetails.put("trafficType", networkAcl.getTrafficType().name()); + //Set sourceIP to null as it is not applicable + aclDetails.put("sourceIpAddress", null); + aclDetails.put("action", networkAcl.getAction().name()); + aclDetails.put("priority", networkAcl.getNumber()); + aclDetails.put("type", "NetworkACL"); + } + return aclDetails; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java new file mode 100644 index 0000000000..d9882eaa7b --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java @@ -0,0 +1,416 @@ +// +// 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.guru; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkProfile; +import com.cloud.network.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetwork.IsolationMethod; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.db.DB; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value = NetworkGuru.class) +public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { + public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class); + + @Inject + NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; + @Inject + NetworkOfferingDao _ntwkOfferingDao; + @Inject + DomainDao _domainDao; + @Inject + AccountDao _accountDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + HostDao _hostDao; + @Inject + VpcDao _vpcDao; + @Inject + AgentManager _agentMgr; + + public NuageVspGuestNetworkGuru() { + super(); + _isolationMethods = new IsolationMethod[] {IsolationMethod.VSP}; + } + + @Override + public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { + PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId()); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + if (!canHandle(offering, dc.getNetworkType(), physnet)) { + s_logger.debug("Refusing to design this network"); + return null; + } + + NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner); + if (networkObject == null) { + return null; + } + + networkObject.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); + return networkObject; + } + + @Override + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException { + + assert (network.getState() == State.Implementing) : "Why are we implementing " + network; + + long dcId = dest.getDataCenter().getId(); + //Get physical network id + Long physicalNetworkId = network.getPhysicalNetworkId(); + //Physical network id can be null in Guest Network in Basic zone, so locate the physical network + if (physicalNetworkId == null) { + physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType()); + } + NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, + network.getDataCenterId(), physicalNetworkId); + if (network.getGateway() != null) { + implemented.setGateway(network.getGateway()); + } + if (network.getCidr() != null) { + implemented.setCidr(network.getCidr()); + } + Collection ipAddressRange = new ArrayList(); + String virtualRouterIp = getVirtualRouterIP(network, ipAddressRange); + String networkUuid = implemented.getUuid(); + String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId(); + String broadcastUriStr = networkUuid + "/" + virtualRouterIp; + implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr)); + implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); + //Check if the network is associated to a VPC + Long vpcId = network.getVpcId(); + boolean isVpc = (vpcId != null); + //Check owner of the Network + Domain networksDomain = _domainDao.findById(network.getDomainId()); + //Get the Account details and find the type + AccountVO networksAccount = _accountDao.findById(network.getAccountId()); + if (networksAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { + String errorMessage = "CS project support is not yet implemented in NuageVsp"; + s_logger.debug(errorMessage); + throw new InsufficientVirtualNetworkCapacityException(errorMessage, Account.class, network.getAccountId()); + } + boolean isL3Network = isL3Network(offering.getId()); + String vpcName = null; + String vpcUuid = null; + if (isVpc) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcName = vpcObj.getName(); + vpcUuid = vpcObj.getUuid(); + } + + HostVO nuageVspHost = getNuageVspHost(physicalNetworkId); + ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(networksDomain.getName(), networksDomain.getPath(), networksDomain.getUuid(), + networksAccount.getAccountName(), networksAccount.getUuid(), network.getName(), network.getCidr(), network.getGateway(), network.getUuid(), isL3Network, vpcName, + vpcUuid, offering.getEgressDefaultPolicy(), ipAddressRange); + ImplementNetworkVspAnswer answer = (ImplementNetworkVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("ImplementNetworkNuageVspCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + return null; + } + s_logger.info("Implemented OK, network " + networkUuid + " in tenant " + tenantId + " linked to " + implemented.getBroadcastUri().toString()); + return implemented; + } + + @Override + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + + return super.allocate(network, nic, vm); + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + nic.setBroadcastUri(network.getBroadcastUri()); + nic.setIsolationUri(network.getBroadcastUri()); + + s_logger.debug("Handling reserve() call back to with Create a new VM or add an interface to existing VM in network " + network.getName()); + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + Account networksAccount = _accountDao.findById(network.getAccountId()); + DomainVO networksDomain = _domainDao.findById(network.getDomainId()); + //Get the Account details and find the type + long networkOwnedBy = network.getAccountId(); + AccountVO neworkAccountDetails = _accountDao.findById(networkOwnedBy); + if (neworkAccountDetails.getType() == Account.ACCOUNT_TYPE_PROJECT) { + throw new InsufficientVirtualNetworkCapacityException("CS project support is " + "not yet implemented in NuageVsp", DataCenter.class, dc.getId()); + } + + //NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort + //that we create in VSP + NicVO nicFrmDB = _nicDao.findById(nic.getId()); + long networkOfferingId = _ntwkOfferingDao.findById(network.getNetworkOfferingId()).getId(); + boolean isL3Network = isL3Network(networkOfferingId); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(nicFrmDB.getUuid(), nic.getMacAddress(), network.getUuid(), isL3Network, vpcUuid, + networksDomain.getUuid(), networksAccount.getUuid(), vm.getType().equals(VirtualMachine.Type.DomainRouter), network.getBroadcastUri().getPath().substring(1), + vm.getInstanceName(), vm.getUuid(), networksDomain.getUuid(), networksAccount.getUuid()); + ReserveVmInterfaceVspAnswer answer = (ReserveVmInterfaceVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("ReserveVmInterfaceNuageVspCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId()); + } + List> vmInterfacesDetails = answer.getInterfaceDetails(); + setIPGatewayMaskInfo(network, nic, vmInterfacesDetails); + } + + @Override + protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { + if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated + && isMyIsolationMethod(physicalNetwork)) { + return true; + } else { + s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); + return false; + } + } + + @Override + public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { + long networkId = nic.getNetworkId(); + Network network = _networkDao.findById(networkId); + s_logger.debug("Handling release() call back, which is called when a VM is stopped or destroyed, to delete the VM with state " + vm.getVirtualMachine().getState() + + " from netork " + network.getName()); + if (vm.getVirtualMachine().getState().equals(VirtualMachine.State.Stopping)) { + try { + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ReleaseVmVspCommand cmd = new ReleaseVmVspCommand(network.getUuid(), vm.getUuid(), vm.getInstanceName()); + ReleaseVmVspAnswer answer = (ReleaseVmVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ReleaseVmNuageVspCommand for VM " + vm.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (InsufficientVirtualNetworkCapacityException e) { + s_logger.debug("Handling release() call back. Failed to delete CS VM " + vm.getInstanceName() + " in VSP. " + e.getMessage()); + } + } else { + s_logger.debug("Handling release() call back. VM " + vm.getInstanceName() + " is in " + vm.getVirtualMachine().getState() + " state. So, the CS VM is not deleted." + + " This could be a case where VM interface is deleted. deallocate() call back should be called later"); + } + + return super.release(nic, vm, reservationId); + } + + @Override + @DB + public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + + try { + s_logger.debug("Handling deallocate() call back, which is called when a VM is destroyed or interface is removed, " + "to delete VM Interface with IP " + + nic.getIp4Address() + " from a VM " + vm.getInstanceName() + " with state " + vm.getVirtualMachine().getState()); + DomainVO networksDomain = _domainDao.findById(network.getDomainId()); + NicVO nicFrmDd = _nicDao.findById(nic.getId()); + long networkOfferingId = _ntwkOfferingDao.findById(network.getNetworkOfferingId()).getId(); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(network.getUuid(), nicFrmDd.getUuid(), nic.getMacAddress(), nic.getIp4Address(), + isL3Network(networkOfferingId), vpcUuid, networksDomain.getUuid(), vm.getInstanceName(), vm.getUuid()); + DeallocateVmVspAnswer answer = (DeallocateVmVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (InsufficientVirtualNetworkCapacityException e) { + s_logger.error("Handling deallocate(). VM " + vm.getInstanceName() + " with NIC IP " + nic.getIp4Address() + + " is getting destroyed. REST API failed to update the VM state in NuageVsp", e); + } + super.deallocate(network, nic, vm); + } + + @Override + public void shutdown(NetworkProfile profile, NetworkOffering offering) { + super.shutdown(profile, offering); + } + + @Override + public boolean trash(Network network, NetworkOffering offering) { + + s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP"); + long domainId = network.getDomainId(); + Domain domain = _domainDao.findById(domainId); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + try { + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(domain.getUuid(), network.getUuid(), isL3Network(offering.getId()), vpcUuid); + TrashNetworkVspAnswer answer = (TrashNetworkVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("TrashNetworkNuageVspCommand for network " + network.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to clean up network information in Vsp " + e.getMessage()); + } + + return super.trash(network, offering); + } + + private String getVirtualRouterIP(Network network, Collection addressRange) throws InsufficientVirtualNetworkCapacityException { + String virtualRouterIp; + String subnet = NetUtils.getCidrSubNet(network.getCidr()); + String netmask = NetUtils.getCidrNetmask(network.getCidr()); + long cidrSize = NetUtils.getCidrSize(netmask); + + Set allIPsInCidr = NetUtils.getAllIpsFromCidr(subnet, cidrSize, new HashSet()); + + if (allIPsInCidr.size() > 3) { + Iterator ipIterator = allIPsInCidr.iterator(); + long vip = ipIterator.next(); + if (NetUtils.ip2Long(network.getGateway()) == vip) { + s_logger.debug("Gateway of the Network(" + network.getUuid() + ") has the first IP " + NetUtils.long2Ip(vip)); + vip = ipIterator.next(); + virtualRouterIp = NetUtils.long2Ip(vip); + s_logger.debug("So, reserving the 2nd IP " + virtualRouterIp + " for the Virtual Router IP in Network(" + network.getUuid() + ")"); + } else { + virtualRouterIp = NetUtils.long2Ip(vip); + s_logger.debug("1nd IP is not used as the gateway IP. So, reserving" + virtualRouterIp + " for the Virtual Router IP for " + "Network(" + network.getUuid() + ")"); + } + addressRange.add(NetUtils.long2Ip(ipIterator.next())); + addressRange.add(NetUtils.long2Ip((Long)allIPsInCidr.toArray()[allIPsInCidr.size() - 1])); + return virtualRouterIp; + } + + throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " So, subnet should have atleast minimum 4 hosts ", Network.class, + network.getId()); + } + + private void setIPGatewayMaskInfo(Network network, NicProfile nic, List> vmInterfacesDetails) throws InsufficientVirtualNetworkCapacityException { + try { + for (Map interfaces : vmInterfacesDetails) { + String macFromNuage = interfaces.get("mac"); + if (StringUtils.equals(macFromNuage, nic.getMacAddress())) { + nic.setIp4Address(interfaces.get("ip4Address")); + nic.setGateway(interfaces.get("gateway")); + nic.setNetmask(interfaces.get("netmask")); + break; + } + } + } catch (Exception e) { + s_logger.error("Failed to parse the VM interface Json response from VSP REST API. VM interface json string is " + vmInterfacesDetails, e); + throw new InsufficientVirtualNetworkCapacityException("Failed to parse the VM interface Json response from VSP REST API. VM interface Json " + "string is " + + vmInterfacesDetails + ". So. failed to get IP for the VM from VSP address for network " + network, Network.class, network.getId()); + } + } + + private boolean isL3Network(Long offeringId) { + return _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.SourceNat) + || _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.StaticNat); + } + + private HostVO getNuageVspHost(long physicalNetworkId) throws InsufficientVirtualNetworkCapacityException { + HostVO nuageVspHost; + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + nuageVspHost = _hostDao.findById(config.getHostId()); + _hostDao.loadDetails(nuageVspHost); + } else { + throw new InsufficientVirtualNetworkCapacityException("Nuage VSD is not configured on physical network ", PhysicalNetwork.class, physicalNetworkId); + } + return nuageVspHost; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java new file mode 100644 index 0000000000..2b4d2b558a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java @@ -0,0 +1,55 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.network.manager; + +import java.util.List; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.ConfigKey.Scope; + +import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.component.PluggableService; + +public interface NuageVspManager extends PluggableService { + + static final String NUAGE_VPC_OFFERING_NAME = "Default VPC offering with NuageVsp"; + + static final String NUAGE_VPC_OFFERING_DISPLAY_TEXT = "Default VPC offering with NuageVsp"; + + static final ConfigKey NuageVspSyncInterval = new ConfigKey(Integer.class, "nuagevsp.sync.interval", "Advanced", "480", + "The interval (in minutes) to wait before running the next synchronization worker to synchronize the information between CloudStack and NuageVsp", false, Scope.Global, + 1); + + static final ConfigKey NuageVspSyncWorkers = new ConfigKey(Integer.class, "nuagevsp.sync.workers", "Advanced", "1", + "Number of workers to synchronize the information between CloudStack and NuageVsp", false, Scope.Global, 1); + + NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd); + + NuageVspDeviceResponse createNuageVspDeviceResponse(NuageVspDeviceVO nuageVspDeviceVO); + + boolean deleteNuageVspDevice(DeleteNuageVspDeviceCmd cmd); + + List listNuageVspDevices(ListNuageVspDevicesCmd cmd); + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java new file mode 100644 index 0000000000..fed970ede5 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java @@ -0,0 +1,353 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.network.manager; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.IssueNuageVspResourceRequestCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.exception.InvalidParameterValueException; +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.Network; +import com.cloud.network.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.network.sync.NuageVspSync; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.resource.ServerResource; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.exception.CloudRuntimeException; + +@Local(value = {NuageVspManager.class}) +public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, Configurable { + + private static final Logger s_logger = Logger.getLogger(NuageVspManagerImpl.class); + + private static final int ONE_MINUTE_MULTIPLIER = 60 * 1000; + + @Inject + ResourceManager _resourceMgr; + @Inject + HostDetailsDao _hostDetailsDao; + @Inject + HostDao _hostDao; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + ConfigurationDao _configDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + NetworkDao _networkDao; + @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcOfferingServiceMapDao _vpcOffSvcMapDao; + @Inject + VpcDao _vpcDao; + @Inject + NuageVspDao nuageVspDao; + @Inject + NuageVspSync nuageVspSync; + + private ScheduledExecutorService scheduler; + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + cmdList.add(AddNuageVspDeviceCmd.class); + cmdList.add(DeleteNuageVspDeviceCmd.class); + cmdList.add(ListNuageVspDevicesCmd.class); + cmdList.add(IssueNuageVspResourceRequestCmd.class); + + return cmdList; + } + + @Override + public NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd) { + ServerResource resource = new NuageVspResource(); + final String deviceName = Network.Provider.NuageVsp.getName(); + ExternalNetworkDeviceManager.NetworkDevice networkDevice = ExternalNetworkDeviceManager.NetworkDevice.getNetworkDevice(deviceName); + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); + } + long zoneId = physicalNetwork.getDataCenterId(); + + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), + networkDevice.getNetworkServiceProvder()); + if (ntwkSvcProvider == null) { + throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + " is not added 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 (_nuageVspDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { + throw new CloudRuntimeException("A NuageVsp device is already configured on this physical network"); + } + + Map params = new HashMap(); + params.put("guid", UUID.randomUUID().toString()); + params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); + params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); + params.put("name", "Nuage VSD - " + cmd.getHostName()); + params.put("hostname", cmd.getHostName()); + params.put("cmsuser", cmd.getUserName()); + String cmsUserPasswordBase64 = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.encodeBase64(cmd.getPassword().getBytes(Charset.forName("UTF-8")))); + params.put("cmsuserpass", cmsUserPasswordBase64); + int port = cmd.getPort(); + if (0 == port) { + port = 443; + } + params.put("port", String.valueOf(port)); + params.put("apirelativepath", "/nuage/api/" + cmd.getApiVersion()); + params.put("retrycount", String.valueOf(cmd.getApiRetryCount())); + params.put("retryinterval", String.valueOf(cmd.getApiRetryInterval())); + + Map hostdetails = new HashMap(); + hostdetails.putAll(params); + + try { + resource.configure(cmd.getHostName(), hostdetails); + + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); + if (host != null) { + return Transaction.execute(new TransactionCallback() { + @Override + public NuageVspDeviceVO doInTransaction(TransactionStatus status) { + NuageVspDeviceVO nuageVspDevice = new NuageVspDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); + _nuageVspDao.persist(nuageVspDevice); + + DetailVO detail = new DetailVO(host.getId(), "nuagevspdeviceid", String.valueOf(nuageVspDevice.getId())); + _hostDetailsDao.persist(detail); + + return nuageVspDevice; + } + }); + } else { + throw new CloudRuntimeException("Failed to add Nuage Vsp Device due to internal error."); + } + } catch (ConfigurationException e) { + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public NuageVspDeviceResponse createNuageVspDeviceResponse(NuageVspDeviceVO nuageVspDeviceVO) { + HostVO nuageVspHost = _hostDao.findById(nuageVspDeviceVO.getHostId()); + _hostDao.loadDetails(nuageVspHost); + + NuageVspDeviceResponse response = new NuageVspDeviceResponse(); + response.setDeviceName(nuageVspDeviceVO.getDeviceName()); + PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(nuageVspDeviceVO.getPhysicalNetworkId()); + if (pnw != null) { + response.setPhysicalNetworkId(pnw.getUuid()); + } + response.setId(nuageVspDeviceVO.getUuid()); + response.setProviderName(nuageVspDeviceVO.getProviderName()); + response.setHostName(nuageVspHost.getDetail("hostname")); + response.setPort(Integer.parseInt(nuageVspHost.getDetail("port"))); + String apiRelativePath = nuageVspHost.getDetail("apirelativepath"); + response.setApiVersion(apiRelativePath.substring(apiRelativePath.lastIndexOf('/') + 1)); + response.setApiRetryCount(Integer.parseInt(nuageVspHost.getDetail("retrycount"))); + response.setApiRetryInterval(Long.parseLong(nuageVspHost.getDetail("retryinterval"))); + response.setObjectName("nuagevspdevice"); + return response; + } + + @Override + public boolean deleteNuageVspDevice(DeleteNuageVspDeviceCmd cmd) { + Long nuageDeviceId = cmd.getNuageVspDeviceId(); + NuageVspDeviceVO nuageVspDevice = _nuageVspDao.findById(nuageDeviceId); + if (nuageVspDevice == null) { + throw new InvalidParameterValueException("Could not find a Nuage Vsp device with id " + nuageDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = nuageVspDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork != null) { + // Lets see if there are networks that use us + // Find the NuageVsp on this physical network + List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Vsp) { + if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) { + throw new CloudRuntimeException("This Nuage Vsp device can not be deleted as there are one or more logical networks provisioned by Cloudstack."); + } + } + } + } + + HostVO nuageHost = _hostDao.findById(nuageVspDevice.getHostId()); + Long hostId = nuageHost.getId(); + + nuageHost.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, nuageHost); + _resourceMgr.deleteHost(hostId, false, false); + + _nuageVspDao.remove(nuageDeviceId); + return true; + } + + @Override + public List listNuageVspDevices(ListNuageVspDevicesCmd cmd) { + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + Long nuageVspDeviceId = cmd.getNuageVspDeviceId(); + List responseList = new ArrayList(); + + if (physicalNetworkId == null && nuageVspDeviceId == null) { + throw new InvalidParameterValueException("Either physical network Id or Nuage device Id must be specified"); + } + + if (nuageVspDeviceId != null) { + NuageVspDeviceVO nuageVspDevice = _nuageVspDao.findById(nuageVspDeviceId); + if (nuageVspDevice == null) { + throw new InvalidParameterValueException("Could not find Nuage Vsp device with id: " + nuageVspDeviceId); + } + responseList.add(nuageVspDevice); + } else { + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId); + } + responseList = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + } + + return responseList; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + try { + initNuageScheduledTasks(); + } catch (Exception ce) { + s_logger.warn("Failed to load NuageVsp configuration properties. Check if the NuageVsp properties are configured correctly"); + } + return true; + } + + private void initNuageScheduledTasks() { + Integer numOfSyncThreads = Integer.valueOf(_configDao.getValue(NuageVspManager.NuageVspSyncWorkers.key())); + Integer syncUpIntervalInMinutes = Integer.valueOf(_configDao.getValue(NuageVspManager.NuageVspSyncInterval.key())); + + if (numOfSyncThreads != null && syncUpIntervalInMinutes != null) { + ThreadFactory threadFactory = new ThreadFactory() { + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "Nuage Vsp sync task"); + if (thread.isDaemon()) + thread.setDaemon(false); + if (thread.getPriority() != Thread.NORM_PRIORITY) + thread.setPriority(Thread.NORM_PRIORITY); + return thread; + } + }; + scheduler = Executors.newScheduledThreadPool(numOfSyncThreads, threadFactory); + scheduler.scheduleWithFixedDelay(new NuageVspSyncTask("FLOATING_IP"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, + TimeUnit.MILLISECONDS); + scheduler.scheduleWithFixedDelay(new NuageVspSyncTask("ENTERPRISE_NTWK_MACRO"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, + TimeUnit.MILLISECONDS); + scheduler + .scheduleWithFixedDelay(new NuageVspSyncTask("ENTERPRISE"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, TimeUnit.MILLISECONDS); + } else { + s_logger.warn("NuageVsp configuration for syncWorkers=" + numOfSyncThreads + " syncInterval=" + syncUpIntervalInMinutes + + " could not be read properly. So, check if the properties are configured properly in global properties"); + } + } + + public class NuageVspSyncTask implements Runnable { + + private String nuageVspEntity; + + public NuageVspSyncTask(String nuageVspEntity) { + this.nuageVspEntity = nuageVspEntity; + } + + public String getNuageVspEntity() { + return nuageVspEntity; + } + + @Override + public void run() { + nuageVspSync.syncWithNuageVsp(nuageVspEntity); + } + } + + @Override + public String getConfigComponentName() { + return NuageVspManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {NuageVspSyncWorkers, NuageVspSyncInterval}; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java new file mode 100644 index 0000000000..65c8ae96fa --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java @@ -0,0 +1,467 @@ +// +// 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.List; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.naming.ConfigurationException; + +import net.nuage.vsp.acs.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.NuageVspApiClient; +import net.nuage.vsp.acs.client.NuageVspElementClient; +import net.nuage.vsp.acs.client.NuageVspGuruClient; +import net.nuage.vsp.acs.client.NuageVspSyncClient; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import com.cloud.agent.IAgentControl; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +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.StartupVspCommand; +import com.cloud.agent.api.VspResourceAnswer; +import com.cloud.agent.api.VspResourceCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.agent.api.element.ShutDownVpcVspAnswer; +import com.cloud.agent.api.element.ShutDownVpcVspCommand; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.Host; +import com.cloud.resource.ServerResource; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; + +public class NuageVspResource extends ManagerBase implements ServerResource { + private static final Logger s_logger = Logger.getLogger(NuageVspResource.class); + + private String _name; + private String _guid; + private String _zoneId; + private String[] _cmsUserInfo; + private String _relativePath; + private int _numRetries; + private int _retryInterval; + + protected NuageVspApiClient _nuageVspApiClient; + protected NuageVspGuruClient _nuageVspGuruClient; + protected NuageVspElementClient _nuageVspElementClient; + protected NuageVspSyncClient _nuageVspSyncClient; + protected boolean _isNuageVspClientLoaded; + + private static final String CMS_USER_ENTEPRISE_NAME = "CSP"; + private static final String NUAGE_VSP_PLUGIN_ERROR_MESSAGE = "Nuage Vsp plugin client is not installed"; + private static final String NUAGE_PLUGIN_CLIENT_JAR_FILE = "/usr/share/nuagevsp/lib/nuage-vsp-acs-client.jar"; + private static final String NUAGE_VSP_API_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspApiClientImpl"; + private static final String NUAGE_VSP_SYNC_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspSyncClientImpl"; + private static final String NUAGE_VSP_ELEMENT_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspElementClientImpl"; + private static final String NUAGE_VSP_GURU_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspGuruClientImpl"; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + + _name = (String)params.get("name"); + if (_name == null) { + throw new ConfigurationException("Unable to find name"); + } + + _guid = (String)params.get("guid"); + if (_guid == null) { + throw new ConfigurationException("Unable to find the guid"); + } + + _zoneId = (String)params.get("zoneId"); + if (_zoneId == null) { + throw new ConfigurationException("Unable to find zone"); + } + + String hostname = (String)params.get("hostname"); + if (hostname == null) { + throw new ConfigurationException("Unable to find hostname"); + } + + String cmsUser = (String)params.get("cmsuser"); + if (cmsUser == null) { + throw new ConfigurationException("Unable to find CMS username"); + } + + String cmsUserPassBase64 = (String)params.get("cmsuserpass"); + if (cmsUserPassBase64 == null) { + throw new ConfigurationException("Unable to find CMS password"); + } + + String port = (String)params.get("port"); + if (port == null) { + throw new ConfigurationException("Unable to find port"); + } + + String apiRelativePath = (String)params.get("apirelativepath"); + if ((apiRelativePath != null) && (!apiRelativePath.isEmpty())) { + String apiVersion = apiRelativePath.substring(apiRelativePath.lastIndexOf('/') + 1); + if (!Pattern.matches("v\\d+_\\d+", apiVersion)) { + throw new ConfigurationException("Incorrect API version"); + } + } else { + throw new ConfigurationException("Unable to find API version"); + } + + String retryCount = (String)params.get("retrycount"); + if ((retryCount != null) && (!retryCount.isEmpty())) { + try { + _numRetries = Integer.parseInt(retryCount); + } catch (NumberFormatException ex) { + throw new ConfigurationException("Number of retries has to be between 1 and 10"); + } + if ((_numRetries < 1) || (_numRetries > 10)) { + throw new ConfigurationException("Number of retries has to be between 1 and 10"); + } + } else { + throw new ConfigurationException("Unable to find number of retries"); + } + + String retryInterval = (String)params.get("retryinterval"); + if ((retryInterval != null) && (!retryInterval.isEmpty())) { + try { + _retryInterval = Integer.parseInt(retryInterval); + } catch (NumberFormatException ex) { + throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); + } + if ((_retryInterval < 0) || (_retryInterval > 10000)) { + throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); + } + } else { + throw new ConfigurationException("Unable to find retry interval"); + } + + _relativePath = new StringBuffer().append("https://").append(hostname).append(":").append(port).append(apiRelativePath).toString(); + + String cmsUserPass = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.decodeBase64(cmsUserPassBase64)); + _cmsUserInfo = new String[] {CMS_USER_ENTEPRISE_NAME, cmsUser, cmsUserPass}; + + try { + loadNuageClient(); + } catch (Exception e) { + throw new CloudRuntimeException("Failed to login to Nuage VSD on " + name + " as user " + cmsUser, e); + } + + try { + login(); + } catch (Exception e) { + s_logger.error("Failed to login to Nuage VSD on " + name + " as user " + cmsUser + " Exception " + e.getMessage()); + throw new CloudRuntimeException("Failed to login to Nuage VSD on " + name + " as user " + cmsUser, e); + } + + return true; + } + + protected void login() throws Exception { + isNuageVspApiLoaded(); + _nuageVspApiClient.login(); + } + + protected void loadNuageClient() throws Exception { + + try { + ClassLoader loader = NuageVspPluginClientLoader.getClassLoader(NUAGE_PLUGIN_CLIENT_JAR_FILE); + + Class nuageVspApiClientClass = Class.forName(NUAGE_VSP_API_CLIENT_IMPL, true, loader); + Class nuageVspSyncClientClass = Class.forName(NUAGE_VSP_SYNC_CLIENT_IMPL, true, loader); + Class nuageVspGuruClientClass = Class.forName(NUAGE_VSP_GURU_CLIENT_IMPL, true, loader); + Class nuageVspElementClientClass = Class.forName(NUAGE_VSP_ELEMENT_CLIENT_IMPL, true, loader); + + //Instantiate the instances + _nuageVspApiClient = (NuageVspApiClient)nuageVspApiClientClass.newInstance(); + _nuageVspApiClient.setNuageVspHost(_relativePath, _cmsUserInfo, _numRetries, _retryInterval); + _nuageVspSyncClient = (NuageVspSyncClient)nuageVspSyncClientClass.newInstance(); + _nuageVspSyncClient.setNuageVspApiClient(_nuageVspApiClient); + _nuageVspGuruClient = (NuageVspGuruClient)nuageVspGuruClientClass.newInstance(); + _nuageVspGuruClient.setNuageVspApiClient(_nuageVspApiClient); + _nuageVspElementClient = (NuageVspElementClient)nuageVspElementClientClass.newInstance(); + _nuageVspElementClient.setNuageVspApiClient(_nuageVspApiClient); + _isNuageVspClientLoaded = true; + } catch (Exception e) { + _isNuageVspClientLoaded = false; + String errorMessage = "Nuage Vsp Plugin client is not yet installed. Please install NuageVsp plugin client to use NuageVsp plugin in Cloudstack. "; + s_logger.warn(errorMessage + e.getMessage()); + throw new Exception(errorMessage); + } + + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public Host.Type getType() { + return Host.Type.L2Networking; + } + + @Override + public StartupCommand[] initialize() { + StartupVspCommand sc = new StartupVspCommand(); + sc.setGuid(_guid); + sc.setName(_name); + sc.setDataCenter(_zoneId); + sc.setPod(""); + sc.setPrivateIpAddress(""); + sc.setStorageIpAddress(""); + sc.setVersion(NuageVspResource.class.getPackage().getImplementationVersion()); + return new StartupCommand[] {sc}; + } + + @Override + public PingCommand getCurrentStatus(long id) { + if ((_relativePath == null) || (_relativePath.isEmpty()) || (_cmsUserInfo == null) || (_cmsUserInfo.length == 0)) { + s_logger.error("Failed to ping to Nuage VSD"); + return null; + } + try { + login(); + } catch (Exception e) { + s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " + _cmsUserInfo[1] + " Exception " + e.getMessage()); + return null; + } + return new PingCommand(Host.Type.L2Networking, id); + } + + @Override + public Answer executeRequest(Command cmd) { + if (cmd instanceof ReadyCommand) { + return executeRequest((ReadyCommand)cmd); + } else if (cmd instanceof MaintainCommand) { + return executeRequest((MaintainCommand)cmd); + } else if (cmd instanceof VspResourceCommand) { + return executeRequest((VspResourceCommand)cmd); + } + //Guru commands + else if (cmd instanceof ImplementNetworkVspCommand) { + return executeRequest((ImplementNetworkVspCommand)cmd); + } else if (cmd instanceof ReserveVmInterfaceVspCommand) { + return executeRequest((ReserveVmInterfaceVspCommand)cmd); + } else if (cmd instanceof ReleaseVmVspCommand) { + return executeRequest((ReleaseVmVspCommand)cmd); + } else if (cmd instanceof DeallocateVmVspCommand) { + return executeRequest((DeallocateVmVspCommand)cmd); + } else if (cmd instanceof TrashNetworkVspCommand) { + return executeRequest((TrashNetworkVspCommand)cmd); + } + //Element commands + else if (cmd instanceof ApplyAclRuleVspCommand) { + return executeRequest((ApplyAclRuleVspCommand)cmd); + } else if (cmd instanceof ApplyStaticNatVspCommand) { + return executeRequest((ApplyStaticNatVspCommand)cmd); + } else if (cmd instanceof ShutDownVpcVspCommand) { + return executeRequest((ShutDownVpcVspCommand)cmd); + } + //Sync Commands + else if (cmd instanceof SyncVspCommand) { + return executeRequest((SyncVspCommand)cmd); + } + s_logger.debug("Received unsupported command " + cmd.toString()); + return Answer.createUnsupportedCommandAnswer(cmd); + } + + @Override + public void disconnected() { + } + + @Override + public IAgentControl getAgentControl() { + return null; + } + + @Override + public void setAgentControl(IAgentControl agentControl) { + } + + private Answer executeRequest(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + private Answer executeRequest(MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } + + private Answer executeRequest(VspResourceCommand cmd) { + try { + isNuageVspApiLoaded(); + if (cmd.getRequestType().equalsIgnoreCase("GETALL") || cmd.getRequestType().equalsIgnoreCase("GET") || cmd.getRequestType().equalsIgnoreCase("GETRELATED")) { + String resourceInfo = _nuageVspApiClient.executeRestApi(cmd.getRequestType(), cmd.getResource(), cmd.getResourceId(), cmd.getChildResource(), + cmd.getEntityDetails(), cmd.getResourceFilter(), cmd.getProxyUserUuid(), cmd.getProxyUserDomainuuid()); + return new VspResourceAnswer(cmd, resourceInfo, "Executed Issue Resource command"); + } + return new VspResourceAnswer(cmd, false, cmd.getRequestType() + " is not yet supported"); + } catch (Exception e) { + return new VspResourceAnswer(cmd, e); + } + } + + private Answer executeRequest(ImplementNetworkVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.implement(cmd.getNetworkDomainName(), cmd.getNetworkDomainPath(), cmd.getNetworkDomainUuid(), cmd.getNetworkAccountName(), + cmd.getNetworkAccountUuid(), cmd.getNetworkName(), cmd.getNetworkCidr(), cmd.getNetworkGateway(), cmd.getNetworkUuid(), cmd.isL3Network(), cmd.getVpcName(), + cmd.getVpcUuid(), cmd.isDefaultEgressPolicy(), cmd.getIpAddressRange()); + return new ImplementNetworkVspAnswer(cmd, true, "Created Nuage VSP network mapping to " + cmd.getNetworkName()); + } catch (Exception e) { + return new ImplementNetworkVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ReserveVmInterfaceVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + List> vmInterfaceInfo = _nuageVspGuruClient.reserve(cmd.getNicUuid(), cmd.getNicMacAddress(), cmd.getNetworkUuid(), cmd.isL3Network(), + cmd.getVpcUuid(), cmd.getNetworkDomainUuid(), cmd.getNetworksAccountUuid(), cmd.isDomainRouter(), cmd._getDomainRouterIp(), cmd._getVmInstanceName(), + cmd._getVmUuid()); + return new ReserveVmInterfaceVspAnswer(cmd, vmInterfaceInfo, "Created NIC in VSP that maps to nicUuid" + cmd.getNicUuid()); + } catch (Exception e) { + return new ReserveVmInterfaceVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ReleaseVmVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.release(cmd.getNetworkUuid(), cmd.getVmUuid(), cmd.getVmInstanceName()); + return new ReleaseVmVspAnswer(cmd, true, "VM has been deleted from VSP."); + } catch (Exception e) { + return new ReleaseVmVspAnswer(cmd, e); + } + } + + private Answer executeRequest(DeallocateVmVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.deallocate(cmd.getNetworkUuid(), cmd.getNicFrmDdUuid(), cmd.getNicMacAddress(), cmd.getNicIp4Address(), cmd.isL3Network(), cmd.getVpcUuid(), + cmd.getNetworksDomainUuid(), cmd.getVmInstanceName(), cmd.getVmUuid()); + return new DeallocateVmVspAnswer(cmd, true, "Deallocated VM from Nuage VSP."); + } catch (Exception e) { + return new DeallocateVmVspAnswer(cmd, e); + } + } + + private Answer executeRequest(TrashNetworkVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.trash(cmd.getDomainUuid(), cmd.getNetworkUuid(), cmd.isL3Network(), cmd.getVpcUuid()); + return new TrashNetworkVspAnswer(cmd, true, "Deleted Nuage VSP network mapping to " + cmd.getNetworkUuid()); + } catch (Exception e) { + return new TrashNetworkVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ApplyStaticNatVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.applyStaticNats(cmd.getNetworkDomainUuid(), cmd.getVpcOrSubnetUuid(), cmd.isL3Network(), cmd.getStaticNatDetails()); + return new ApplyStaticNatVspAnswer(cmd, true, "Applied Static NAT to VSP network mapping to " + cmd.getVpcOrSubnetUuid()); + } catch (Exception e) { + return new ApplyStaticNatVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ApplyAclRuleVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.applyAclRules(cmd.getNetworkUuid(), cmd.getNetworkDomainUuid(), cmd.getVpcOrSubnetUuid(), cmd.isL3Network(), cmd.getAclRules(), cmd.isVpc(), + cmd.getNetworkId()); + return new ApplyAclRuleVspAnswer(cmd, true, "Applied ACL Rule to VSP network mapping to " + cmd.getVpcOrSubnetUuid()); + } catch (Exception e) { + return new ApplyAclRuleVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ShutDownVpcVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.shutDownVpc(cmd.getDomainUuid(), cmd.getVpcUuid()); + return new ShutDownVpcVspAnswer(cmd, true, "Shutdown VPC " + cmd.getVpcUuid()); + } catch (Exception e) { + return new ShutDownVpcVspAnswer(cmd, e); + } + } + + private Answer executeRequest(SyncVspCommand cmd) { + try { + isNuageVspSyncLoaded(); + _nuageVspSyncClient.syncWithNuageVsp(cmd.getNuageVspEntity()); + return new SyncVspAnswer(cmd, true, "Synced " + cmd.getNuageVspEntity() + " in VSP"); + } catch (Exception e) { + return new SyncVspAnswer(cmd, e); + } + } + + protected void isNuageVspApiLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspApiClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspGuruLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspGuruClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspElementLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspElementClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspSyncLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspSyncClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java new file mode 100644 index 0000000000..4e1cc431e7 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java @@ -0,0 +1,26 @@ +// +// 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.sync; + + +public interface NuageVspSync { + + public void syncWithNuageVsp(String nuageVspEntity); +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java new file mode 100644 index 0000000000..f3d19c1635 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java @@ -0,0 +1,72 @@ +// +// 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.sync; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; + +@Component +public class NuageVspSyncImpl implements NuageVspSync { + + private static final Logger s_logger = Logger.getLogger(NuageVspSyncImpl.class); + + @Inject + NuageVspDao _nuageVspDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + + public void syncWithNuageVsp(String nuageVspEntity) { + //Get the NuageVspDevice and get the host information. + //This information is used to query VSP and synch the corresponding + //entities + List nuageVspDevices = _nuageVspDao.listAll(); + for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) { + + try { + HostVO nuageVspHost = _hostDao.findById(nuageVspDevice.getHostId()); + _hostDao.loadDetails(nuageVspHost); + SyncVspCommand cmd = new SyncVspCommand(nuageVspEntity); + SyncVspAnswer answer = (SyncVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("SyncNuageVspCommand for Nuage VSP Host " + nuageVspHost.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to clean up " + nuageVspEntity + " in Vsp " + e.getMessage()); + } + } + } +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java new file mode 100644 index 0000000000..76b98234a0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java @@ -0,0 +1,46 @@ +// +// 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 net.nuage.vsp.acs; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public class NuageVspPluginClientLoader { + + private static NuageVspPluginClientLoader nuageVspPluginClientClassloader; + private ClassLoader loader = null; + + private NuageVspPluginClientLoader(String nuagePluginClientJarLocation) { + try { + loader = URLClassLoader.newInstance(new URL[] {new URL("jar:file:" + nuagePluginClientJarLocation + "!/")}, + getClass().getClassLoader()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + public static ClassLoader getClassLoader(String nuagePluginClientJarLocation) { + if (nuageVspPluginClientClassloader == null) { + nuageVspPluginClientClassloader = new NuageVspPluginClientLoader(nuagePluginClientJarLocation); + } + return nuageVspPluginClientClassloader.loader; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java new file mode 100644 index 0000000000..d584c6f536 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java @@ -0,0 +1,30 @@ +// +// 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 net.nuage.vsp.acs.client; + +public interface NuageVspApiClient { + + public void login() throws Exception; + + public void setNuageVspHost(String restRelativePath, String[] cmsUserInfo, int noofRetry, int retryInterval); + + public String executeRestApi(String method, String resource, String resourceId, String childResource, Object entityDetails, String resourceFilter, String proxyUserUuid, + String proxyUserDomainuuid) throws Exception; +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java new file mode 100644 index 0000000000..27c613b3c1 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java @@ -0,0 +1,36 @@ +// +// 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 net.nuage.vsp.acs.client; + +import java.util.List; +import java.util.Map; + +public interface NuageVspElementClient { + + public void applyStaticNats(String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> staticNatDetails) throws Exception; + + public void applyAclRules(String networkUuid, String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> aclRules, boolean isVpc, long networkId) + throws Exception; + + public void shutDownVpc(String domainUuid, String vpcUuid) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); + +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java new file mode 100644 index 0000000000..3c7f33d878 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java @@ -0,0 +1,44 @@ +// +// 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 net.nuage.vsp.acs.client; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface NuageVspGuruClient { + + public void implement(String networkDomainName, String networkDomainPath, String networkDomainUuid, String networkAccountName, String networkAccountUuid, String networkName, + String networkCidr, String networkGateway, String networkUuid, boolean isL3Network, String vpcName, String vpcUuid, boolean defaultEgressPolicy, + Collection ipAddressRange) throws Exception; + + public List> reserve(String nicUuid, String nicMacAddress, String networkUuid, boolean isL3Network, String vpcUuid, String networkDomainUuid, + String networksAccountUuid, boolean isDomainRouter, String domainRouterIp, String vmInstanceName, String vmUuid) throws Exception; + + public void release(String networkUuid, String vmUuid, String vmInstanceName) throws Exception; + + public void deallocate(String networkUuid, String nicFrmDdUuid, String nicMacAddress, String nicIp4Address, boolean isL3Network, String vpcUuid, String networksDomainUuid, + String vmInstanceName, String vmUuid) throws Exception; + + public void trash(String domainUuid, String networkUuid, boolean isL3Network, String vpcUuid) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); + +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java new file mode 100644 index 0000000000..b9400f1515 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java @@ -0,0 +1,27 @@ +// +// 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 net.nuage.vsp.acs.client; + +public interface NuageVspSyncClient { + + public void syncWithNuageVsp(String nuageVspEntity) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java new file mode 100644 index 0000000000..08d685f459 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java @@ -0,0 +1,280 @@ +// +// 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.CloudException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.user.Account; +import com.cloud.vm.ReservationContext; + +public class NuageVspElementTest { + + private static final long NETWORK_ID = 42L; + NuageVspElement element = new NuageVspElement(); + NetworkOrchestrationService networkManager = mock(NetworkOrchestrationService.class); + NetworkModel networkModel = mock(NetworkModel.class); + NetworkServiceMapDao ntwkSrvcDao = mock(NetworkServiceMapDao.class); + AgentManager agentManager = mock(AgentManager.class); + HostDao hostDao = mock(HostDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + DomainDao domainDao = mock(DomainDao.class); + NetworkOfferingDao ntwkOfferingDao = mock(NetworkOfferingDao.class); + NetworkOfferingServiceMapDao ntwkOfferingSrvcDao = mock(NetworkOfferingServiceMapDao.class); + + Answer genericAnswer = new Answer() { + public Object answer(InvocationOnMock invocation) { + return null; + } + }; + + @Before + public void setUp() throws ConfigurationException { + element._resourceMgr = mock(ResourceManager.class); + element._ntwkSrvcDao = ntwkSrvcDao; + element._networkModel = networkModel; + element._agentMgr = agentManager; + element._hostDao = hostDao; + element._nuageVspDao = nuageVspDao; + element._ntwkOfferingSrvcDao = ntwkOfferingSrvcDao; + element._domainDao = domainDao; + element._ntwkOfferingDao = ntwkOfferingDao; + + // Standard responses + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + + element.configure("NuageVspTestElement", Collections. emptyMap()); + } + + @Test + public void testCcanHandle() { + final Network net = mock(Network.class); + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(net.getId()).thenReturn(NETWORK_ID); + + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + // Golden path + assertTrue(element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan); + // Only broadcastdomaintype Vsp is supported + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(false); + // No NuageVsp provider in the network + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(false); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + // NusageVsp provider does not provide Connectivity for this network + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + // Only service Connectivity is supported + assertFalse(element.canHandle(net, Service.Dhcp)); + + } + + @Test + public void testImplement() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException { + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("")); + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + DeployDestination deployDest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + assertTrue(element.implement(network, offering, deployDest, context)); + } + + @Test + public void testVerifyServiceCombination() { + Set services = new HashSet(); + services.add(Service.Dhcp); + services.add(Service.StaticNat); + services.add(Service.SourceNat); + services.add(Service.Connectivity); + services.add(Service.Firewall); + assertTrue(element.verifyServicesCombination(services)); + + services = new HashSet(); + services.add(Service.Dhcp); + services.add(Service.StaticNat); + services.add(Service.Connectivity); + services.add(Service.Firewall); + assertFalse(element.verifyServicesCombination(services)); + } + + @Test + public void testApplyStaticNats() throws CloudException { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final DomainVO domVo = mock(DomainVO.class); + when(domainDao.findById(41l)).thenReturn(domVo); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + when(element.isL3Network(NETWORK_ID)).thenReturn(true); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ApplyStaticNatVspAnswer answer = mock(ApplyStaticNatVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyStaticNats(network, new ArrayList())); + } + + @Test + public void testApplyFWRules() throws Exception { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + + final ApplyAclRuleVspAnswer answer = mock(ApplyAclRuleVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyFWRules(network, new ArrayList())); + } + + @Test + public void testApplyNetworkACL() throws Exception { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ApplyAclRuleVspAnswer answer = mock(ApplyAclRuleVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyNetworkACLs(network, new ArrayList())); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java new file mode 100644 index 0000000000..f879f09b14 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java @@ -0,0 +1,386 @@ +// +// 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.guru; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.junit.Before; +import org.junit.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.Mode; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicDao; + +public class NuageVspGuestNetworkGuruTest { + private static final long NETWORK_ID = 42L; + PhysicalNetworkDao physnetdao = mock(PhysicalNetworkDao.class); + DataCenterDao dcdao = mock(DataCenterDao.class); + NetworkOfferingServiceMapDao nosd = mock(NetworkOfferingServiceMapDao.class); + AgentManager agentManager = mock(AgentManager.class); + NetworkOrchestrationService netmgr = mock(NetworkOrchestrationService.class); + NetworkModel networkModel = mock(NetworkModel.class); + AccountDao accountDao = mock(AccountDao.class); + DomainDao domainDao = mock(DomainDao.class); + NicDao nicDao = mock(NicDao.class); + NetworkOfferingDao ntwkOfferDao = mock(NetworkOfferingDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + HostDao hostDao = mock(HostDao.class); + NetworkDao networkDao = mock(NetworkDao.class); + + NetworkDao netdao = mock(NetworkDao.class); + NuageVspGuestNetworkGuru guru; + + @Before + public void setUp() { + guru = new NuageVspGuestNetworkGuru(); + ((GuestNetworkGuru)guru)._physicalNetworkDao = physnetdao; + guru._physicalNetworkDao = physnetdao; + guru._nuageVspDao = nuageVspDao; + guru._dcDao = dcdao; + guru._ntwkOfferingSrvcDao = nosd; + guru._networkModel = networkModel; + guru._hostDao = hostDao; + guru._agentMgr = agentManager; + guru._networkDao = netdao; + guru._networkDao = networkDao; + guru._accountDao = accountDao; + guru._domainDao = domainDao; + guru._nicDao = nicDao; + guru._ntwkOfferingDao = ntwkOfferDao; + + final DataCenterVO dc = mock(DataCenterVO.class); + when(dc.getNetworkType()).thenReturn(NetworkType.Advanced); + when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24"); + + when(dcdao.findById((Long)any())).thenReturn(dc); + } + + @Test + public void testCanHandle() { + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VSP"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported TrafficType != Guest + when(offering.getTrafficType()).thenReturn(TrafficType.Management); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: GuestType Shared + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: Basic networking + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true); + + // Not supported: IsolationMethod != STT + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + } + + @Test + public void testDesign() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VSP"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork != null); + assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vsp); + } + + @Test + public void testDesignNoElementOnPhysicalNetwork() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"STT"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections. emptyList()); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testDesignNoIsolationMethodVSP() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections. emptyList()); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testReserve() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + when(network.getAccountId()).thenReturn(NETWORK_ID); + when(network.getVpcId()).thenReturn(null); + when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1")); + + final DataCenterVO dataCenter = mock(DataCenterVO.class); + when(dcdao.findById(NETWORK_ID)).thenReturn(dataCenter); + final AccountVO networksAccount = mock(AccountVO.class); + when(networksAccount.getUuid()).thenReturn("aaaa-abbbb"); + when(networksAccount.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL); + when(accountDao.findById(NETWORK_ID)).thenReturn(networksAccount); + final DomainVO networksDomain = mock(DomainVO.class); + when(networksDomain.getUuid()).thenReturn("aaaaa-bbbbb"); + when(domainDao.findById(NETWORK_ID)).thenReturn(networksDomain); + + final NicVO nicvo = mock(NicVO.class); + when(nicvo.getId()).thenReturn(NETWORK_ID); + when(nicvo.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa"); + when(nicvo.getUuid()).thenReturn("aaaa-fffff"); + when(nicDao.findById(NETWORK_ID)).thenReturn(nicvo); + + final VirtualMachineProfile vm = mock(VirtualMachineProfile.class); + when(vm.getType()).thenReturn(VirtualMachine.Type.User); + when(vm.getInstanceName()).thenReturn(""); + when(vm.getUuid()).thenReturn("aaaa-bbbbb"); + + NicProfile nicProfile = mock(NicProfile.class); + when(nicProfile.getUuid()).thenReturn("aaa-bbbb"); + when(nicProfile.getId()).thenReturn(NETWORK_ID); + when(nicProfile.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa"); + + final NetworkOfferingVO ntwkoffering = mock(NetworkOfferingVO.class); + when(ntwkoffering.getId()).thenReturn(NETWORK_ID); + when(ntwkOfferDao.findById(NETWORK_ID)).thenReturn(ntwkoffering); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ReserveVmInterfaceVspAnswer answer = mock(ReserveVmInterfaceVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(answer.getInterfaceDetails()).thenReturn(new ArrayList>()); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.reserve(nicProfile, network, vm, mock(DeployDestination.class), mock(ReservationContext.class)); + } + + @Test + public void testRelease() { + final NicProfile nicProfile = mock(NicProfile.class); + when(nicProfile.getNetworkId()).thenReturn(NETWORK_ID); + final NetworkVO network = mock(NetworkVO.class); + when(network.getUuid()).thenReturn("aaaaaa-ffffff"); + when(network.getName()).thenReturn("aaaaaa"); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(networkDao.findById(NETWORK_ID)).thenReturn(network); + + final VirtualMachineProfile vm = mock(VirtualMachineProfile.class); + when(vm.getType()).thenReturn(VirtualMachine.Type.User); + when(vm.getInstanceName()).thenReturn(""); + when(vm.getUuid()).thenReturn("aaaa-bbbbb"); + + final VirtualMachine virtualMachine = mock(VirtualMachine.class); + when(vm.getVirtualMachine()).thenReturn(virtualMachine); + when(virtualMachine.getState()).thenReturn(State.Stopping); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final ReleaseVmVspAnswer answer = mock(ReleaseVmVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.release(nicProfile, vm, "aaaaa-fffff"); + } + + @Test + public void testImplementNetwork() throws URISyntaxException, InsufficientVirtualNetworkCapacityException { + final Network network = mock(Network.class); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + when(network.getAccountId()).thenReturn(NETWORK_ID); + when(network.getVpcId()).thenReturn(null); + when(network.getState()).thenReturn(com.cloud.network.Network.State.Implementing); + when(network.getTrafficType()).thenReturn(TrafficType.Guest); + when(network.getMode()).thenReturn(Mode.Static); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1")); + when(network.getGateway()).thenReturn("10.1.1.1"); + when(network.getCidr()).thenReturn("10.1.1.0/24"); + when(network.getName()).thenReturn("iso"); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getTags()).thenReturn("aaaa"); + when(offering.getEgressDefaultPolicy()).thenReturn(true); + + when(networkModel.findPhysicalNetworkId(NETWORK_ID, "aaa", TrafficType.Guest)).thenReturn(NETWORK_ID); + + final ReservationContext reserveContext = mock(ReservationContext.class); + final Domain domain = mock(Domain.class); + when(reserveContext.getDomain()).thenReturn(domain); + when(domain.getName()).thenReturn("aaaaa"); + final Account account = mock(Account.class); + when(account.getAccountId()).thenReturn(NETWORK_ID); + when(reserveContext.getAccount()).thenReturn(account); + final DomainVO domainVo = mock(DomainVO.class); + when(domainDao.findById(NETWORK_ID)).thenReturn(domainVo); + final AccountVO accountVo = mock(AccountVO.class); + when(accountDao.findById(NETWORK_ID)).thenReturn(accountVo); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final ImplementNetworkVspAnswer answer = mock(ImplementNetworkVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + final DataCenter dc = mock(DataCenter.class); + when(dc.getId()).thenReturn(NETWORK_ID); + final DeployDestination deployDest = mock(DeployDestination.class); + when(deployDest.getDataCenter()).thenReturn(dc); + guru.implement(network, offering, deployDest, reserveContext); + } + +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java new file mode 100644 index 0000000000..a8bed6d119 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java @@ -0,0 +1,111 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.network.manager; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; + +import javax.naming.ConfigurationException; + +import org.junit.Before; +import org.junit.Test; + +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.resource.ResourceManager; + +public class NuageVspManagerTest { + private static final long NETWORK_ID = 42L; + + PhysicalNetworkDao physicalNetworkDao = mock(PhysicalNetworkDao.class); + PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao = mock(PhysicalNetworkServiceProviderDao.class); + ResourceManager resourceMgr = mock(ResourceManager.class); + HostDetailsDao hostDetailsDao = mock(HostDetailsDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + NetworkDao networkDao = mock(NetworkDao.class); + HostDao hostDao = mock(HostDao.class); + + NuageVspManagerImpl manager; + + @Before + public void setUp() { + manager = new NuageVspManagerImpl(); + + manager._physicalNetworkServiceProviderDao = physicalNetworkServiceProviderDao; + manager._physicalNetworkDao = physicalNetworkDao; + manager._resourceMgr = resourceMgr; + manager._hostDetailsDao = hostDetailsDao; + manager._nuageVspDao = nuageVspDao; + manager._networkDao = networkDao; + manager._hostDao = hostDao; + } + + @Test + public void testDeleteNuageVspDevice() throws ConfigurationException { + + final PhysicalNetworkVO physicalNetwork = mock(PhysicalNetworkVO.class); + when(physicalNetwork.getDataCenterId()).thenReturn(NETWORK_ID); + when(physicalNetwork.getId()).thenReturn(NETWORK_ID); + when(physicalNetworkDao.findById(NETWORK_ID)).thenReturn(physicalNetwork); + + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.findById(NETWORK_ID)).thenReturn(nuageVspDevice); + + when(networkDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(new ArrayList()); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final DeleteNuageVspDeviceCmd cmd = mock(DeleteNuageVspDeviceCmd.class); + when(cmd.getNuageVspDeviceId()).thenReturn(NETWORK_ID); + + manager.deleteNuageVspDevice(cmd); + } + + @Test + public void testListNuageVspDevices() { + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + + final PhysicalNetworkVO phyNtwkVO = mock(PhysicalNetworkVO.class); + when(physicalNetworkDao.findById(NETWORK_ID)).thenReturn(phyNtwkVO); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(new ArrayList()); + + final ListNuageVspDevicesCmd cmd = mock(ListNuageVspDevicesCmd.class); + when(cmd.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(cmd.getNuageVspDeviceId()).thenReturn(null); + manager.listNuageVspDevices(cmd); + } +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java new file mode 100644 index 0000000000..db359b6768 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java @@ -0,0 +1,252 @@ +// +// 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 static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import net.nuage.vsp.acs.client.NuageVspApiClient; +import net.nuage.vsp.acs.client.NuageVspElementClient; +import net.nuage.vsp.acs.client.NuageVspGuruClient; +import net.nuage.vsp.acs.client.NuageVspSyncClient; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.agent.api.element.ShutDownVpcVspAnswer; +import com.cloud.agent.api.element.ShutDownVpcVspCommand; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.Host; + +public class NuageVspResourceTest { + NuageVspResource _resource; + NuageVspApiClient _mockNuageVspApiClient = mock(NuageVspApiClient.class); + NuageVspElementClient _mockNuageVspElementClient = mock(NuageVspElementClient.class); + NuageVspGuruClient _mockNuageVspGuruClient = mock(NuageVspGuruClient.class); + NuageVspSyncClient _mockNuageVspSyncClient = mock(NuageVspSyncClient.class); + Map _parameters; + + Answer genericAnswer = new Answer() { + public Object answer(InvocationOnMock invocation) { + return null; + } + }; + + @Before + public void setUp() throws Exception { + _resource = new NuageVspResource() { + + @Override + protected void loadNuageClient() { + _isNuageVspClientLoaded = true; + _nuageVspApiClient = _mockNuageVspApiClient; + _nuageVspElementClient = _mockNuageVspElementClient; + _nuageVspGuruClient = _mockNuageVspGuruClient; + _nuageVspSyncClient = _mockNuageVspSyncClient; + + } + + protected void isNuageVspApiLoaded() throws Exception { + } + + protected void isNuageVspGuruLoaded() throws Exception { + } + + protected void isNuageVspElementLoaded() throws Exception { + } + + protected void isNuageVspSyncLoaded() throws Exception { + } + + protected void login() throws Exception { + } + + }; + + _parameters = new HashMap(); + _parameters.put("name", "nuagevsptestdevice"); + _parameters.put("guid", "aaaaa-bbbbb-ccccc"); + _parameters.put("zoneId", "blublub"); + _parameters.put("hostname", "nuagevsd"); + _parameters.put("cmsuser", "cmsuser"); + _parameters.put("cmsuserpass", "cmsuserpass"); + _parameters.put("port", "8443"); + _parameters.put("apirelativepath", "nuage/api/v1_0"); + _parameters.put("retrycount", "3"); + _parameters.put("retryinterval", "3"); + } + + @Test(expected = Exception.class) + public void resourceConfigureFailure() throws Exception { + _resource.configure("NuageVspResource", Collections. emptyMap()); + } + + @Test + public void resourceConfigure() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + assertTrue("nuagevsptestdevice".equals(_resource.getName())); + assertTrue(_resource.getType() == Host.Type.L2Networking); + } + + @Test + public void testInitialization() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + StartupCommand[] sc = _resource.initialize(); + assertTrue(sc.length == 1); + assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid())); + assertTrue("nuagevsptestdevice".equals(sc[0].getName())); + assertTrue("blublub".equals(sc[0].getDataCenter())); + } + + @Test + public void testPingCommandStatus() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + PingCommand ping = _resource.getCurrentStatus(42); + assertTrue(ping != null); + assertTrue(ping.getHostId() == 42); + assertTrue(ping.getHostType() == Host.Type.L2Networking); + } + + @Test + public void testImplementNetworkVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ImplementNetworkVspCommand impNtwkCmd = new ImplementNetworkVspCommand("networkDomainName", "networkDomainPath", "networkDomainUuid", "networkAccountName", + "networkAccountUuid", "networkName", "networkCidr", "networkGateway", "networkUuid", true, "vpcName", "vpcUuid", true, new ArrayList()); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).implement("networkDomainName", "networkDomainPath", "networkDomainUuid", "networkAccountName", "networkAccountUuid", + "networkName", "networkCidr", "networkGateway", "networkUuid", true, "vpcName", "vpcUuid", true, new ArrayList()); + ImplementNetworkVspAnswer implNtwkAns = (ImplementNetworkVspAnswer)_resource.executeRequest(impNtwkCmd); + assertTrue(implNtwkAns.getResult()); + } + + @Test + public void testReserveVmInterfaceVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ReserveVmInterfaceVspCommand rsrvVmInfCmd = new ReserveVmInterfaceVspCommand("nicUuid", "nicMacAddress", "networkUuid", true, "vpcUuid", "networkDomainUuid", + "networksAccountUuid", false, "domainRouterIp", "vmInstanceName", "vmUuid", "vmUserName", "vmUserDomainName"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).reserve("nicUuid", "nicMacAddress", "networkUuid", true, "vpcUuid", "networkDomainUuid", "networksAccountUuid", + false, "domainRouterIp", "vmInstanceName", "vmUuid"); + ReserveVmInterfaceVspAnswer rsrvVmInfAns = (ReserveVmInterfaceVspAnswer)_resource.executeRequest(rsrvVmInfCmd); + assertTrue(rsrvVmInfAns.getResult()); + } + + @Test + public void testReleaseVmVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ReleaseVmVspCommand releaseVmCmd = new ReleaseVmVspCommand("networkUuid", "vmUuid", "vmInstanceName"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).release("networkUuid", "vmUuid", "vmInstanceName"); + ReleaseVmVspAnswer releaseVmAns = (ReleaseVmVspAnswer)_resource.executeRequest(releaseVmCmd); + assertTrue(releaseVmAns.getResult()); + } + + @Test + public void testDeallocateVmVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + DeallocateVmVspCommand dellocateVmCmd = new DeallocateVmVspCommand("networkUuid", "nicFrmDdUuid", "nicMacAddress", "nicIp4Address", true, "vpcUuid", "networksDomainUuid", + "vmInstanceName", "vmUuid"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).deallocate("networkUuid", "nicFrmDdUuid", "nicMacAddress", "nicIp4Address", true, "vpcUuid", "networksDomainUuid", + "vmInstanceName", "vmUuid"); + DeallocateVmVspAnswer dellocateVmAns = (DeallocateVmVspAnswer)_resource.executeRequest(dellocateVmCmd); + assertTrue(dellocateVmAns.getResult()); + } + + @Test + public void testTrashNetworkVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + TrashNetworkVspCommand trashNtwkCmd = new TrashNetworkVspCommand("domainUuid", "networkUuid", true, "vpcUuid"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).trash("domainUuid", "networkUuid", true, "vpcUuid"); + TrashNetworkVspAnswer trashNtwkAns = (TrashNetworkVspAnswer)_resource.executeRequest(trashNtwkCmd); + assertTrue(trashNtwkAns.getResult()); + } + + @Test + public void testApplyStaticNatVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ApplyStaticNatVspCommand applyNatCmd = new ApplyStaticNatVspCommand("networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>()); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyStaticNats("networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>()); + ApplyStaticNatVspAnswer applyNatAns = (ApplyStaticNatVspAnswer)_resource.executeRequest(applyNatCmd); + assertTrue(applyNatAns.getResult()); + } + + @Test + public void testApplyAclRuleVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ApplyAclRuleVspCommand applyAclCmd = new ApplyAclRuleVspCommand("networkUuid", "networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>(), false, + 100); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyAclRules("networkUuid", "networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>(), + false, 100); + ApplyAclRuleVspAnswer applyAclAns = (ApplyAclRuleVspAnswer)_resource.executeRequest(applyAclCmd); + assertTrue(applyAclAns.getResult()); + } + + @Test + public void testShutDownVpcVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ShutDownVpcVspCommand shutVpcCmd = new ShutDownVpcVspCommand("domainUuid", "vpcUuid"); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).shutDownVpc("domainUuid", "vpcUuid"); + ShutDownVpcVspAnswer shutVpcAns = (ShutDownVpcVspAnswer)_resource.executeRequest(shutVpcCmd); + assertTrue(shutVpcAns.getResult()); + } + + @Test + public void testSyncVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + SyncVspCommand shutVpcCmd = new SyncVspCommand("nuageVspEntity"); + doAnswer(genericAnswer).when(_mockNuageVspSyncClient).syncWithNuageVsp("nuageVspEntity"); + SyncVspAnswer shutVpcAns = (SyncVspAnswer)_resource.executeRequest(shutVpcCmd); + assertTrue(shutVpcAns.getResult()); + } +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java new file mode 100644 index 0000000000..f9e503d5ae --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java @@ -0,0 +1,73 @@ +// +// 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.sync; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; + +public class NuageVspSyncTest { + private static final long NETWORK_ID = 42L; + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + AgentManager agentManager = mock(AgentManager.class); + HostDao hostDao = mock(HostDao.class); + + NuageVspSyncImpl sync; + + @Before + public void setUp() { + sync = new NuageVspSyncImpl(); + sync._nuageVspDao = nuageVspDao; + sync._agentMgr = agentManager; + sync._hostDao = hostDao; + } + + @Test + public void testSyncWithNuageVsp() { + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDevice.getId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listAll()).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final SyncVspAnswer answer = mock(SyncVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + sync.syncWithNuageVsp("users"); + } +} diff --git a/plugins/pom.xml b/plugins/pom.xml index 802e2ea375..eff5a01856 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -163,6 +163,17 @@ network-elements/juniper-srx + + nuagevsp + + + noredist + + + + network-elements/nuage-vsp + + vmware diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 51122e0c9e..013da0b70b 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2304,7 +2304,7 @@ public ServiceResponse createNetworkServiceResponse(Service service) { for (Network.Provider serviceProvider : serviceProviders) { // return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall if (service == Service.Firewall - && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto)) { + && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp)) { continue; } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1940f4839a..42ac19fb98 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -4496,7 +4496,8 @@ public List searchForNetworkOfferings(ListNetworkOffe @Override public boolean isOfferingForVpc(NetworkOffering offering) { boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter) || - _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter); + _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter) || + _ntwkOffServiceMapDao.getDistinctProviders(offering.getId()).contains(Provider.NuageVsp.getName()); return vpcProvider; } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index c7237c1541..9971bd5583 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -207,7 +207,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter, - Provider.Ovs); + Provider.Ovs, Provider.NuageVsp); int _cleanupInterval; int _maxNetworks; @@ -320,6 +320,7 @@ public VpcOffering createVpcOffering(String name, String displayText, List sdnProviders = new HashSet(); sdnProviders.add(Provider.NiciraNvp); sdnProviders.add(Provider.JuniperContrailVpcRouter); + sdnProviders.add(Provider.NuageVsp); boolean sourceNatSvc = false; boolean firewallSvs = false; diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index d047060d26..6cb81c65fa 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -63,6 +63,18 @@ CREATE VIEW `cloud`.`disk_offering_view` AS where disk_offering.state='ACTIVE'; +DROP TABLE IF EXISTS `cloud`.`external_nuage_vsp_devices`; +CREATE TABLE `cloud`.`external_nuage_vsp_devices` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which nuage vsp is added', + `provider_name` varchar(255) NOT NULL COMMENT 'the service provider name corresponding to this nuage vsp device', + `device_name` varchar(255) NOT NULL COMMENT 'the name of the nuage vsp device', + `host_id` bigint unsigned NOT NULL COMMENT 'host id corresponding to the external nuage vsp device', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_nuage_vsp_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_nuage_vsp_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP VIEW IF EXISTS `cloud`.`service_offering_view`; CREATE VIEW `cloud`.`service_offering_view` AS diff --git a/test/integration/component/test_nuage_vsp.py b/test/integration/component/test_nuage_vsp.py new file mode 100644 index 0000000000..143fe391a7 --- /dev/null +++ b/test/integration/component/test_nuage_vsp.py @@ -0,0 +1,312 @@ +# 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. + +""" P1 tests for NuageVsp network Plugin +""" +#Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources, + random_gen, validateList) +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Host, + Network, + NATRule, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.sshClient import SshClient +from marvin.codes import PASS +import time + + +class Services: + """Test NuageVsp plugin + """ + + def __init__(self): + self.services = { + "account": { + "email": "cloudstack@cloudmonkey.com", + "firstname": "cloudstack", + "lastname": "bob", + "username": "bobbuilder", + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "virtual_machine": { + "displayname": "TestVM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "nuage_vsp_device": { + "hostname": '192.168.0.7', + "username": 'testusername', + "password": 'testpassword', + "port": '8443', + "apiversion": 'v1_0', + "retrycount": '4', + "retryinterval": '60' + }, + #services supported by Nuage for isolated networks. + "network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "UserData": 'VirtualRouter', + "Dhcp" : 'NuageVsp', + "Connectivity" : 'NuageVsp', + "StaticNat" : 'NuageVsp', + "SourceNat" : 'NuageVsp', + "Firewall" : 'NuageVsp' + }, + }, + "network": { + "name": "nuage", + "displaytext": "nuage", + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + "timeout": 10 + } + +class TestNuageVsp(cloudstackTestCase): + + + @classmethod + def setUpClass(cls): + cls._cleanup = [] + cls.testClient = super(TestNuageVsp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + #nuage vsp device brings the Nuage virtual service platform into play + cls.nuage_services = cls.services["nuage_vsp_device"] + try: + + resp = listPhysicalNetworks.listPhysicalNetworksCmd() + resp.zoneid = cls.zone.id + physical_networks = cls.api_client.listPhysicalNetworks(resp) + if isinstance(physical_networks, list): + physical_network = physical_networks[1] + resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd() + resp.name = 'NuageVsp' + resp.physicalnetworkid = physical_network.id + nw_service_providers = cls.api_client.listNetworkServiceProviders(resp) + if isinstance(nw_service_providers, list): + nuage_provider = nw_service_providers[0] + else: + #create network service provider and add nuage vsp device + resp_add_nsp = addNetworkServiceProvider.addNetworkServiceProviderCmd() + resp_add_nsp.name = 'NuageVsp' + resp_add_nsp.physicalnetworkid = physical_network.id + nuage_provider = cls.api_client.addNetworkServiceProvider(resp_add_nsp) + resp_add_device = addNuageVspDevice.addNuageVspDeviceCmd() + resp_add_device.physicalnetworkid = physical_network.id + resp_add_device.username = cls.nuage_services["username"] + resp_add_device.password = cls.nuage_services["password"] + resp_add_device.hostname = cls.nuage_services["hostname"] + resp_add_device.apiversion = cls.nuage_services["apiversion"] + resp_add_device.retrycount = cls.nuage_services["retrycount"] + resp_add_device.retryinterval = cls.nuage_services["retryinterval"] + cls.nuage = cls.api_client.addNuageVspDevice(resp_add_device) + + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + cls._cleanup.append(cls.network_offering) + + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise Exception ("Warning: Exception in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + interval = Configurations.list( + self.apiclient, + name='network.gc.interval' + ) + wait = Configurations.list( + self.apiclient, + name='network.gc.wait' + ) + #time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + + @attr(tags = ["advancedns"]) + def test_network_vsp(self): + """Test nuage Network and VM Creation + """ + + + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network.id) + + self.debug("Deploying VM in account: %s" % self.account.name) + + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Deploying another VM in account: %s" % + self.account.name) + + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + VirtualMachine.delete(virtual_machine_1, self.apiclient) + + # Deleting a single VM + VirtualMachine.delete(virtual_machine_2, self.apiclient) + + # Delete Network + Network.delete(self.network, self.apiclient) + + return diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index 827d6bf4e4..bcc8417c3c 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -133,6 +133,7 @@ 'Tags': 'Resource tags', 'NiciraNvpDevice': 'Nicira NVP', 'BigSwitchVnsDevice': 'BigSwitch VNS', + 'NuageVsp': 'Nuage VSP', 'AutoScale': 'AutoScale', 'Counter': 'AutoScale', 'Condition': 'AutoScale', diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index e9d84de9b2..c84d0ddea0 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -351,6 +351,7 @@ dictionary = { 'label.add.new.PA': '', 'label.add.new.tier': '', 'label.add.NiciraNvp.device': '', +'label.add.NuageVsp.device': '', 'label.add.pod': '', 'label.add.port.forwarding.rule': '', 'label.add.primary.storage': '', @@ -399,6 +400,7 @@ dictionary = { 'label.anti.affinity.group': '', 'label.anti.affinity.groups': '', 'label.api.key': '', +'label.api.version': '', 'label.apply': '', 'label.assign': '', 'label.assign.to.load.balancer': '', @@ -506,6 +508,7 @@ dictionary = { 'label.delete.gateway': '', 'label.delete.NetScaler': '', 'label.delete.NiciraNvp': '', +'label.delete.NuageVsp': '', 'label.delete.project': '', 'label.delete.SRX': '', 'label.delete.PA': '', @@ -998,6 +1001,7 @@ dictionary = { 'label.restart.required': '', 'label.restart.vpc': '', 'label.restore': '', +'label.retry.interval': '', 'label.review': '', 'label.revoke.project.invite': '', 'label.role': '', @@ -1430,6 +1434,7 @@ dictionary = { 'message.confirm.action.force.reconnect': '', 'message.confirm.delete.F5': '', 'message.confirm.delete.NetScaler': '', +'message.confirm.delete.NuageVsp': '', 'message.confirm.delete.SRX': '', 'message.confirm.delete.PA': '', 'message.confirm.destroy.router': '', diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 9311e37842..895f8e86d4 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -2176,7 +2176,7 @@ //p.s. Netscaler is supported in both vpc and non-vpc if ($useVpc.is(':visible') && $useVpcCb.is(':checked')) { //*** vpc *** $optionsOfProviders.each(function(index) { - if ($(this).val() == 'InternalLbVm' || $(this).val() == 'VpcVirtualRouter' || $(this).val() == 'Netscaler') { + if ($(this).val() == 'InternalLbVm' || $(this).val() == 'VpcVirtualRouter' || $(this).val() == 'Netscaler' || $(this).val() == 'NuageVsp' || $(this).val() == 'NuageVspVpc') { $(this).attr('disabled', false); } else { $(this).attr('disabled', true); @@ -3456,7 +3456,9 @@ var networkServiceObjs = []; networkServiceObjs.push({ name: 'Dhcp', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'Dns', @@ -3472,15 +3474,21 @@ }); networkServiceObjs.push({ name: 'StaticNat', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'SourceNat', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'NetworkACL', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'PortForwarding', @@ -3500,7 +3508,8 @@ provider: [ {name: 'NiciraNvp'}, {name: 'Ovs'}, - {name: 'JuniperContrailVpcRouter'} + {name: 'JuniperContrailVpcRouter'}, + {name: 'NuageVsp'} ] }); diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 74a08bc8db..2075e30f02 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -1250,5 +1250,34 @@ cloudStack.docs = { helpVpcOfferingDescription: { desc: 'A short description of the offering that can be displayed to users', externalLink: '' + }, + // Add Nuage VSP + helpVspHostname: { + desc: 'The hostname/IP address of Nuage VSD', + externalLink: '' + }, + helpVspUsername: { + desc: 'A name of the CMS user in Nuage VSD.', + externalLink: '' + }, + helpVspPassword: { + desc: 'The password for the CMS user in Nuage VSD.', + externalLink: '' + }, + helpVspPort: { + desc: 'The port to communicate with Nuage VSD. e.g. Unspecified/0 if using HAProxy for load balancing or 8443 if connecting directly to a VSD server.', + externalLink: '' + }, + helpVspApiVersion: { + desc: 'The API version of Nuage VSD', + externalLink: '' + }, + helpVspRetries: { + desc: 'Number of times to attempt a command on Nuage VSD before considering the operation failed. Valid values [1 - 10].', + externalLink: '' + }, + helpVspRetryInterval: { + desc: 'The interval of time in milliseconds to wait on failure before attempting to resend the command to Nuage VSD. Valid values [0 - 10000].', + externalLink: '' } }; diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 9012580189..502007f501 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -6689,6 +6689,249 @@ } } }, + // Nuage Vsp provider detail view + nuageVsp: { + type: 'detailView', + id: 'nuageVspProvider', + label: 'label.nuageVsp', + viewAll: { + label: 'label.devices', + path: '_zone.nuageVspDevices' + }, + tabs: { + details: { + title: 'label.details', + fields: [{ + name: { + label: 'label.name' + } + }, { + state: { + label: 'label.state' + } + }], + dataProvider: function(args) { + refreshNspData("NuageVsp"); + var providerObj; + $(nspHardcodingArray).each(function() { + if (this.id == "nuageVsp") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('nuageVsp') + }); + } + } + }, + actions: { + add: { + label: 'label.add.NuageVsp.device', + createForm: { + title: 'label.add.NuageVsp.device', + preFilter: function(args) {}, + fields: { + hostname: { + label: 'label.host.name', + validation: { + required: true + }, + docID: 'helpVspHostname' + }, + username: { + label: 'label.username', + validation: { + required: true + }, + docID: 'helpVspUsername' + }, + password: { + label: 'label.password', + isPassword: true, + validation: { + required: true + }, + docID: 'helpVspPassword' + }, + port: { + label: 'label.port', + validation: { + required: false, + number: true + }, + docID: 'helpVspPort' + }, + apiversion: { + label: 'label.api.version', + defaultValue: 'v1_0', + validation: { + required: true + }, + docID: 'helpVspApiVersion' + }, + retrycount: { + label: 'label.numretries', + defaultValue: '4', + validation: { + required: true, + number: true + }, + docID: 'helpVspRetries' + }, + retryinterval: { + label: 'label.retry.interval', + defaultValue: '60', + validation: { + required: false, + number: true + }, + docID: 'helpVspRetryInterval' + } + } + }, + action: function(args) { + if (nspMap["nuageVsp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NuageVsp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNuageVspProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + clearInterval(addNuageVspProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["nuageVsp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } else { + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } + }, + messages: { + notification: function(args) { + return 'label.add.NuageVsp.device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["nuageVsp"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["nuageVsp"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["nuageVsp"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + } + }, Opendaylight: { type: 'detailView', id: 'openDaylightProvider', @@ -11953,6 +12196,202 @@ } } }, + nuageVspDevices: { + id: 'nuageVspDevices', + title: 'label.devices', + listView: { + id: 'nuageVspDevices', + fields: { + hostname: { + label: 'label.host.name' + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version' + }, + retrycount: { + label: 'label.numretries', + }, + retryinterval: { + label: 'label.retry.interval' + } + }, + actions: { + add: { + label: 'label.add.NuageVsp.device', + createForm: { + title: 'label.add.NuageVsp.device', + preFilter: function(args) {}, + fields: { + hostname: { + label: 'label.host.name' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version', + defaultValue: 'v1_0' + }, + retrycount: { + label: 'label.numretries', + defaultValue: '4' + }, + retryinterval: { + label: 'label.retry.interval', + defaultValue: '60' + } + } + }, + action: function(args) { + if (nspMap["nuageVsp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NuageVsp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNuageVspProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; + } else { + clearInterval(addNuageVspProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["nuageVsp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } else { + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } + }, + + messages: { + notification: function(args) { + return 'Added new Nuage Vsp Controller'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + dataProvider: function(args) { + $.ajax({ + url: createURL("listNuageVspDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + data: { + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listnuagevspdeviceresponse.nuagevspdevice; + args.response.success({ + data: items + }); + } + }); + }, + detailView: { + name: 'Nuage Vsp details', + actions: { + 'remove': { + label: 'label.delete.NuageVsp', + messages: { + confirm: function(args) { + return 'message.confirm.delete.NuageVsp'; + }, + notification: function(args) { + return 'label.delete.NuageVsp'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteNuageVspDevice&vspdeviceid=" + args.context.nuageVspDevices[0].vspdeviceid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deletenuagevspdeviceresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + fields: [{ + vspdeviceid: { + label: 'label.id' + }, + hostname: { + label: 'label.host.name' + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version' + }, + retrycount: { + label: 'label.numretries', + }, + retryinterval: { + label: 'label.retry.interval' + } + }], + dataProvider: function(args) { + $.ajax({ + url: createURL("listNuageVspDevices&vspdeviceid=" + args.context.nuageVspDevices[0].vspdeviceid), + dataType: "json", + async: true, + success: function(json) { + var item = json.listnuagevspdeviceresponse.nuagevspdevice[0]; + args.response.success({ + data: item + }); + } + }); + } + } + } + } + } + }, pods: { title: 'label.pods', listView: { @@ -18817,8 +19256,39 @@ }); } - var afterCreateZonePhysicalNetworkTrafficTypes = function (args, newZoneObj, newPhysicalnetwork) { + function addNuageVspDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { + var array1 = []; + array1.push("&physicalnetworkid=" + physicalNetworkObj.id); + array1.push("&hostname=" + todb(args.data.hostname)); + array1.push("&username=" + todb(args.data.username)); + array1.push("&password=" + todb(args.data.password)); + array1.push("&port=" + todb(args.data.port)); + array1.push("&apiversion=" + todb(args.data.apiversion)); + array1.push("&retrycount=" + todb(args.data.retrycount)); + array1.push("&retryinterval=" + todb(args.data.retryinterval)); + $.ajax({ + url: createURL(apiCmd + array1.join("")), + dataType: "json", + type: "POST", + success: function(json) { + var jid = json[apiCmdRes].jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult[apiCmdObj]; + + return item; + } + } + }); + } + }); + } + + var afterCreateZonePhysicalNetworkTrafficTypes = function (args, newZoneObj, newPhysicalnetwork) { + $.ajax({ url: createURL("updatePhysicalNetwork&state=Enabled&id=" + newPhysicalnetwork.id), dataType: "json", success: function (json) { @@ -19495,6 +19965,9 @@ case "Opendaylight": nspMap[ "Opendaylight"] = items[i]; break; + case "NuageVsp": + nspMap["nuageVsp"] = items[i]; + break; } } } @@ -19560,6 +20033,12 @@ name: 'MidoNet', state: nspMap.midoNet ? nspMap.midoNet.state: 'Disabled' }); + + nspHardcodingArray.push({ + id: 'nuageVsp', + name: 'Nuage Vsp', + state: nspMap.nuageVsp ? nspMap.nuageVsp.state : 'Disabled' + }); nspHardcodingArray.push({ id: 'InternalLbVm', diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 4091c035a1..645c2b1b94 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -726,7 +726,10 @@ }).html('ODL'), $(' + + nuagevsp + + + noredist + + + + network-elements/nuage-vsp + + From fe4e4858ce24de153b06b87a9bbcb40850f34301 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Mon, 21 Jul 2014 11:14:29 +0200 Subject: [PATCH 130/819] Let's blame it on the fact that its monday --- client/pom.xml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index d4ead21e5a..410cb19a1a 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -1028,16 +1028,5 @@ - - nuagevsp - - - noredist - - - - network-elements/nuage-vsp - - From b8ddbe8ffa5718c5ab5c9b3438467c284af0de50 Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Fri, 28 Mar 2014 18:47:05 +0530 Subject: [PATCH 131/819] CLOUDSTACK-6239: Encrypt security related config values before inserting into DB --- .../framework/security/keys/KeysManagerImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java index 550bd155c9..15bb49c65f 100644 --- a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java @@ -61,7 +61,7 @@ public class KeysManagerImpl implements KeysManager, Configurable { public String getHashKey() { String value = HashKey.value(); if (value == null) { - _configDepot.set(HashKey, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(HashKey.key(), HashKey.category(), getBase64EncodedRandomKey(128), HashKey.description()); } return HashKey.value(); @@ -71,7 +71,8 @@ public String getHashKey() { public String getEncryptionKey() { String value = EncryptionKey.value(); if (value == null) { - _configDepot.set(EncryptionKey, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(EncryptionKey.key(), EncryptionKey.category(), getBase64EncodedRandomKey(128), + EncryptionKey.description()); } return EncryptionKey.value(); } @@ -80,7 +81,8 @@ public String getEncryptionKey() { public String getEncryptionIV() { String value = EncryptionIV.value(); if (value == null) { - _configDepot.set(EncryptionIV, getBase64EncodedRandomKey(128)); + _configDao.getValueAndInitIfNotExist(EncryptionIV.key(), EncryptionIV.category(), getBase64EncodedRandomKey(128), + EncryptionIV.description()); } return EncryptionIV.value(); } From 9dc322d46fa5cfb9abd87c408988abad1219d607 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Mon, 21 Jul 2014 16:48:28 +0530 Subject: [PATCH 132/819] CLOUDSTACK-7144: No GSLB provider is available during assigning load balancing rule this fix ensures any bean implementing GslbProvider interface are injected into GlobalLoadBalancingRulesServiceImpl. --- .../spring-core-registry-core-context.xml | 5 +++++ ...-lifecycle-network-context-inheritable.xml | 8 +++++-- .../spring-server-core-managers-context.xml | 5 +++-- .../GlobalLoadBalancingRulesServiceImpl.java | 21 ++++++++++++------- ...obalLoadBalancingRulesServiceImplTest.java | 4 +++- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index 908d8f0652..02034d66e1 100644 --- a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -234,6 +234,11 @@ + + + + diff --git a/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml b/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml index e5086d2137..1986777f2d 100644 --- a/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml +++ b/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml @@ -98,5 +98,9 @@ - - \ No newline at end of file + + + + + diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index fc1c7e23b9..1eba0b2230 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -224,7 +224,8 @@ - + class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" > + + diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java index c84fea29d5..1d2c62bf63 100644 --- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -95,10 +95,10 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR @Inject AgentManager _agentMgr; - protected GslbServiceProvider _gslbProvider = null; + protected List _gslbProviders; - public void setGslbServiceProvider(GslbServiceProvider provider) { - _gslbProvider = provider; + public void setGslbServiceProviders(List providers) { + _gslbProviders = providers; } @Override @@ -656,8 +656,8 @@ private boolean applyGlobalLoadBalancerRuleConfig(long gslbRuleId, boolean revok new SiteLoadBalancerConfig(gslbLbMapVo.isRevoke(), serviceType, ip.getAddress().addr(), Integer.toString(loadBalancer.getDefaultPortStart()), dataCenterId); - siteLb.setGslbProviderPublicIp(_gslbProvider.getZoneGslbProviderPublicIp(dataCenterId, physicalNetworkId)); - siteLb.setGslbProviderPrivateIp(_gslbProvider.getZoneGslbProviderPrivateIp(dataCenterId, physicalNetworkId)); + siteLb.setGslbProviderPublicIp(lookupGslbServiceProvider().getZoneGslbProviderPublicIp(dataCenterId, physicalNetworkId)); + siteLb.setGslbProviderPrivateIp(lookupGslbServiceProvider().getZoneGslbProviderPrivateIp(dataCenterId, physicalNetworkId)); siteLb.setWeight(gslbLbMapVo.getWeight()); zoneSiteLoadbalancerMap.put(network.getDataCenterId(), siteLb); @@ -686,7 +686,7 @@ private boolean applyGlobalLoadBalancerRuleConfig(long gslbRuleId, boolean revok } try { - _gslbProvider.applyGlobalLoadBalancerRule(zoneId.first(), zoneId.second(), gslbConfigCmd); + lookupGslbServiceProvider().applyGlobalLoadBalancerRule(zoneId.first(), zoneId.second(), gslbConfigCmd); } catch (ResourceUnavailableException e) { String msg = "Failed to configure GSLB rule in the zone " + zoneId.first() + " due to " + e.getMessage(); s_logger.warn(msg); @@ -711,11 +711,16 @@ public boolean revokeAllGslbRulesForAccount(com.cloud.user.Account caller, long private boolean checkGslbServiceEnabledInZone(long zoneId, long physicalNetworkId) { - if (_gslbProvider == null) { + GslbServiceProvider gslbProvider = lookupGslbServiceProvider(); + if (gslbProvider == null) { throw new CloudRuntimeException("No GSLB provider is available"); } - return _gslbProvider.isServiceEnabledInZone(zoneId, physicalNetworkId); + return gslbProvider.isServiceEnabledInZone(zoneId, physicalNetworkId); + } + + protected GslbServiceProvider lookupGslbServiceProvider() { + return _gslbProviders.size() == 0 ? null : _gslbProviders.get(0); } @Override diff --git a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java index d152c6668b..94bc3c745c 100644 --- a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java +++ b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java @@ -720,7 +720,9 @@ void runRemoveFromGlobalLoadBalancerRuleTest() throws Exception { gslbServiceImpl._globalConfigDao = Mockito.mock(ConfigurationDao.class); gslbServiceImpl._ipAddressDao = Mockito.mock(IPAddressDao.class); gslbServiceImpl._agentMgr = Mockito.mock(AgentManager.class); - gslbServiceImpl._gslbProvider = Mockito.mock(GslbServiceProvider.class); + List mockGslbProviders = new ArrayList(); + mockGslbProviders.add(Mockito.mock(GslbServiceProvider.class)); + gslbServiceImpl._gslbProviders = mockGslbProviders; RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd = new RemoveFromGlobalLoadBalancerRuleCmdExtn(); Class _class = removeFromGslbCmd.getClass().getSuperclass(); From 58bad41910970fb3b08aa4d21875af6d04c8bf2e Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Thu, 17 Jul 2014 11:44:26 +0530 Subject: [PATCH 133/819] Fixed CLOUDSTACK-6983: unable to register lxc template added a check for tar.gz format in checktemplate --- .../apache/cloudstack/utils/template/TemplateUtils.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java b/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java index a3f3a682a5..cf1e177e6d 100644 --- a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java +++ b/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java @@ -61,6 +61,13 @@ public static String checkTemplateFormat(String path, String url) { s_logger.debug("File at path " + path + " looks like ova : " + output); return ""; } + + //lxc + if (output.contains("POSIX tar") && isCorrectExtension(url, "tar")) { + s_logger.debug("File at path " + path + " looks like just tar : " + output); + return ""; + } + if (output.contains("ISO 9660") && isCorrectExtension(url, "iso")) { s_logger.debug("File at path " + path + " looks like an iso : " + output); return ""; From 77dadd75c49142b0cf3a4af29377d0fc54892b6a Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Mon, 21 Jul 2014 14:07:41 -0700 Subject: [PATCH 134/819] CLOUDSTACK-6787: Publishing uuids missing in some cases, adding/correcting events in some cases. Also fixed a bug in the global config framework. --- .../user/firewall/CreateEgressFirewallRuleCmd.java | 1 + .../apache/cloudstack/framework/config/ConfigKey.java | 2 +- .../src/com/cloud/network/as/AutoScaleManagerImpl.java | 9 +++++---- .../com/cloud/storage/snapshot/SnapshotManagerImpl.java | 3 +++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java index 1a0cfaed60..48ee0dfc9a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java @@ -261,6 +261,7 @@ public void create() { try { FirewallRule result = _firewallService.createEgressFirewallRule(this); setEntityId(result.getId()); + setEntityUuid(result.getUuid()); } catch (NetworkRuleConflictException ex) { s_logger.info("Network rule conflict: " + ex.getMessage()); s_logger.trace("Network Rule Conflict: ", ex); diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java b/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java index b400e6f9bd..d39bb5d356 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java @@ -133,7 +133,7 @@ public boolean equals(Object obj) { public T value() { if (_value == null || isDynamic()) { ConfigurationVO vo = s_depot != null ? s_depot.global().findById(key()) : null; - _value = valueOf(vo != null ? vo.getValue() : defaultValue()); + _value = valueOf((vo != null && vo.getValue() != null) ? vo.getValue() : defaultValue()); } return _value; diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 96d82adc34..01c1486dfa 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -795,6 +795,7 @@ public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) { } @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", async = true) public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) throws ResourceUnavailableException { return configureAutoScaleVmGroup(cmd.getEntityId(), AutoScaleVmGroup.State_New); } @@ -823,7 +824,7 @@ private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) t @Override @DB - @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group") + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group", async = true) public boolean deleteAutoScaleVmGroup(final long id) { AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); @@ -997,7 +998,7 @@ public AutoScaleVmGroupVO doInTransaction(TransactionStatus status) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group") + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group", async = true) public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) { Long vmGroupId = cmd.getId(); Integer minMembers = cmd.getMinMembers(); @@ -1046,7 +1047,7 @@ public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) { @Override @DB - @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group") + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group", async = true) public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) { AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); boolean success = false; @@ -1072,7 +1073,7 @@ public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group") + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group", async = true) @DB public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) { AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 5c114c518b..a8b7e5fa9e 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -639,6 +639,7 @@ public boolean deleteSnapshotDirsForAccount(long accountId) { @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_POLICY_CREATE, eventDescription = "creating snapshot policy") public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner) { Long volumeId = cmd.getVolumeId(); boolean display = cmd.isDisplay(); @@ -735,6 +736,8 @@ public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policy } } + // TODO - Make createSnapshotPolicy - BaseAsyncCreate and remove this. + CallContext.current().putContextParameter(SnapshotPolicy.class.getName(), policy.getUuid()); return policy; } From 88f35179ef90dc4f7696b6fe2e8ee7ca4d00586c Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Mon, 21 Jul 2014 19:10:34 -0400 Subject: [PATCH 135/819] Revert "CLOUDSTACK-7130: Adding BugId to failed test cases" This reverts commit 24da72f37395a6bb612ea1d073db0155289cf000. --- test/integration/smoke/test_volumes.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index c6c0accb20..7fbcc21647 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -113,7 +113,7 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_01_create_volume(self): """Test Volume creation for all Disk Offerings (incl. custom) """ @@ -343,7 +343,7 @@ def tearDown(self): cleanup_resources(self.apiClient, self.cleanup) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_02_attach_volume(self): """Attach a created Volume to a Running VM """ @@ -389,7 +389,7 @@ def test_02_attach_volume(self): (self.virtual_machine.ipaddress, e)) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_03_download_attached_volume(self): """Download a Volume attached to a VM """ @@ -411,7 +411,7 @@ def test_03_download_attached_volume(self): with self.assertRaises(Exception): self.apiClient.extractVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_04_delete_attached_volume(self): """Delete a Volume attached to a VM """ @@ -432,7 +432,7 @@ def test_04_delete_attached_volume(self): with self.assertRaises(Exception): self.apiClient.deleteVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_05_detach_volume(self): """Detach a Volume attached to a VM """ @@ -474,7 +474,7 @@ def test_05_detach_volume(self): ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_06_download_detached_volume(self): """Download a Volume unattached to an VM """ @@ -511,7 +511,7 @@ def test_06_download_detached_volume(self): % (extract_vol.url, self.volume.id) ) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_07_resize_fail(self): """Test resize (negative) non-existent volume""" # Verify the size is the new size is what we wanted it to be. @@ -729,7 +729,7 @@ def test_08_resize_volume(self): time.sleep(30) return - @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false", BugId="CLOUDSTACK-7130") + @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false") def test_09_delete_detached_volume(self): """Delete a Volume unattached to an VM """ From 4596ae9aac81ecec2c1de95950da431e7490b95d Mon Sep 17 00:00:00 2001 From: sanjeev Date: Thu, 17 Jul 2014 17:19:04 +0530 Subject: [PATCH 136/819] Changed delete method signature inside VirtualMachine class. From 4.3 onwards vm destroy has expunge parameter to expunge the vm immediately. Signed-off-by: sanjeev Signed-off-by: Santhosh Edukulla --- tools/marvin/marvin/lib/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index e9d5bb4b5b..8d405918cf 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -612,10 +612,11 @@ def update(self, apiclient, **kwargs): [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.updateVirtualMachine(cmd)) - def delete(self, apiclient): + def delete(self, apiclient, **kwargs): """Destroy an Instance""" cmd = destroyVirtualMachine.destroyVirtualMachineCmd() cmd.id = self.id + [setattr(cmd, k, v) for k, v in kwargs.items()] apiclient.destroyVirtualMachine(cmd) def expunge(self, apiclient): From b3e4c6d6dc9bf57aa880ab100a76027b2a12053d Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Tue, 22 Jul 2014 09:48:20 +0530 Subject: [PATCH 137/819] CLOUDSTACK-7150. [VMware] Global config 'vm.instancename' is not honored. If global config 'vm.instancename' is set to true, VM name in vCenter should be '-'. --- .../com/cloud/hypervisor/vmware/resource/VmwareResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 7b73b19e34..0c4ab20a19 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1832,7 +1832,8 @@ private Pair composeVmNames(VirtualMachineTO vmSpec) { vmInternalCSName = vmSpec.getName(); if (_instanceNameFlag == true) { String[] tokens = vmInternalCSName.split("-"); - vmNameOnVcenter = String.format("%s-%s-%s", tokens[0], tokens[1], vmSpec.getHostName()); + assert (tokens.length >= 3); // vmInternalCSName has format i-x-y- + vmNameOnVcenter = String.format("%s-%s-%s-%s", tokens[0], tokens[1], tokens[2], vmSpec.getHostName()); } else vmNameOnVcenter = vmSpec.getName(); From 493fd170543658ac7602e230a336985c59e8e1a1 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 14 Jul 2014 15:04:37 +0530 Subject: [PATCH 138/819] CLOUDSTACK-7152. Attaching datadisk to VMs that have VM snapshot throws 'Unexpected exception'. Like with other API commands, ensure input parameter validation for AttachVolume happens outside the job queue. --- .../cloud/storage/VolumeApiServiceImpl.java | 193 +++++++++--------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 64d6bc0bd1..ac2a88123d 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1141,50 +1141,77 @@ private boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransiti @Override public Volume attachVolumeToVM(AttachVolumeCmd command) { + return attachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); + } - AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); - if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { - // avoid re-entrance - - VmWorkJobVO placeHolder = null; - if (VmJobEnabled.value()) { - placeHolder = createPlaceHolderWork(command.getVirtualMachineId()); + private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { + VolumeInfo volumeToAttach = volFactory.getVolume(volumeId); + UserVmVO vm = _userVmDao.findById(vmId); + VolumeVO exstingVolumeOfVm = null; + List rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT); + if (rootVolumesOfVm.size() > 1) { + throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state."); + } else { + if (!rootVolumesOfVm.isEmpty()) { + exstingVolumeOfVm = rootVolumesOfVm.get(0); + } else { + // locate data volume of the vm + List diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK); + for (VolumeVO diskVolume : diskVolumesOfVm) { + if (diskVolume.getState() != Volume.State.Allocated) { + exstingVolumeOfVm = diskVolume; + break; + } + } } + } + + HypervisorType rootDiskHyperType = vm.getHypervisorType(); + HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId()); + + VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach; + + //don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet + StoragePoolVO destPrimaryStorage = null; + if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) { + destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId()); + } + + if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Uploaded)) { try { - return orchestrateAttachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); - } finally { - if (VmJobEnabled.value()) - _workJobDao.expunge(placeHolder.getId()); + newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage); + } catch (NoTransitionException e) { + s_logger.debug("Failed to create volume on primary storage", e); + throw new CloudRuntimeException("Failed to create volume on primary storage", e); } + } - } else { - Outcome outcome = attachVolumeToVmThroughJobQueue(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); + // reload the volume from db + newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId()); + boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage); - Volume vol = null; - try { - outcome.get(); - } catch (InterruptedException e) { - throw new RuntimeException("Operation is interrupted", e); - } catch (java.util.concurrent.ExecutionException e) { - throw new RuntimeException("Execution excetion", e); + if (moveVolumeNeeded) { + PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)newVolumeOnPrimaryStorage.getDataStore(); + if (primaryStore.isLocal()) { + throw new CloudRuntimeException("Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() + + " as migration of local data volume is not allowed"); } + StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId()); - Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob()); - if (jobResult != null) { - if (jobResult instanceof ConcurrentOperationException) - throw (ConcurrentOperationException)jobResult; - else if (jobResult instanceof Throwable) - throw new RuntimeException("Unexpected exception", (Throwable)jobResult); - else if (jobResult instanceof Long) { - vol = _volsDao.findById((Long) jobResult); - } + try { + newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), + vmRootVolumePool.getClusterId(), volumeToAttachHyperType); + } catch (ConcurrentOperationException e) { + s_logger.debug("move volume failed", e); + throw new CloudRuntimeException("move volume failed", e); + } catch (StorageUnavailableException e) { + s_logger.debug("move volume failed", e); + throw new CloudRuntimeException("move volume failed", e); } - return vol; } - } - - private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { - return attachVolumeToVM(vmId, volumeId, deviceId); + VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId()); + newVol = sendAttachVolumeCommand(vm, newVol, deviceId); + return newVol; } @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true) @@ -1275,25 +1302,6 @@ public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state"); } - VolumeVO exstingVolumeOfVm = null; - List rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT); - if (rootVolumesOfVm.size() > 1) { - throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state."); - } else { - if (!rootVolumesOfVm.isEmpty()) { - exstingVolumeOfVm = rootVolumesOfVm.get(0); - } else { - // locate data volume of the vm - List diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK); - for (VolumeVO diskVolume : diskVolumesOfVm) { - if (diskVolume.getState() != Volume.State.Allocated) { - exstingVolumeOfVm = diskVolume; - break; - } - } - } - } - HypervisorType rootDiskHyperType = vm.getHypervisorType(); HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId()); @@ -1307,62 +1315,57 @@ public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { } } - VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach; + AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); - //don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet - StoragePoolVO destPrimaryStorage = null; - if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) { - destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId()); - } + if (asyncExecutionContext != null) { + AsyncJob job = asyncExecutionContext.getJob(); - if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Uploaded)) { - try { - newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage); - } catch (NoTransitionException e) { - s_logger.debug("Failed to create volume on primary storage", e); - throw new CloudRuntimeException("Failed to create volume on primary storage", e); + if (s_logger.isInfoEnabled()) { + s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status"); } + + _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } - // reload the volume from db - newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId()); - boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage); + AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); + if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { + // avoid re-entrance - if (moveVolumeNeeded) { - PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)newVolumeOnPrimaryStorage.getDataStore(); - if (primaryStore.isLocal()) { - throw new CloudRuntimeException("Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() - + " as migration of local data volume is not allowed"); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmId); } - StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId()); - try { - newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), - vmRootVolumePool.getClusterId(), volumeToAttachHyperType); - } catch (ConcurrentOperationException e) { - s_logger.debug("move volume failed", e); - throw new CloudRuntimeException("move volume failed", e); - } catch (StorageUnavailableException e) { - s_logger.debug("move volume failed", e); - throw new CloudRuntimeException("move volume failed", e); + return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); } - } - AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); - - if (asyncExecutionContext != null) { - AsyncJob job = asyncExecutionContext.getJob(); + } else { + Outcome outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId); - if (s_logger.isInfoEnabled()) { - s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status"); + Volume vol = null; + try { + outcome.get(); + } catch (InterruptedException e) { + throw new RuntimeException("Operation is interrupted", e); + } catch (java.util.concurrent.ExecutionException e) { + throw new RuntimeException("Execution excetion", e); } - _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); + Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob()); + if (jobResult != null) { + if (jobResult instanceof ConcurrentOperationException) + throw (ConcurrentOperationException)jobResult; + else if (jobResult instanceof Throwable) + throw new RuntimeException("Unexpected exception", (Throwable)jobResult); + else if (jobResult instanceof Long) { + vol = _volsDao.findById((Long)jobResult); + } + } + return vol; } - - VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId()); - newVol = sendAttachVolumeCommand(vm, newVol, deviceId); - return newVol; } @Override From 70e68be4f32538b7965e916cce1f51334fadbbd5 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 22 Jul 2014 13:10:26 +0200 Subject: [PATCH 139/819] Fix string encoding problem reported by coverity --- .../resource/virtualnetwork/ConfigHelper.java | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java index d94c1c660b..a065a0228a 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/ConfigHelper.java @@ -19,6 +19,16 @@ package com.cloud.agent.resource.virtualnetwork; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; + +import com.google.gson.Gson; + import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.routing.CreateIpAliasCommand; @@ -53,13 +63,6 @@ import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.rules.FirewallRule; import com.cloud.utils.net.NetUtils; -import com.google.gson.Gson; -import org.apache.commons.codec.binary.Base64; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; public class ConfigHelper { @@ -307,10 +310,14 @@ private static List generateConfig(VmDataCommand cmd) { data.put(cmd.getVmIpAddress(), cmd.getVmData()); String json = new Gson().toJson(data); + String encoded; + try { + encoded = Base64.encodeBase64String(json.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException("Unable retrieve UTF-8 encoded data from vmdata"); + } - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; + String args = "-d " + encoded; cfg.add(new ScriptConfigItem(VRScripts.VMDATA, args)); return cfg; @@ -367,12 +374,16 @@ private static List generateConfig(CreateIpAliasCommand cmd) { LinkedList cfg = new LinkedList<>(); List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; + StringBuilder args = new StringBuilder(); for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - - cfg.add(new ScriptConfigItem(VRScripts.IPALIAS_CREATE, args)); + args.append(ipaliasto.getAlias_count()); + args.append(':'); + args.append(ipaliasto.getRouterip()); + args.append(':'); + args.append(ipaliasto.getNetmask()); + args.append('-'); + } + cfg.add(new ScriptConfigItem(VRScripts.IPALIAS_CREATE, args.toString())); return cfg; } From 28333664159dd618682b0b07352782af641d295d Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 22 Jul 2014 13:11:11 +0200 Subject: [PATCH 140/819] Remove dead code --- .../src/com/cloud/network/element/VirtualRouterElement.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index fd15ee35ed..e4660b7969 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -72,9 +72,9 @@ import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; -import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; @@ -89,8 +89,8 @@ import com.cloud.user.AccountManager; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; -import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.crypt.DBEncryptionUtil; +import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; @@ -335,8 +335,6 @@ public static boolean validateHAProxyLBRule(LoadBalancingRule rule) { for (Pair paramKV : paramsList) { String key = paramKV.first(); String value = paramKV.second(); - if ("cookie-name".equalsIgnoreCase(key)) { - } if ("length".equalsIgnoreCase(key)) length = value; if ("holdtime".equalsIgnoreCase(key)) From 4bf321bd034f179c1ac9dda111fbb5e1034fadd0 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 22 Jul 2014 13:11:46 +0200 Subject: [PATCH 141/819] Fix equality check using != on objects Cleanup in the code, removing dead code --- .../cloud/storage/VolumeApiServiceImpl.java | 217 +++++++++--------- 1 file changed, 106 insertions(+), 111 deletions(-) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index ac2a88123d..54ae965d49 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -312,10 +312,10 @@ private boolean validateVolume(Account caller, long ownerId, Long zoneId, String .toLowerCase().endsWith("vhd.gz"))) || (format.equalsIgnoreCase("vhdx") && (!url.toLowerCase().endsWith(".vhdx") && !url.toLowerCase().endsWith("vhdx.zip") && !url.toLowerCase().endsWith("vhdx.bz2") && !url .toLowerCase().endsWith("vhdx.gz"))) - || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") - && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz"))) - || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url - .toLowerCase().endsWith("ova.gz"))) || (format.equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith(".img") && !url.toLowerCase().endsWith("raw")))) { + || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") + && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz"))) + || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url + .toLowerCase().endsWith("ova.gz"))) || (format.equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith(".img") && !url.toLowerCase().endsWith("raw")))) { throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase()); } UriUtils.validateUrl(url); @@ -370,21 +370,21 @@ public VolumeVO doInTransaction(TransactionStatus status) { } else { volume.setDiskOfferingId(diskOfferingId); } - // volume.setSize(size); - volume.setInstanceId(null); - volume.setUpdated(new Date()); - volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); - volume.setFormat(ImageFormat.valueOf(format)); - volume = _volsDao.persist(volume); - CallContext.current().setEventDetails("Volume Id: " + volume.getId()); - - // Increment resource count during allocation; if actual creation fails, - // decrement it - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); + // volume.setSize(size); + volume.setInstanceId(null); + volume.setUpdated(new Date()); + volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); + volume.setFormat(ImageFormat.valueOf(format)); + volume = _volsDao.persist(volume); + CallContext.current().setEventDetails("Volume Id: " + volume.getId()); - return volume; - } + // Increment resource count during allocation; if actual creation fails, + // decrement it + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); + + return volume; + } }); } @@ -530,7 +530,7 @@ public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationExcept diskOffering = _diskOfferingDao.findById(diskOfferingId); if (zoneId == null) { // if zoneId is not provided, we default to create volume in the same zone as the snapshot zone. - zoneId = snapshotCheck.getDataCenterId(); + zoneId = snapshotCheck.getDataCenterId(); } size = snapshotCheck.getSize(); // ; disk offering is used for tags // purposes @@ -695,7 +695,7 @@ public VolumeVO createVolume(CreateVolumeCmd cmd) { protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Long vmId) throws StorageUnavailableException { VolumeInfo createdVolume = null; SnapshotVO snapshot = _snapshotDao.findById(snapshotId); - long snapshotVolId = snapshot.getVolumeId(); + snapshot.getVolumeId(); UserVmVO vm = null; if (vmId != null) { @@ -738,13 +738,13 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId()); if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer && - hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any && hypervisorType != HypervisorType.None) { + hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any && hypervisorType != HypervisorType.None) { throw new InvalidParameterValueException("CloudStack currently only supports volumes marked as the KVM, VMware, or XenServer hypervisor type for resize."); } if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) { throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. Volume " + - volume.getUuid() + " is in state " + volume.getState() + "."); + volume.getUuid() + " is in state " + volume.getState() + "."); } // if we are to use the existing disk offering @@ -830,7 +830,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep newSize = newDiskOffering.getDiskSize(); } - if (volume.getSize() != newSize && !volume.getVolumeType().equals(Volume.Type.DATADISK)) { + if (!volume.getSize().equals(newSize) && !volume.getVolumeType().equals(Volume.Type.DATADISK)) { throw new InvalidParameterValueException("Only data volumes can be resized via a new disk offering."); } @@ -909,7 +909,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep try { return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, - newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); + newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); } finally { if (VmJobEnabled.value()) { _workJobDao.expunge(placeHolder.getId()); @@ -1741,7 +1741,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) { placeHolder = createPlaceHolderWork(vm.getId()); } try { - return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume); + return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume); } finally { if ((VmJobEnabled.value())&&(placeHolder != null)) _workJobDao.expunge(placeHolder.getId()); @@ -1790,7 +1790,7 @@ private Volume orchestrateMigrateVolume(long volumeId, long destPoolId, boolean try { newVol = _volumeMgr.migrateVolume(vol, destPool); } catch (StorageUnavailableException e) { - s_logger.debug("Failed to migrate volume", e); + s_logger.debug("Failed to migrate volume", e); } } return newVol; @@ -1843,7 +1843,7 @@ public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Acco placeHolder = createPlaceHolderWork(vm.getId()); } try { - return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm); + return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm); } finally { if (VmJobEnabled.value()) _workJobDao.expunge(placeHolder.getId()); @@ -1873,10 +1873,10 @@ else if (jobResult instanceof Throwable) return _snapshotDao.findById(snapshotId); } } else { - CreateSnapshotPayload payload = new CreateSnapshotPayload(); - payload.setSnapshotId(snapshotId); - payload.setSnapshotPolicyId(policyId); - payload.setAccount(account); + CreateSnapshotPayload payload = new CreateSnapshotPayload(); + payload.setSnapshotId(snapshotId); + payload.setSnapshotPolicyId(policyId); + payload.setAccount(account); payload.setQuiescevm(quiescevm); volume.addPayload(payload); return volService.takeSnapshot(volume); @@ -1996,11 +1996,8 @@ public String extractVolume(ExtractVolumeCmd cmd) { } } - Upload.Mode extractMode; if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) { throw new InvalidParameterValueException("Please specify a valid extract Mode "); - } else { - extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; } // Check if the url already exists @@ -2009,14 +2006,12 @@ public String extractVolume(ExtractVolumeCmd cmd) { return volumeStoreRef.getExtractUrl(); } - // Clean up code to remove all those previous uploadVO and uploadMonitor code. Previous code is trying to fake an async operation purely in - // db table with uploadVO and async_job entry, but internal implementation is actually synchronous. - StoragePool srcPool = (StoragePool)dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); + dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); ImageStoreEntity secStore = (ImageStoreEntity)dataStoreMgr.getImageStore(zoneId); - String secondaryStorageURL = secStore.getUri(); + secStore.getUri(); String value = _configDao.getValue(Config.CopyVolumeWait.toString()); - int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); // Copy volume from primary to secondary storage VolumeInfo srcVol = volFactory.getVolume(volume.getId()); AsyncCallFuture cvAnswer = volService.copyVolume(srcVol, secStore); @@ -2100,7 +2095,7 @@ private boolean needMoveVolume(VolumeVO existingVolume, VolumeInfo newVolume) { if (storeForNewStoreScope.getScopeType() == ScopeType.CLUSTER) { Long vmClusterId = null; if (storeForExistingStoreScope.getScopeType() == ScopeType.HOST) { - HostScope hs = (HostScope)storeForExistingStoreScope; + HostScope hs = (HostScope)storeForExistingStoreScope; vmClusterId = hs.getClusterId(); } else if (storeForExistingStoreScope.getScopeType() == ScopeType.ZONE) { Long hostId = _vmInstanceDao.findById(existingVolume.getInstanceId()).getHostId(); @@ -2171,8 +2166,8 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L if (sendCommand) { if (host.getHypervisorType() == HypervisorType.KVM && - volumeToAttachStoragePool.isManaged() && - volumeToAttach.getPath() == null) { + volumeToAttachStoragePool.isManaged() && + volumeToAttach.getPath() == null) { volumeToAttach.setPath(volumeToAttach.get_iScsiName()); _volsDao.update(volumeToAttach.getId(), volumeToAttach); @@ -2380,29 +2375,29 @@ public Object[] doInTransaction(TransactionStatus status) { _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE); try { - workJob = new VmWorkJobVO(context.getContextId()); + workJob = new VmWorkJobVO(context.getContextId()); - workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); - workJob.setCmd(VmWorkAttachVolume.class.getName()); + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); + workJob.setCmd(VmWorkAttachVolume.class.getName()); - workJob.setAccountId(callingAccount.getId()); - workJob.setUserId(callingUser.getId()); - workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(VirtualMachine.Type.Instance); - workJob.setVmInstanceId(vm.getId()); + workJob.setAccountId(callingAccount.getId()); + workJob.setUserId(callingUser.getId()); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobId()); - // save work context info (there are some duplications) + // save work context info (there are some duplications) VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, deviceId); - workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); + workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); - _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); + _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); - AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId()); - s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult()); + AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId()); + s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult()); - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, new Long(workJob.getId())}; } finally { _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId())); } @@ -2431,26 +2426,26 @@ public Object[] doInTransaction(TransactionStatus status) { _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE); try { - workJob = new VmWorkJobVO(context.getContextId()); + workJob = new VmWorkJobVO(context.getContextId()); - workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); - workJob.setCmd(VmWorkDetachVolume.class.getName()); + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); + workJob.setCmd(VmWorkDetachVolume.class.getName()); - workJob.setAccountId(callingAccount.getId()); - workJob.setUserId(callingUser.getId()); - workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(VirtualMachine.Type.Instance); - workJob.setVmInstanceId(vm.getId()); + workJob.setAccountId(callingAccount.getId()); + workJob.setUserId(callingUser.getId()); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobId()); - // save work context info (there are some duplications) + // save work context info (there are some duplications) VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId); - workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); + workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); - _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); + _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, new Long(workJob.getId())}; } finally { _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId())); } @@ -2481,26 +2476,26 @@ public Object[] doInTransaction(TransactionStatus status) { _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE); try { - workJob = new VmWorkJobVO(context.getContextId()); + workJob = new VmWorkJobVO(context.getContextId()); - workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); - workJob.setCmd(VmWorkResizeVolume.class.getName()); + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); + workJob.setCmd(VmWorkResizeVolume.class.getName()); - workJob.setAccountId(callingAccount.getId()); - workJob.setUserId(callingUser.getId()); - workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(VirtualMachine.Type.Instance); - workJob.setVmInstanceId(vm.getId()); + workJob.setAccountId(callingAccount.getId()); + workJob.setUserId(callingUser.getId()); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobId()); - // save work context info (there are some duplications) - VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), - VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newMinIops, newMaxIops, newServiceOfferingId, shrinkOk); - workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); + // save work context info (there are some duplications) + VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), + VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newMinIops, newMaxIops, newServiceOfferingId, shrinkOk); + workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); - _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); + _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, new Long(workJob.getId())}; } finally { _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId())); } @@ -2530,26 +2525,26 @@ public Object[] doInTransaction(TransactionStatus status) { _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE); try { - workJob = new VmWorkJobVO(context.getContextId()); + workJob = new VmWorkJobVO(context.getContextId()); - workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); - workJob.setCmd(VmWorkMigrateVolume.class.getName()); + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); + workJob.setCmd(VmWorkMigrateVolume.class.getName()); - workJob.setAccountId(callingAccount.getId()); - workJob.setUserId(callingUser.getId()); - workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(VirtualMachine.Type.Instance); - workJob.setVmInstanceId(vm.getId()); + workJob.setAccountId(callingAccount.getId()); + workJob.setUserId(callingUser.getId()); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobId()); - // save work context info (there are some duplications) - VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), - VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, destPoolId, liveMigrate); - workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); + // save work context info (there are some duplications) + VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), + VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, destPoolId, liveMigrate); + workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); - _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); + _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, new Long(workJob.getId())}; } finally { _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId())); } @@ -2579,27 +2574,27 @@ public Object[] doInTransaction(TransactionStatus status) { _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE); try { - workJob = new VmWorkJobVO(context.getContextId()); + workJob = new VmWorkJobVO(context.getContextId()); - workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); - workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName()); + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER); + workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName()); - workJob.setAccountId(callingAccount.getId()); - workJob.setUserId(callingUser.getId()); - workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(VirtualMachine.Type.Instance); - workJob.setVmInstanceId(vm.getId()); + workJob.setAccountId(callingAccount.getId()); + workJob.setUserId(callingUser.getId()); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobId()); - // save work context info (there are some duplications) - VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot( - callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(), - VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm); - workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); + // save work context info (there are some duplications) + VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot( + callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(), + VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm); + workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo)); - _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); + _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, new Long(workJob.getId())}; } finally { _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId())); } From 7d3f381d9476fec5dc7ba1cada8294bcb2df0ffa Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Tue, 22 Jul 2014 17:50:16 +0530 Subject: [PATCH 142/819] Set mapped device path while detaching rbd disk --- .../kvm/resource/LibvirtDomainXMLParser.java | 4 +++- .../hypervisor/kvm/storage/KVMPhysicalDisk.java | 5 +++++ .../hypervisor/kvm/storage/KVMStorageProcessor.java | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index fabe9a881d..a0a4ac4d62 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -108,7 +108,9 @@ public boolean parseDomainXML(String domXML) { def.defBlockBasedDisk(diskDev, diskLabel, DiskDef.diskBus.valueOf(bus.toUpperCase())); } - def.setCacheMode(DiskDef.diskCacheMode.valueOf(diskCacheMode.toUpperCase())); + if (diskCacheMode != null) { + def.setCacheMode(DiskDef.diskCacheMode.valueOf(diskCacheMode.toUpperCase())); + } } NodeList iotune = disk.getElementsByTagName("iotune"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java index 669bd0bad3..c344e8ce4e 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java @@ -91,4 +91,9 @@ public String getPath() { public KVMStoragePool getPool() { return this.pool; } + + public void setPath(String path) { + this.path = path; + } + } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 9b1c9debc7..5deb636955 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -941,6 +941,18 @@ protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, S parser.parseDomainXML(xml); disks = parser.getDisks(); + if (attachingPool.getType() == StoragePoolType.RBD) { + if (resource.getHypervisorType() == Hypervisor.HypervisorType.LXC) { + String[] splitPoolImage = attachingDisk.getPath().split("/"); + //ToDo: rbd showmapped supports json and xml output. Use json/xml to get device + String device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+" "+splitPoolImage[1]+"\" | cut -d \" \" -f10"); + if (device != null) { + s_logger.debug("RBD device on host is: "+device); + attachingDisk.setPath(device); + } + } + } + for (DiskDef disk : disks) { String file = disk.getDiskPath(); if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) { From 4523490d44160b054de9e943f72db1d0ce06054a Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Mon, 21 Jul 2014 20:49:03 +0530 Subject: [PATCH 143/819] Fixed Coverity Issues reported Signed-off-by: Santhosh Edukulla --- .../api/command/user/vm/DeployVMCmd.java | 4 +- .../storage/dao/VMTemplatePoolDaoImpl.java | 67 ++++------- .../cloud/upgrade/dao/Upgrade440to450.java | 5 +- .../endpoint/DefaultEndPointSelector.java | 28 ++--- .../storage/volume/VolumeServiceImpl.java | 5 +- .../kvm/resource/BridgeVifDriver.java | 24 ++-- .../src/com/cloud/api/ApiResponseHelper.java | 76 +++++++------ .../com/cloud/api/doc/ApiXmlDocWriter.java | 25 ++--- .../cloud/resource/ResourceManagerImpl.java | 21 ++-- .../cloud/server/ConfigurationServerImpl.java | 6 +- utils/src/com/cloud/utils/nio/NioClient.java | 104 +++++++++--------- 11 files changed, 172 insertions(+), 193 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 1beb5957e5..14b703c0c2 100755 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -225,8 +225,8 @@ public Map getDetails() { Iterator iter = parameterCollection.iterator(); while (iter.hasNext()) { HashMap value = (HashMap)iter.next(); - for (String key : value.keySet()) { - customparameterMap.put(key, value.get(key)); + for (Map.Entry entry: value.entrySet()) { + customparameterMap.put(entry.getKey(),entry.getValue()); } } } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java index 12a0921be5..aacd4ffc36 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java @@ -18,7 +18,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -170,36 +169,25 @@ public List listByTemplateStatus(long templateId, long @Override public List listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; List result = new ArrayList(); - ResultSet rs = null; - try { - String sql = DOWNLOADS_STATE_DC_POD; - pstmt = txn.prepareStatement(sql); - + String sql = DOWNLOADS_STATE_DC_POD; + try(PreparedStatement pstmt = txn.prepareStatement(sql);) { pstmt.setLong(1, datacenterId); pstmt.setLong(2, podId); pstmt.setLong(3, templateId); pstmt.setString(4, downloadState.toString()); - rs = pstmt.executeQuery(); - while (rs.next()) { - // result.add(toEntityBean(rs, false)); TODO: this is buggy in - // GenericDaoBase for hand constructed queries - long id = rs.getLong(1); // ID column - result.add(findById(id)); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + // result.add(toEntityBean(rs, false)); TODO: this is buggy in + // GenericDaoBase for hand constructed queries + long id = rs.getLong(1); // ID column + result.add(findById(id)); + } + }catch (Exception e) { + s_logger.warn("Exception: ", e); } } catch (Exception e) { s_logger.warn("Exception: ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } return result; @@ -207,34 +195,23 @@ public List listByTemplateStatus(long templateId, long public List listByHostTemplate(long hostId, long templateId) { TransactionLegacy txn = TransactionLegacy.currentTxn(); - PreparedStatement pstmt = null; List result = new ArrayList(); - ResultSet rs = null; - try { - String sql = HOST_TEMPLATE_SEARCH; - pstmt = txn.prepareStatement(sql); - + String sql = HOST_TEMPLATE_SEARCH; + try(PreparedStatement pstmt = txn.prepareStatement(sql);) { pstmt.setLong(1, hostId); pstmt.setLong(2, templateId); - rs = pstmt.executeQuery(); - while (rs.next()) { - // result.add(toEntityBean(rs, false)); TODO: this is buggy in - // GenericDaoBase for hand constructed queries - long id = rs.getLong(1); // ID column - result.add(findById(id)); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + // result.add(toEntityBean(rs, false)); TODO: this is buggy in + // GenericDaoBase for hand constructed queries + long id = rs.getLong(1); // ID column + result.add(findById(id)); + } + }catch (Exception e) { + s_logger.warn("Exception: ", e); } } catch (Exception e) { s_logger.warn("Exception: ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } return result; diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java index caf3b422d2..aad5162e7d 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to450.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.log4j.Logger; @@ -80,8 +81,8 @@ private void dropInvalidKeyFromStoragePoolTable(Connection conn) { uniqueKeys.put("storage_pool", keys); s_logger.debug("Droping id_2 key from storage_pool table"); - for (String tableName : uniqueKeys.keySet()) { - DbUpgradeUtils.dropKeysIfExist(conn, tableName, uniqueKeys.get(tableName), false); + for (Map.Entry> entry: uniqueKeys.entrySet()) { + DbUpgradeUtils.dropKeysIfExist(conn,entry.getKey(), entry.getValue(), false); } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index f06b43eecc..0a867f6291 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -115,33 +115,21 @@ protected EndPoint findEndPointInScope(Scope scope, String sqlBase, Long poolId) // TODO: order by rand() is slow if there are lot of hosts sbuilder.append(" ORDER by rand() limit 1"); String sql = sbuilder.toString(); - PreparedStatement pstmt = null; - ResultSet rs = null; HostVO host = null; TransactionLegacy txn = TransactionLegacy.currentTxn(); - - try { - pstmt = txn.prepareStatement(sql); + try(PreparedStatement pstmt = txn.prepareStatement(sql);) { pstmt.setLong(1, poolId); - rs = pstmt.executeQuery(); - while (rs.next()) { - long id = rs.getLong(1); - host = hostDao.findById(id); + try(ResultSet rs = pstmt.executeQuery();) { + while (rs.next()) { + long id = rs.getLong(1); + host = hostDao.findById(id); + } + }catch (SQLException e) { + s_logger.warn("can't find endpoint", e); } } catch (SQLException e) { s_logger.warn("can't find endpoint", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } } - if (host == null) { return null; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 3fc43ea2d8..821c9396e3 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -1464,8 +1464,9 @@ public void handleVolumeSync(DataStore store) { } // Delete volumes which are not present on DB. - for (Long uniqueName : volumeInfos.keySet()) { - TemplateProp tInfo = volumeInfos.get(uniqueName); + for (Map.Entry entry : volumeInfos.entrySet()) { + Long uniqueName = entry.getKey(); + TemplateProp tInfo = entry.getValue(); //we cannot directly call expungeVolumeAsync here to // reuse delete logic since in this case, our db does not have diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index e684b8de5f..3b034bb640 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -104,16 +104,16 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0; - if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vNetId.equalsIgnoreCase("untagged") || - nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) { - if (trafficLabel != null && !trafficLabel.isEmpty()) { - s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel); - String brName = createVnetBr(vNetId, trafficLabel, protocol); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); - } else { - String brName = createVnetBr(vNetId, "private", protocol); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); - } + if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) || + (nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) { + if (trafficLabel != null && !trafficLabel.isEmpty()) { + s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel); + String brName = createVnetBr(vNetId, trafficLabel, protocol); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); + } else { + String brName = createVnetBr(vNetId, "private", protocol); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); + } } else { intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); } @@ -123,8 +123,8 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter)); } else if (nic.getType() == Networks.TrafficType.Public) { Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0; - if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vNetId.equalsIgnoreCase("untagged") || - nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) { + if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) || + (nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) { if (trafficLabel != null && !trafficLabel.isEmpty()) { s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel); String brName = createVnetBr(vNetId, trafficLabel, protocol); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 013da0b70b..70ed47da49 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1026,20 +1026,24 @@ public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); - response.setPublicIpAddressId(ip.getUuid()); - response.setPublicIpAddress(ip.getAddress().addr()); - if (ip != null && fwRule.getDestinationIpAddress() != null) { - response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString()); - UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId()); - if (vm != null) { - response.setVirtualMachineId(vm.getUuid()); - response.setVirtualMachineName(vm.getHostName()); + if (ip != null) + { + response.setPublicIpAddressId(ip.getUuid()); + response.setPublicIpAddress(ip.getAddress().addr()); + if (fwRule.getDestinationIpAddress() != null) + { + response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString()); + UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId()); + if (vm != null) { + response.setVirtualMachineId(vm.getUuid()); + response.setVirtualMachineName(vm.getHostName()); - if (vm.getDisplayName() != null) { - response.setVirtualMachineDisplayName(vm.getDisplayName()); - } else { - response.setVirtualMachineDisplayName(vm.getHostName()); + if (vm.getDisplayName() != null) { + response.setVirtualMachineDisplayName(vm.getDisplayName()); + } else { + response.setVirtualMachineDisplayName(vm.getHostName()); + } } } } @@ -1071,18 +1075,20 @@ public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwR response.setProtocol(fwRule.getProtocol()); IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); - response.setPublicIpAddressId(ip.getId()); - response.setPublicIpAddress(ip.getAddress().addr()); - - if (ip != null && fwRule.getDestIpAddress() != null) { - UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId()); - if (vm != null) {// vm might be destroyed - response.setVirtualMachineId(vm.getUuid()); - response.setVirtualMachineName(vm.getHostName()); - if (vm.getDisplayName() != null) { - response.setVirtualMachineDisplayName(vm.getDisplayName()); - } else { - response.setVirtualMachineDisplayName(vm.getHostName()); + + if (ip != null) { + response.setPublicIpAddressId(ip.getId()); + response.setPublicIpAddress(ip.getAddress().addr()); + if (fwRule.getDestIpAddress() != null) { + UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId()); + if (vm != null) {// vm might be destroyed + response.setVirtualMachineId(vm.getUuid()); + response.setVirtualMachineName(vm.getHostName()); + if (vm.getDisplayName() != null) { + response.setVirtualMachineDisplayName(vm.getDisplayName()); + } else { + response.setVirtualMachineDisplayName(vm.getHostName()); + } } } } @@ -1701,7 +1707,9 @@ public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering off Map> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId()); List serviceResponses = new ArrayList(); - for (Service service : serviceProviderMap.keySet()) { + for (Map.Entry> entry : serviceProviderMap.entrySet()) { + Service service = entry.getKey(); + Set srvc_providers = entry.getValue(); ServiceResponse svcRsp = new ServiceResponse(); // skip gateway service if (service == Service.Gateway) { @@ -1709,7 +1717,7 @@ public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering off } svcRsp.setName(service.getName()); List providers = new ArrayList(); - for (Provider provider : serviceProviderMap.get(service)) { + for (Provider provider : srvc_providers) { if (provider != null) { ProviderResponse providerRsp = new ProviderResponse(); providerRsp.setName(provider.getName()); @@ -1956,8 +1964,9 @@ public NetworkResponse createNetworkResponse(ResponseView view, Network network) Domain domain = ApiDBUtils.findDomainById(dedicatedDomainId); if (domain != null) { response.setDomainId(domain.getUuid()); + response.setDomainName(domain.getName()); } - response.setDomainName(domain.getName()); + } response.setSpecifyIpRanges(network.getSpecifyIpRanges()); @@ -2563,7 +2572,10 @@ public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); List serviceResponses = new ArrayList(); - for (Service service : serviceProviderMap.keySet()) { + for (Map.Entry> entry : serviceProviderMap.entrySet()) { + Service service = entry.getKey(); + Set srvc_providers = entry.getValue(); + ServiceResponse svcRsp = new ServiceResponse(); // skip gateway service if (service == Service.Gateway) { @@ -2571,7 +2583,7 @@ public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { } svcRsp.setName(service.getName()); List providers = new ArrayList(); - for (Provider provider : serviceProviderMap.get(service)) { + for (Provider provider : srvc_providers) { if (provider != null) { ProviderResponse providerRsp = new ProviderResponse(); providerRsp.setName(provider.getName()); @@ -3114,7 +3126,6 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) { } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) { //Template/ISO ID VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(tmpl.getUuid()); if (tmpl != null) { usageRecResponse.setUsageId(tmpl.getUuid()); } @@ -3389,10 +3400,11 @@ public ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(Applic //set Lb instances information List instanceResponses = new ArrayList(); - for (Ip ip : lbInstances.keySet()) { + for (Map.Entry entry : lbInstances.entrySet()) { + Ip ip = entry.getKey(); + UserVm vm = entry.getValue(); ApplicationLoadBalancerInstanceResponse instanceResponse = new ApplicationLoadBalancerInstanceResponse(); instanceResponse.setIpAddress(ip.addr()); - UserVm vm = lbInstances.get(ip); instanceResponse.setId(vm.getUuid()); instanceResponse.setName(vm.getInstanceName()); instanceResponse.setObjectName("loadbalancerinstance"); diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index fe07056eb6..682418509f 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -144,10 +144,8 @@ public static void main(String[] args) { } for (String fileName : fileNames) { - try { - FileInputStream in = new FileInputStream(fileName); + try(FileInputStream in = new FileInputStream(fileName);) { preProcessedCommands.load(in); - in.close(); } catch (FileNotFoundException ex) { System.out.println("Can't find file " + fileName); System.exit(2); @@ -595,14 +593,17 @@ static void addDir(File dirObj, ZipOutputStream out) throws IOException { addDir(files[i], out); continue; } - FileInputStream in = new FileInputStream(files[i].getPath()); - out.putNextEntry(new ZipEntry(files[i].getPath().substring(pathToDir.length()))); - int len; - while ((len = in.read(tmpBuf)) > 0) { - out.write(tmpBuf, 0, len); + try(FileInputStream in = new FileInputStream(files[i].getPath());) { + out.putNextEntry(new ZipEntry(files[i].getPath().substring(pathToDir.length()))); + int len; + while ((len = in.read(tmpBuf)) > 0) { + out.write(tmpBuf, 0, len); + } + out.closeEntry(); + }catch(IOException ex) + { + s_logger.error("addDir:Exception:"+ ex.getMessage(),ex); } - out.closeEntry(); - in.close(); } } @@ -619,8 +620,7 @@ private static void deleteDir(File dir) { private static void writeAlertTypes(String dirName) { XStream xs = new XStream(); xs.alias("alert", Alert.class); - try { - ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/alert_types.xml"), "alerts"); + try(ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/alert_types.xml"), "alerts");) { for (Field f : AlertManager.class.getFields()) { if (f.getClass().isAssignableFrom(Number.class)) { String name = f.getName().substring(11); @@ -628,7 +628,6 @@ private static void writeAlertTypes(String dirName) { out.writeObject(alert); } } - out.close(); } catch (IOException e) { s_logger.error("Failed to create output stream to write an alert types ", e); } catch (IllegalAccessException e) { diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 68c92864d2..6f089af957 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -136,7 +136,6 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.User; import com.cloud.utils.StringUtils; import com.cloud.utils.UriUtils; import com.cloud.utils.component.Manager; @@ -323,29 +322,29 @@ protected void processResourceEvent(Integer event, Object... params) { String eventName; for (ResourceListener l : lst) { - if (event == ResourceListener.EVENT_DISCOVER_BEFORE) { + if (event.equals(ResourceListener.EVENT_DISCOVER_BEFORE)) { l.processDiscoverEventBefore((Long)params[0], (Long)params[1], (Long)params[2], (URI)params[3], (String)params[4], (String)params[5], (List)params[6]); eventName = "EVENT_DISCOVER_BEFORE"; - } else if (event == ResourceListener.EVENT_DISCOVER_AFTER) { + } else if (event.equals(ResourceListener.EVENT_DISCOVER_AFTER)) { l.processDiscoverEventAfter((Map>)params[0]); eventName = "EVENT_DISCOVER_AFTER"; - } else if (event == ResourceListener.EVENT_DELETE_HOST_BEFORE) { + } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_BEFORE)) { l.processDeleteHostEventBefore((HostVO)params[0]); eventName = "EVENT_DELETE_HOST_BEFORE"; - } else if (event == ResourceListener.EVENT_DELETE_HOST_AFTER) { + } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_AFTER)) { l.processDeletHostEventAfter((HostVO)params[0]); eventName = "EVENT_DELETE_HOST_AFTER"; - } else if (event == ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) { + } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE)) { l.processCancelMaintenaceEventBefore((Long)params[0]); eventName = "EVENT_CANCEL_MAINTENANCE_BEFORE"; - } else if (event == ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) { + } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER)) { l.processCancelMaintenaceEventAfter((Long)params[0]); eventName = "EVENT_CANCEL_MAINTENANCE_AFTER"; - } else if (event == ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) { + } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE)) { l.processPrepareMaintenaceEventBefore((Long)params[0]); eventName = "EVENT_PREPARE_MAINTENANCE_BEFORE"; - } else if (event == ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) { + } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER)) { l.processPrepareMaintenaceEventAfter((Long)params[0]); eventName = "EVENT_PREPARE_MAINTENANCE_AFTER"; } else { @@ -798,7 +797,7 @@ public Host getHost(long hostId) { @DB protected boolean doDeleteHost(final long hostId, boolean isForced, final boolean isForceDeleteStorage) { - User caller = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); + _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); // Verify that host exists final HostVO host = _hostDao.findById(hostId); if (host == null) { @@ -1463,7 +1462,7 @@ private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, boolean Map.Entry item = it.next(); ResourceStateAdapter adapter = item.getValue(); - String msg = new String("Dispatching resource state event " + event + " to " + item.getKey()); + String msg = "Dispatching resource state event " + event + " to " + item.getKey(); s_logger.debug(msg); if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) { diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 7c3b5a52e8..6e72d0887d 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -1221,9 +1221,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) { defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); - for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); + for (Map.Entry entry : defaultVpcNetworkOfferingProviders.entrySet()) { + NetworkOfferingServiceMapVO offService = + new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), entry.getKey(), entry.getValue()); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } diff --git a/utils/src/com/cloud/utils/nio/NioClient.java b/utils/src/com/cloud/utils/nio/NioClient.java index 34d03c2635..db17b7a36f 100755 --- a/utils/src/com/cloud/utils/nio/NioClient.java +++ b/utils/src/com/cloud/utils/nio/NioClient.java @@ -48,61 +48,63 @@ public void setBindAddress(String ipAddress) { @Override protected void init() throws IOException { _selector = Selector.open(); - SocketChannel sch = null; InetSocketAddress addr = null; - - try { - sch = SocketChannel.open(); - sch.configureBlocking(true); - s_logger.info("Connecting to " + _host + ":" + _port); - - if (_bindAddress != null) { - s_logger.info("Binding outbound interface at " + _bindAddress); - - addr = new InetSocketAddress(_bindAddress, 0); - sch.socket().bind(addr); + try(SocketChannel sch = SocketChannel.open();) { + try { + sch.configureBlocking(true); + s_logger.info("Connecting to " + _host + ":" + _port); + + if (_bindAddress != null) { + s_logger.info("Binding outbound interface at " + _bindAddress); + + addr = new InetSocketAddress(_bindAddress, 0); + sch.socket().bind(addr); + } + + addr = new InetSocketAddress(_host, _port); + sch.connect(addr); + } catch (IOException e) { + _selector.close(); + throw e; + } + SSLEngine sslEngine = null; + try { + // Begin SSL handshake in BLOCKING mode + sch.configureBlocking(true); + + SSLContext sslContext = Link.initSSLContext(true); + sslEngine = sslContext.createSSLEngine(_host, _port); + sslEngine.setUseClientMode(true); + + Link.doHandshake(sch, sslEngine, true); + s_logger.info("SSL: Handshake done"); + s_logger.info("Connected to " + _host + ":" + _port); + } catch (Exception e) { + _selector.close(); + throw new IOException("SSL: Fail to init SSL! " + e); } - addr = new InetSocketAddress(_host, _port); - sch.connect(addr); - } catch (IOException e) { - _selector.close(); - throw e; - } - - SSLEngine sslEngine = null; - try { - // Begin SSL handshake in BLOCKING mode - sch.configureBlocking(true); - - SSLContext sslContext = Link.initSSLContext(true); - sslEngine = sslContext.createSSLEngine(_host, _port); - sslEngine.setUseClientMode(true); - - Link.doHandshake(sch, sslEngine, true); - s_logger.info("SSL: Handshake done"); - s_logger.info("Connected to " + _host + ":" + _port); - } catch (Exception e) { - _selector.close(); - throw new IOException("SSL: Fail to init SSL! " + e); - } - - Task task = null; - try { - sch.configureBlocking(false); - Link link = new Link(addr, this); - link.setSSLEngine(sslEngine); - SelectionKey key = sch.register(_selector, SelectionKey.OP_READ); - link.setKey(key); - key.attach(link); - // Notice we've already connected due to the handshake, so let's get the - // remaining task done - task = _factory.create(Task.Type.CONNECT, link, null); - } catch (Exception e) { - _selector.close(); - throw new IOException("Fail to init NioClient! " + e); + Task task = null; + try { + sch.configureBlocking(false); + Link link = new Link(addr, this); + link.setSSLEngine(sslEngine); + SelectionKey key = sch.register(_selector, SelectionKey.OP_READ); + link.setKey(key); + key.attach(link); + // Notice we've already connected due to the handshake, so let's get the + // remaining task done + task = _factory.create(Task.Type.CONNECT, link, null); + } catch (Exception e) { + _selector.close(); + throw new IOException("Fail to init NioClient! " + e); + } + _executor.execute(task); + }catch(IOException ex) + { + s_logger.error("NioClient:init:Exception:"+ex.getMessage()); + throw new IOException("NioClient:init:Exception:"+ex.getMessage(),ex); } - _executor.execute(task); } @Override From 1d2124dcbf48d15d23ddbdea23a29f0ab21be6f3 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 22 Jul 2014 17:43:49 +0200 Subject: [PATCH 144/819] Fix NPE reported on IRC, provide the user an informative error message --- .../resource/VmwareStorageProcessor.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 77ee4ce06b..5b4942c10c 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -268,6 +268,9 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { Pair templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName()); VmwareContext context = hostService.getServiceContext(cmd); + if (context == null) { + return new CopyCmdAnswer("Failed to create a Vmware context, check the management server logs or the ssvm log for details"); + } try { VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); @@ -286,7 +289,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { if (managed) { morDs = prepareManagedDatastore(context, hyperHost, managedStoragePoolName, storageHost, storagePort, - chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret); + chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret); } else { morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid); @@ -303,9 +306,9 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { vmMo.unregisterVm(); String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName, - managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false); + managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false); String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, - managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false); + managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false); dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true); dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true); @@ -1294,9 +1297,9 @@ private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean Map details = disk.getDetails(); morDs = prepareManagedStorage(context, hyperHost, iScsiName, storageHost, storagePort, null, - details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET), - details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET), - volumeTO.getSize(), cmd); + details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET), + details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET), + volumeTO.getSize(), cmd); } else { morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid()); @@ -1573,7 +1576,7 @@ public Answer deleteVolume(DeleteCommand cmd) { } ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, - isManaged ? managedDatastoreName : store.getUuid()); + isManaged ? managedDatastoreName : store.getUuid()); if (morDs == null) { String msg = "Unable to find datastore based on volume mount point " + store.getUuid(); @@ -1982,7 +1985,7 @@ public ManagedObjectReference prepareManagedStorage(VmwareContext context, Vmwar String storageHost, int storagePort, String volumeName, String chapInitiatorUsername, String chapInitiatorSecret, String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception { ManagedObjectReference morDs = prepareManagedDatastore(context, hyperHost, iScsiName, storageHost, storagePort, - chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret); + chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret); DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs); From 3b32732459730bfd4848678c95c27e2eb653cc04 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 22 Jul 2014 09:47:27 -0700 Subject: [PATCH 145/819] CLOUDSTACK-7162:queryAsyncJobResult api does not return jobinstanceid. --- .../cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 72fc2b43bc..c28e87b24d 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -244,10 +244,6 @@ public List doInTransaction(TransactionStatus status) { job.setStatus(jobStatus); job.setResultCode(resultCode); - // reset attached object - job.setInstanceType(null); - job.setInstanceId(null); - if (resultObject != null) { job.setResult(resultObject); } else { From 45888e214c949d1e48d800339b366c42a7990641 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Mon, 21 Jul 2014 03:15:07 -0400 Subject: [PATCH 146/819] CLOUDSTACK-7137: Resolving cleanup issue in test_escalations_securitygroups.py --- .../test_escalations_securitygroups.py | 38 ++++--------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/test/integration/component/test_escalations_securitygroups.py b/test/integration/component/test_escalations_securitygroups.py index 8934088774..076477ed1f 100644 --- a/test/integration/component/test_escalations_securitygroups.py +++ b/test/integration/component/test_escalations_securitygroups.py @@ -17,40 +17,15 @@ #Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (createVolume, - createTemplate) -from marvin.lib.base import (Volume, - Iso, - VirtualMachine, - Template, - Snapshot, - SecurityGroup, - Account, - Zone, - Network, - NetworkOffering, - DiskOffering, - ServiceOffering, - VmSnapshot, - SnapshotPolicy, - SSHKeyPair, - Resources, - Configurations, - VpnCustomerGateway, - Hypervisor, - VpcOffering, - VPC, - NetworkACL) +from marvin.lib.base import (SecurityGroup, + Account) from marvin.lib.common import (get_zone, get_domain, - get_template, - list_os_types) + get_template) from marvin.lib.utils import (validateList, - cleanup_resources, - random_gen) -from marvin.codes import (PASS, FAIL, EMPTY_LIST) + cleanup_resources) +from marvin.codes import (PASS, EMPTY_LIST) from nose.plugins.attrib import attr -import time class TestSecurityGroups(cloudstackTestCase): @@ -245,6 +220,7 @@ def test_01_list_securitygroups_pagination(self): SecurityGroup.delete( securitygroup_created, self.userapiclient) + self.cleanup.remove(securitygroup_created) # Listing all the security groups in page 2 again list_securitygroups_page2 = SecurityGroup.list( self.userapiclient, @@ -585,4 +561,4 @@ def test_03_securitygroups_authorize_revoke_egress(self): status[2], "Security Groups Egress rule is not revoked" ) - return \ No newline at end of file + return From 981becc73585c9a789b377e18af623c325b0bc7f Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Tue, 22 Jul 2014 05:05:47 -0400 Subject: [PATCH 147/819] CLOUDSTACK-7148: Adding missing list method --- test/integration/component/test_redundant_router_cleanups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_redundant_router_cleanups.py b/test/integration/component/test_redundant_router_cleanups.py index 444fa3a66b..47e60c8bc9 100644 --- a/test/integration/component/test_redundant_router_cleanups.py +++ b/test/integration/component/test_redundant_router_cleanups.py @@ -592,7 +592,7 @@ def test_network_gc(self): self.fail("Failed to stop guest Vm: %s - %s" % (virtual_machine.name, e)) - interval = Configurations( + interval = Configurations.list( self.apiclient, name='network.gc.interval' ) From 613eb12104af5c27935091127a1a19941f96e336 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Tue, 22 Jul 2014 04:57:46 -0400 Subject: [PATCH 148/819] CLOUDSTACK-7044: Portable IP Range test case changes - reading portable ip range from test_data.py file --- .../integration/component/test_portable_ip.py | 165 ++++++------------ tools/marvin/marvin/config/test_data.py | 3 +- tools/marvin/marvin/lib/common.py | 36 ---- 3 files changed, 52 insertions(+), 152 deletions(-) diff --git a/test/integration/component/test_portable_ip.py b/test/integration/component/test_portable_ip.py index ce27dd8270..81f13592b5 100644 --- a/test/integration/component/test_portable_ip.py +++ b/test/integration/component/test_portable_ip.py @@ -37,11 +37,9 @@ get_domain, get_region, get_pod, - isIpInDesiredState, - getPortableIpRangeServices) + isIpInDesiredState) from netaddr import IPAddress from marvin.sshClient import SshClient -from marvin.codes import FAILED from nose.plugins.attrib import attr class Services: @@ -143,14 +141,7 @@ def __init__(self): "publicport": 22, "protocol": 'TCP', }, - "portableIpRange": - { - "gateway": "10.223.252.195", - "netmask": "255.255.255.192", - "startip": "10.223.252.196", - "endip": "10.223.252.197", - "vlan": "1001", - }, + "portableiprange":"", "ostype": 'CentOS 5.3 (64-bit)' } @@ -164,7 +155,7 @@ def setUpClass(cls): cls.testClient = super(TestCreatePortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -190,6 +181,7 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() + self.services["portableiprange"]["regionid"] = self.region.id self.cleanup = [] return @@ -208,17 +200,10 @@ def test_create_portable_ip_range(self): """ # 1. Create new portable ip range with root admin api # 2. Portable ip range should be created successfully - - portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id - try: #create new portable ip range new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(new_portable_ip_range) except Exception as e: @@ -232,11 +217,6 @@ def test_create_portable_ip_range_non_root_admin(self): # 1. Create new portable ip range with non root admin api client # 2. Portable ip range should not be created - portable_ip_range_services = getPortableIpRangeServices(self.config) - - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - try: self.account = Account.create( self.apiclient, @@ -250,12 +230,10 @@ def test_create_portable_ip_range_non_root_admin(self): DomainName=self.account.domain ) - portable_ip_range_services["regionid"] = self.region.id - self.debug("Trying to create portable ip range with non root-admin api client, should raise exception") with self.assertRaises(Exception): portable_ip_range = PortablePublicIpRange.create(self.api_client_user, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(portable_ip_range) except Exception as e: self.fail(e) @@ -269,19 +247,14 @@ def test_create_portable_ip_range_invalid_region(self): # 1. Try to create new portable ip range with invalid region id # 2. Portable ip range creation should fail - portable_ip_range_services = getPortableIpRangeServices(self.config) - - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = -1 + self.services["portableiprange"]["regionid"] = -1 #create new portable ip range self.debug("Trying to create portable ip range with wrong region id") with self.assertRaises(Exception): portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(portable_ip_range) return @@ -296,7 +269,7 @@ def setUpClass(cls): cls.testClient = super(TestDeletePortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -306,7 +279,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id - + cls.services["portableiprange"]["regionid"] = cls.region.id cls._cleanup = [] return @@ -323,16 +296,9 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - portable_ip_range_services = getPortableIpRangeServices(self.config) - - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup = [] return @@ -454,7 +420,7 @@ def setUpClass(cls): cls.testClient = super(TestListPortablePublicIpRanges, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -464,7 +430,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id - + cls.services["portableiprange"]["regionid"] = cls.region.id cls._cleanup = [] return @@ -480,27 +446,13 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - - #create new portable ip range - self.portable_ip_range_services = getPortableIpRangeServices(self.config) - - if self.portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - self.portable_ip_range_services["regionid"] = self.region.id - self.debug("Creating new portable IP range with startip:%s and endip:%s" % - (str(self.portable_ip_range_services["startip"]), - str(self.portable_ip_range_services["endip"]))) + (str(self.services["portableiprange"]["startip"]), + str(self.services["portableiprange"]["endip"]))) #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, - self.portable_ip_range_services) - - self.debug("Created new portable IP range with startip:%s and endip:%s and id:%s" % - (self.portable_ip_range.startip, - self.portable_ip_range.endip, - self.portable_ip_range.id)) + self.services["portableiprange"]) self.cleanup = [self.portable_ip_range, ] return @@ -532,16 +484,16 @@ def test_list_portable_ip_range(self): portable_ip_range = list_portable_ip_range[0] - self.assertEqual(str(portable_ip_range.startip), str(self.portable_ip_range_services["startip"]), + self.assertEqual(str(portable_ip_range.startip), str(self.services["portableiprange"]["startip"]), "Listed startip not matching with the startip of created public ip range") - self.assertEqual(str(portable_ip_range.endip), str(self.portable_ip_range_services["endip"]), + self.assertEqual(str(portable_ip_range.endip), str(self.services["portableiprange"]["endip"]), "Listed endip not matching with the endip of created public ip range") - self.assertEqual(str(portable_ip_range.gateway), str(self.portable_ip_range_services["gateway"]), + self.assertEqual(str(portable_ip_range.gateway), str(self.services["portableiprange"]["gateway"]), "Listed gateway not matching with the gateway of created public ip range") - self.assertEqual(str(portable_ip_range.netmask), str(self.portable_ip_range_services["netmask"]), + self.assertEqual(str(portable_ip_range.netmask), str(self.services["portableiprange"]["netmask"]), "Listed netmask not matching with the netmask of created public ip range") return @@ -580,7 +532,7 @@ def setUpClass(cls): cls.testClient = super(TestAssociatePublicIp, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -590,6 +542,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id + cls.services["portableiprange"]["regionid"] = cls.region.id template = get_template( cls.api_client, @@ -641,19 +594,10 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - portable_ip_range_services = getPortableIpRangeServices(self.config) - - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(self.portable_ip_range) return @@ -896,7 +840,7 @@ def setUpClass(cls): cls.testClient = super(TestDisassociatePublicIp, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -906,6 +850,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id + cls.services["portableiprange"]["regionid"] = cls.region.id template = get_template( cls.api_client, @@ -977,16 +922,9 @@ def setUp(self): self.dbclient = self.testClient.getDbConnection() self.cleanup = [] - portable_ip_range_services = getPortableIpRangeServices(self.config) - - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - portable_ip_range_services["regionid"] = self.region.id - #create new portable ip range new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(new_portable_ip_range) return @@ -1135,7 +1073,7 @@ def setUpClass(cls): cls.testClient = super(TestDeleteAccount, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -1146,6 +1084,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id + cls.services["portableiprange"]["regionid"] = cls.region.id template = get_template( cls.api_client, cls.zone.id, @@ -1171,10 +1110,6 @@ def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - portable_ip_range_services = getPortableIpRangeServices(self.config) - if portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - self.cleanup = [] try: self.account = Account.create( @@ -1184,10 +1119,10 @@ def setUp(self): admin=True ) self.cleanup.append(self.account) - portable_ip_range_services["regionid"] = self.region.id + self.debug("portable ip range services: %s" % self.services["portableiprange"]) #create new portable ip range new_portable_ip_range = PortablePublicIpRange.create(self.apiclient, - portable_ip_range_services) + self.services["portableiprange"]) self.cleanup.append(new_portable_ip_range) self.network_offering = NetworkOffering.create( self.apiclient, @@ -1226,8 +1161,7 @@ def test_delete_account_services_disabled(self): # 2. Delete account # 3. Account should get deleted successfully - try: - portableip = PublicIPAddress.create( + portableip = PublicIPAddress.create( self.apiclient, accountid=self.account.name, zoneid=self.zone.id, @@ -1235,12 +1169,16 @@ def test_delete_account_services_disabled(self): networkid=self.network.id, isportable=True ) + try: self.account.delete(self.apiclient) - with self.assertRaises(Exception): - PublicIPAddress.list(self.apiclient, - id=portableip.ipaddress.id) + self.cleanup.remove(self.account) except Exception as e: + portableip.delete(self.apiclient) self.fail(e) + + listpublicips = PublicIPAddress.list(self.apiclient, + id=portableip.ipaddress.id) + self.assertTrue(listpublicips is None, "list of public ips should be None") return @attr(tags=["advanced", "selfservice"]) @@ -1312,19 +1250,24 @@ def test_delete_account_services_enabled(self): except Exception as e: portableip.delete(self.apiclient) self.account.delete(self.apiclient) + self.cleanup.remove(self.account) self.fail("Error %s" % e) self.debug("Deleting account: %s :" % self.account.name) - self.account.delete(self.apiclient) + try: + self.account.delete(self.apiclient) + self.cleanup.remove(self.account) + except Exception as e: + portableip.delete(self.apiclient) + self.fail(e) self.debug("Trying to list the ip address associated with deleted account, \ should throw exception") - with self.assertRaises(Exception): - PublicIPAddress.list(self.apiclient, + listpublicips = PublicIPAddress.list(self.apiclient, id=portableip.ipaddress.id) - + self.assertTrue(listpublicips is None, "list of public ips should be None") return class TestPortableIpTransferAcrossNetworks(cloudstackTestCase): @@ -1337,7 +1280,7 @@ def setUpClass(cls): cls.testClient = super(TestPortableIpTransferAcrossNetworks, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services - cls.config = cls.services + cls.services["portableiprange"] = cls.testClient.getParsedTestDataConfig()["portableIpRange"] # Get Zone, Domain and templates cls.region = get_region(cls.api_client) cls.domain = get_domain(cls.api_client) @@ -1347,6 +1290,7 @@ def setUpClass(cls): cls.services["domainid"] = cls.domain.id cls.services["zoneid"] = cls.zone.id cls.services["regionid"] = cls.region.id + cls.services["portableiprange"]["regionid"] = cls.region.id template = get_template( cls.api_client, @@ -1431,18 +1375,9 @@ def tearDownClass(cls): def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - - #create new portable ip range - self.portable_ip_range_services = getPortableIpRangeServices(self.config) - - if self.portable_ip_range_services is FAILED: - self.skipTest('Failed to read config values related to portable ip range') - - self.portable_ip_range_services["regionid"] = self.region.id - #create new portable ip range self.portable_ip_range = PortablePublicIpRange.create(self.apiclient, - self.portable_ip_range_services) + self.services["portableiprange"]) self.cleanup = [self.portable_ip_range, ] return diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 19b9aa4afd..2b60626012 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -871,7 +871,8 @@ "netmask": "255.255.255.192", "startip": "10.223.252.196", "endip": "10.223.252.197", - "vlan": "1001" + "vlan": "1001", + "regionid": "" }, "sparse": { "name": "Sparse Type Disk offering", diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py index bc6b9c775f..187ede6756 100644 --- a/tools/marvin/marvin/lib/common.py +++ b/tools/marvin/marvin/lib/common.py @@ -1165,42 +1165,6 @@ def createNetworkRulesForVM(apiclient, virtualmachine, ruletype, [FAIL, e] return [PASS, public_ip] -def getPortableIpRangeServices(config): - """ Reads config values related to portable ip and fills up - services accordingly""" - - services = {} - attributeError = False - - if config["portableIpRange"]["startip"]: - services["startip"] = config["portableIpRange"]["startip"] - else: - attributeError = True - - if config["portableIpRange"]["endip"]: - services["endip"] = config["portableIpRange"]["endip"] - else: - attributeError = True - - if config["portableIpRange"]["netmask"]: - services["netmask"] = config["portableIpRange"]["netmask"] - else: - attributeError = True - - if config["portableIpRange"]["gateway"]: - services["gateway"] = config["portableIpRange"]["gateway"] - else: - attributeError = True - - if config["portableIpRange"]["vlan"]: - services["vlan"] = config["portableIpRange"]["vlan"] - - if attributeError: - services = FAILED - - return services - - def uploadVolume(apiclient, zoneid, account, services): try: # Upload the volume From 2c0765195a4a01ee51973c48d0561261d4fb01c6 Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Tue, 22 Jul 2014 04:23:10 -0400 Subject: [PATCH 149/819] CLOUDSTACK-7147: Resolving test script issue in test_ip_reservation.py --- test/integration/component/test_ip_reservation.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/integration/component/test_ip_reservation.py b/test/integration/component/test_ip_reservation.py index ce76c1ab55..157b7dd36b 100644 --- a/test/integration/component/test_ip_reservation.py +++ b/test/integration/component/test_ip_reservation.py @@ -964,9 +964,7 @@ def test_destroy_recreate_router(self): self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed") # Destroy Router - result = Router.destroy(self.apiclient, id=routers[0].id) - if result[0] == FAIL: - self.fail("Failed to destroy router: %s" % result[2]) + Router.destroy(self.apiclient, id=routers[0].id) #Restart Network isolated_network.restart(self.apiclient) @@ -1080,7 +1078,7 @@ def test_network_not_implemented(self): isolated_network = resultSet[1] with self.assertRaises(Exception): - response = isolated_network.update(self.apiclient, guestvmcidr="10.1.1.0/26") + isolated_network.update(self.apiclient, guestvmcidr="10.1.1.0/26") return @attr(tags=["advanced", "selfservice"]) From 173909e99d85cfcc85b017bc426950f9f16fddf0 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Tue, 22 Jul 2014 22:28:34 +0200 Subject: [PATCH 150/819] CLOUDSTACK-6181: Allow RBD volumes to be resized We don't need an external script to investigate the format of the RBD volume, we only have to ask Libvirt to resize the volume and that will ask librbd to do so. --- .../kvm/resource/LibvirtComputingResource.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 627c1fdac6..5eb988f970 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -1860,10 +1860,14 @@ public Answer execute(ResizeVolumeCommand cmd) { String path = vol.getPath(); String type = getResizeScriptType(pool, vol); - if (type == null) { - return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '" + pool.getType() + "' and volume format '" + vol.getFormat() + "'"); - } else if (type.equals("QCOW2") && shrinkOk) { - return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type); + if (pool.getType() != StoragePoolType.RBD) { + if (type == null) { + return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '" + pool.getType() + "' and volume format '" + vol.getFormat() + "'"); + } else if (type.equals("QCOW2") && shrinkOk) { + return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type); + } + } else { + s_logger.debug("Volume " + path + " is on a RBD storage pool. No need to query for additional information."); } s_logger.debug("Resizing volume: " + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk); From d3af2dbecacf260acda9f84a51a42838cc0f798c Mon Sep 17 00:00:00 2001 From: Will Stevens Date: Tue, 22 Jul 2014 17:28:01 -0400 Subject: [PATCH 151/819] CLOUDSTACK-6886 - Fixed the issue created by the SSL feature with the SDX: --- .../src/com/cloud/network/resource/NetscalerResource.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index 87576990e5..d556362021 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -247,7 +247,7 @@ public boolean configure(String name, Map params) throws Configu //enable load balancing feature enableLoadBalancingFeature(); - SSL.enableSslFeature(_netscalerService); + SSL.enableSslFeature(_netscalerService, _isSdx); //if the the device is cloud stack provisioned then make it part of the public network if (_cloudManaged) { @@ -1910,7 +1910,10 @@ private static void uploadKey(String nsIp, String user, String password, String } } - private static void enableSslFeature(nitro_service ns) throws ExecutionException { + private static void enableSslFeature(nitro_service ns, boolean isSdx) throws ExecutionException { + if (isSdx) { + return; + } try { base_response result = ns.enable_features(new String[] {"SSL"}); if (result.errorcode != 0) From c43b56998a7e04c3a0a0f034666aec76c585c48e Mon Sep 17 00:00:00 2001 From: Damodar Date: Tue, 22 Jul 2014 14:42:44 +0530 Subject: [PATCH 152/819] CLOUDSTACK-7153: addNicToVirtualMachine not BaseAsyncCreate but creates an entity --- api/src/com/cloud/event/EventTypes.java | 3 +++ server/src/com/cloud/vm/UserVmManagerImpl.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 411f620d16..7477152b70 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -31,6 +31,7 @@ import com.cloud.server.ResourceTag; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.vm.ConsoleProxy; +import com.cloud.vm.Nic; import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.SecondaryStorageVm; import org.apache.cloudstack.config.Configuration; @@ -575,6 +576,8 @@ public class EventTypes { entityEventDetails.put(EVENT_FIREWALL_EGRESS_CLOSE, FirewallRule.class); entityEventDetails.put(EVENT_FIREWALL_EGRESS_UPDATE, FirewallRule.class); + // Nic Events + entityEventDetails.put(EVENT_NIC_CREATE, Nic.class); // Load Balancers entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 90f37ef902..ab9ebe0058 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1041,7 +1041,7 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV if (guestNic == null) { throw new CloudRuntimeException("Unable to add NIC to " + vmInstance); } - + CallContext.current().putContextParameter(Nic.class.getName(), guestNic.getUuid()); s_logger.debug("Successful addition of " + network + " from " + vmInstance); return _vmDao.findById(vmInstance.getId()); } From 0ac2eb4f671841b2525db810940d8502e6a3dcf4 Mon Sep 17 00:00:00 2001 From: sanjeev Date: Thu, 17 Jul 2014 16:53:46 +0530 Subject: [PATCH 153/819] CLOUDSTACK: Static IP address assignment for VM Signed-off-by: sanjeev Incorporated review comments for review request 23614 --- .../component/test_escalations_instances.py | 115 +++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/test/integration/component/test_escalations_instances.py b/test/integration/component/test_escalations_instances.py index 4900ff625e..79fd3b1231 100644 --- a/test/integration/component/test_escalations_instances.py +++ b/test/integration/component/test_escalations_instances.py @@ -27,7 +27,7 @@ from marvin.codes import SUCCESS from nose.plugins.attrib import attr from time import sleep -from ctypes.wintypes import BOOLEAN +# from ctypes.wintypes import BOOLEAN class TestListInstances(cloudstackTestCase): @@ -84,7 +84,7 @@ def setUpClass(cls): cls.api_client, account=cls.account.name, domainid=cls.domain.id, - max=-1, + max= -1, resourcetype=i ) @@ -1924,7 +1924,7 @@ def setUpClass(cls): cls.api_client, account=cls.account.name, domainid=cls.domain.id, - max=-1, + max= -1, resourcetype=i ) cls._cleanup.append(cls.account) @@ -3458,3 +3458,112 @@ def test_23_deploy_vm_multiple_securitygroups(self): "Security Groups in VM are not same as created" ) return + + @attr(tags=["advanced", "selfservice"]) + def test_24_deploy_vm_with_static_ip_ES1662(self): + """ + @Desc: Test to verify deploy VM with static ip address assignment + @Steps: + Step1: Create a network for the user + Step2: List the network and check that it is created for the user + Step3: Deploy vm with ip address in the above network + Step4: List the vm and verify the ip address in the response + """ + # Listing Network Offerings + network_offerings_list = NetworkOffering.list( + self.apiClient, + forvpc="false", + guestiptype="Isolated", + state="Enabled", + supportedservices="SourceNat", + zoneid=self.zone.id + ) + status = validateList(network_offerings_list) + self.assertEquals( + PASS, + status[0], + "Isolated Network Offerings with sourceNat enabled are not found" + ) + """ + Create Isolated netwrok with ip range + """ + self.services["network"]["startip"] = "10.1.1.2" + self.services["network"]["endip"] = "10.1.1.254" + self.services["network"]["gateway"] = "10.1.1.1" + self.services["network"]["netmask"] = "255.255.255.0" + vm_ip = "10.1.1.10" + """ + Creating isolated/guest network with ip range + """ + network = Network.create( + self.userapiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=network_offerings_list[0].id, + zoneid=self.zone.id + ) + self.assertIsNotNone( + network, + "Network creation failed" + ) + # Deploying a VM + vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=network.id, + ipaddress=vm_ip, + serviceofferingid=self.service_offering.id, + ) + self.assertIsNotNone( + vm_created, + "VM creation failed" + ) + # self.cleanup.append(vm_created) + self.cleanup.append(network) + # Listing all the VMs for a user again + vm_response = VirtualMachine.list( + self.userapiclient, + id=vm_created.id, + ) + status = validateList(vm_response) + self.assertEquals( + PASS, + status[0], + "vm list returned invalid response" + ) + # Verifying that the size of the list is 1 + self.assertEquals( + 1, + len(vm_response), + "VM list count is not matching" + ) + # Verifying that the NIC's in VM created are same as provided + vm_nics = vm_created.nic + status = validateList(vm_nics) + self.assertEquals( + PASS, + status[0], + "vm list returned invalid response for vm nics" + ) + # Verifying that the size of nics is 1 + self.assertEquals( + 1, + len(vm_nics), + "VM is created with more than one nic which is not expected" + ) + """ + Verifying that NIC IP address is as expected + """ + self.assertEquals( + str(vm_nics[0].ipaddress), + vm_ip, + "VM is not created with static ip address used in vm deployment" + ) + try: + vm_created.delete(self.apiClient, expunge=True) + except Exception as e: + raise Exception("Warning: Exception in expunging vm : %s" % e) + return From 628d8e66f77053de9819436739325720710175ed Mon Sep 17 00:00:00 2001 From: Ritu Sabharwal Date: Wed, 23 Jul 2014 08:51:20 +0200 Subject: [PATCH 154/819] CLOUDSTACK-6823 : First code drop for Brocade Network plugin to orchestrate Brocade VDX switches for L2 connectivity Signed-off-by: Hugo Trippaers --- api/src/com/cloud/network/Network.java | 3 +- api/src/com/cloud/network/Networks.java | 16 +- .../com/cloud/network/PhysicalNetwork.java | 2 +- .../network/ExternalNetworkDeviceManager.java | 1 + .../classes/resources/messages.properties | 6 + .../resources/messages_zh_CN.properties | 3 + client/pom.xml | 5 + client/tomcatconf/commands.properties.in | 7 + plugins/network-elements/brocade-vcs/pom.xml | 78 +++ .../resources/BrocadeInterfaceSchema.xsd | 51 ++ .../resources/BrocadePortProfileSchema.xsd | 118 ++++ .../resources/BrocadeShowVcsSchema.xsd | 108 ++++ .../META-INF/cloudstack/vcs/module.properties | 18 + .../cloudstack/vcs/spring-vcs-context.xml | 29 + .../api/AssociateMacToNetworkAnswer.java | 30 + .../api/AssociateMacToNetworkCommand.java | 48 ++ .../cloud/agent/api/CreateNetworkAnswer.java | 30 + .../cloud/agent/api/CreateNetworkCommand.java | 48 ++ .../cloud/agent/api/DeleteNetworkAnswer.java | 30 + .../cloud/agent/api/DeleteNetworkCommand.java | 43 ++ .../api/DisassociateMacFromNetworkAnswer.java | 30 + .../DisassociateMacFromNetworkCommand.java | 42 ++ .../agent/api/StartupBrocadeVcsCommand.java | 27 + .../api/commands/AddBrocadeVcsDeviceCmd.java | 128 ++++ .../commands/DeleteBrocadeVcsDeviceCmd.java | 105 ++++ .../ListBrocadeVcsDeviceNetworksCmd.java | 104 +++ .../commands/ListBrocadeVcsDevicesCmd.java | 108 ++++ .../response/BrocadeVcsDeviceResponse.java | 74 +++ .../com/cloud/network/BrocadeVcsDeviceVO.java | 99 +++ .../BrocadeVcsNetworkVlanMappingVO.java | 72 +++ .../cloud/network/brocade/BrocadeVcsApi.java | 521 ++++++++++++++++ .../brocade/BrocadeVcsApiException.java | 36 ++ .../com/cloud/network/brocade/Constants.java | 37 ++ .../com/cloud/network/dao/BrocadeVcsDao.java | 35 ++ .../cloud/network/dao/BrocadeVcsDaoImpl.java | 53 ++ .../dao/BrocadeVcsNetworkVlanMappingDao.java | 32 + .../BrocadeVcsNetworkVlanMappingDaoImpl.java | 49 ++ .../network/element/BrocadeVcsElement.java | 467 ++++++++++++++ .../element/BrocadeVcsElementService.java | 45 ++ .../guru/BrocadeVcsGuestNetworkGuru.java | 267 ++++++++ .../network/resource/BrocadeVcsResource.java | 310 +++++++++ .../network/brocade/BrocadeVcsApiTest.java | 185 ++++++ .../guru/BrocadeVcsGuestNetworkGuruTest.java | 590 ++++++++++++++++++ .../resource/BrocadeVcsResourceTest.java | 261 ++++++++ plugins/pom.xml | 1 + setup/db/db/schema-440to450.sql | 20 + .../integration/component/test_brocade_vcs.py | 333 ++++++++++ tools/apidoc/gen_toc.py | 1 + ui/dictionary.jsp | 6 + ui/scripts/system.js | 397 +++++++++++- ui/scripts/ui-custom/zoneWizard.js | 5 +- 51 files changed, 5108 insertions(+), 6 deletions(-) create mode 100644 plugins/network-elements/brocade-vcs/pom.xml create mode 100644 plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd create mode 100644 plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd create mode 100644 plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd create mode 100644 plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties create mode 100644 plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java create mode 100644 plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java create mode 100644 plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java create mode 100644 plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java create mode 100644 plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java create mode 100644 test/integration/component/test_brocade_vcs.py diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 0a08f28104..341c6c4c55 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -135,6 +135,7 @@ public static class Provider { // add Nuage Vsp Providers public static final Provider NuageVsp = new Provider("NuageVsp", false); public static final Provider NuageVspVpc = new Provider("NuageVspVpc", false); + public static final Provider BrocadeVcs = new Provider("BrocadeVcs", false); private final String name; private final boolean isExternal; @@ -223,7 +224,7 @@ public enum State { Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"), Implementing( "Indicates the network configuration is being implemented"), Implemented("Indicates the network configuration is in use"), Shutdown( - "Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed"); + "Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed"); protected static final StateMachine2 s_fsm = new StateMachine2(); diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index 1ad33509fb..f027cf9fe9 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -104,8 +104,20 @@ public URI toUri(T value) { else return new URI("vxlan://" + value.toString()); } catch (URISyntaxException e) { - throw new CloudRuntimeException( - "Unable to convert to broadcast URI: " + value); + throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value); + } + } + }, + Vcs("vcs", Integer.class) { + @Override + public URI toUri(T value) { + try { + if (value.toString().contains("://")) + return new URI(value.toString()); + else + return new URI("vcs://" + value.toString()); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value); } } }, diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 024b3cedec..7c9349d932 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -33,7 +33,7 @@ public enum State { } public enum IsolationMethod { - VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN, VSP; + VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN, VSP, VCS; } public enum BroadcastDomainRange { diff --git a/api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java b/api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java index e73f5263a4..f38e9e6156 100644 --- a/api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java +++ b/api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java @@ -46,6 +46,7 @@ public static class NetworkDevice { public static final NetworkDevice NiciraNvp = new NetworkDevice("NiciraNvp", Network.Provider.NiciraNvp.getName()); public static final NetworkDevice CiscoVnmc = new NetworkDevice("CiscoVnmc", Network.Provider.CiscoVnmc.getName()); public static final NetworkDevice OpenDaylightController = new NetworkDevice("OpenDaylightController", Network.Provider.Opendaylight.getName()); + public static final NetworkDevice BrocadeVcs = new NetworkDevice("BrocadeVcs", Network.Provider.BrocadeVcs.getName()); public NetworkDevice(String deviceName, String ntwkServiceprovider) { _name = deviceName; diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index bb75b08a27..271ffec8e5 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -328,6 +328,7 @@ label.add.new.PA=Add new Palo Alto label.add.new.tier=Add new tier label.add.NiciraNvp.device=Add Nvp Controller label.add.NuageVsp.device=Add Nuage Virtualized Services Directory (VSD) +label.add.BrocadeVcs.device=Add Brocade Vcs Switch label.add.physical.network=Add physical network label.add.pod=Add Pod label.add.port.forwarding.rule=Add port forwarding rule @@ -504,6 +505,7 @@ label.delete.gateway=delete gateway label.delete.NetScaler=Delete NetScaler label.delete.NiciraNvp=Remove Nvp Controller label.delete.NuageVsp=Remove Nuage VSD +label.delete.BrocadeVcs=Remove Brocade Vcs Switch label.delete.project=Delete project label.delete.SRX=Delete SRX label.delete.PA=Delete Palo Alto @@ -878,6 +880,7 @@ label.nic.adapter.type=NIC adapter type label.nicira.controller.address=Controller Address label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid label.nicira.transportzoneuuid=Transport Zone Uuid +label.brocade.vcs.address=Vcs Switch Address label.nics=NICs label.no.actions=No Available Actions label.no.alerts=No Recent Alerts @@ -1423,6 +1426,8 @@ label.srx.details=SRX details label.palo.alto.details=Palo Alto details label.added.nicira.nvp.controller=Added new Nicira NVP Controller label.nicira.nvp.details=Nicira NVP details +label.added.brocade.vcs.switch=Added new Brocade Vcs Switch +label.brocade.vcs.details=Brocade Vcs Switch details label.added.new.bigswitch.vns.controller=Added new BigSwitch VNS Controller label.bigswitch.vns.details=BigSwitch VNS details label.dedicate=Dedicate @@ -1634,6 +1639,7 @@ message.configuring.public.traffic=Configuring public traffic message.configuring.storage.traffic=Configuring storage traffic message.confirm.action.force.reconnect=Please confirm that you want to force reconnect this host. message.confirm.delete.F5=Please confirm that you would like to delete F5 +message.confirm.delete.BrocadeVcs=Please confirm that you would like to delete Brocade Vcs Switch message.confirm.delete.NetScaler=Please confirm that you would like to delete NetScaler message.confirm.delete.NuageVsp=Please confirm that you would like to delete Nuage Virtualized Services Directory message.confirm.delete.SRX=Please confirm that you would like to delete SRX diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties index d7a0ca9ba6..2c497bc893 100644 --- a/client/WEB-INF/classes/resources/messages_zh_CN.properties +++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties @@ -298,6 +298,7 @@ label.add.new.tier=\u6dfb\u52a0\u65b0\u5c42 label.add.nfs.secondary.staging.store=\u6dfb\u52a0 NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.add.NiciraNvp.device=\u6dfb\u52a0 Nvp \u63a7\u5236\u5668 label.add.NuageVsp.device=\u6DFB\u52A0 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 (VSD) +label.add.BrocadeVcs.device=\u6dfb\u52a0 Vcs \u63a7\u5236\u5668 label.add.OpenDaylight.device=\u6dfb\u52a0 OpenDaylight \u63a7\u5236\u5668 label.add.PA.device=\u6dfb\u52a0 Palo Alto \u8bbe\u5907 label.add.physical.network=\u6dfb\u52a0\u7269\u7406\u7f51\u7edc @@ -511,6 +512,7 @@ label.delete.gateway=\u5220\u9664\u7f51\u5173 label.delete.NetScaler=\u5220\u9664 NetScaler label.delete.NiciraNvp=\u79fb\u9664 Nvp \u63a7\u5236\u5668 label.delete.NuageVsp=\u5220\u9664 Nuage VSD +label.delete.BrocadeVcs=\u79fb\u9664 Vcs \u63a7\u5236\u5668 label.delete.OpenDaylight.device=\u5220\u9664 OpenDaylight \u63a7\u5236\u5668 label.delete.PA=\u5220\u9664 Palo Alto label.delete.portable.ip.range=\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 @@ -1610,6 +1612,7 @@ message.confirm.dedicate.pod.domain.account=\u662f\u5426\u786e\u5b9e\u8981\u5c06 message.confirm.dedicate.zone=\u662f\u5426\u8981\u5c06\u6b64\u8d44\u6e90\u57df\u4e13\u7528\u4e8e\u57df/\u5e10\u6237? message.confirm.delete.ciscovnmc.resource=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 CiscoVNMC \u8d44\u6e90 message.confirm.delete.F5=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 F5 +message.confirm.delete.BrocadeVcs=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 Brocade Vcs Switch message.confirm.delete.NetScaler=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 NetScaler message.confirm.delete.NuageVsp=\u8BF7\u786E\u8BA4\u5220\u9664 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 message.confirm.delete.PA=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 Palo Alto diff --git a/client/pom.xml b/client/pom.xml index 410cb19a1a..fcd8317ff3 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -145,6 +145,11 @@ cloud-plugin-network-opendaylight ${project.version} + + org.apache.cloudstack + cloud-plugin-network-vcs + ${project.version} + org.apache.cloudstack cloud-plugin-hypervisor-xenserver diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index aa03949fa4..c1d21b96aa 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -607,6 +607,13 @@ listNiciraNvpDeviceNetworks=1 # Not implemented (yet) #configureNiciraNvpDevice=1 +#### brocade vcs commands + +addBrocadeVcsDevice=1 +deleteBrocadeVcsDevice=1 +listBrocadeVcsDevices=1 +listBrocadeVcsDeviceNetworks=1 + #### bigswitch vns commands addBigSwitchVnsDevice=1 diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml new file mode 100644 index 0000000000..50dc9a480d --- /dev/null +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + cloud-plugin-network-vcs + Apache CloudStack Plugin - Network Brocade VCS + + org.apache.cloudstack + cloudstack-plugins + 4.5.0-SNAPSHOT + ../../pom.xml + + + + + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + 0.7.1 + + + interface + + generate + + + ${project.basedir}/target/generated-sources/xjc1 + ${project.basedir}/resources + + BrocadeInterfaceSchema.xsd + + com.cloud.network.schema.interfacevlan + + + + portprofile + + generate + + + ${project.basedir}/target/generated-sources/xjc2 + ${project.basedir}/resources + + BrocadePortProfileSchema.xsd + + com.cloud.network.schema.portprofile + + + + show-vcs + + generate + + + ${project.basedir}/target/generated-sources/xjc3 + ${project.basedir}/resources + + BrocadeShowVcsSchema.xsd + + com.cloud.network.schema.showvcs + + + + + + + + diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd b/plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd new file mode 100644 index 0000000000..d24e845061 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd @@ -0,0 +1,51 @@ + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd b/plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd new file mode 100644 index 0000000000..9f21ef070c --- /dev/null +++ b/plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd @@ -0,0 +1,118 @@ + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd b/plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd new file mode 100644 index 0000000000..aca9125a70 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd @@ -0,0 +1,108 @@ + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties b/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties new file mode 100644 index 0000000000..db2c80da69 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties @@ -0,0 +1,18 @@ +# 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. +name=vcs +parent=network \ No newline at end of file diff --git a/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml b/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml new file mode 100644 index 0000000000..4c2b419ef5 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java new file mode 100644 index 0000000000..f8541b51aa --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class AssociateMacToNetworkAnswer extends Answer { + + public AssociateMacToNetworkAnswer(Command command, boolean success, String details) { + super(command, success, details); + + } + + public AssociateMacToNetworkAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java new file mode 100644 index 0000000000..91b714a864 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class AssociateMacToNetworkCommand extends Command { + + private String _interfaceMac; + private long _networkId; + private String _ownerName; + + public AssociateMacToNetworkCommand(long networkId, String interfaceMac, String ownerName) { + _networkId = networkId; + _interfaceMac = interfaceMac; + _ownerName = ownerName; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getInterfaceMac() { + return _interfaceMac; + } + + public long getNetworkId() { + return _networkId; + } + + public String getOwnerName() { + return _ownerName; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java new file mode 100644 index 0000000000..7d02c6358e --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class CreateNetworkAnswer extends Answer { + + public CreateNetworkAnswer(Command command, boolean success, String details) { + super(command, success, details); + + } + + public CreateNetworkAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java new file mode 100644 index 0000000000..3516dc39f6 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class CreateNetworkCommand extends Command { + + private int _vlanId; + private long _networkId; + private String _ownerName; + + public CreateNetworkCommand(int vlanId, long networkId, String ownerName) { + _vlanId = vlanId; + _networkId = networkId; + _ownerName = ownerName; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public int getVlanId() { + return _vlanId; + } + + public long getNetworkId() { + return _networkId; + } + + public String getOwnerName() { + return _ownerName; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java new file mode 100644 index 0000000000..c12bd998ec --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class DeleteNetworkAnswer extends Answer { + + public DeleteNetworkAnswer(Command command, boolean success, String details) { + super(command, success, details); + + } + + public DeleteNetworkAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.java new file mode 100644 index 0000000000..93e3f966a9 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.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.agent.api; + +public class DeleteNetworkCommand extends Command { + + private int _vlanId; + private long _networkId; + + public DeleteNetworkCommand(int vlanId, long networkId) { + _vlanId = vlanId; + _networkId = networkId; + + } + + @Override + public boolean executeInSequence() { + return false; + } + + public int getVlanId() { + return _vlanId; + } + + public long getNetworkId() { + return _networkId; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java new file mode 100644 index 0000000000..0146fe2cf7 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class DisassociateMacFromNetworkAnswer extends Answer { + + public DisassociateMacFromNetworkAnswer(Command command, boolean success, String details) { + super(command, success, details); + + } + + public DisassociateMacFromNetworkAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java new file mode 100644 index 0000000000..86777ae5c7 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.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.agent.api; + +public class DisassociateMacFromNetworkCommand extends Command { + + private String _interfaceMac; + private long _networkId; + + public DisassociateMacFromNetworkCommand(long networkId, String interfaceMac) { + _networkId = networkId; + _interfaceMac = interfaceMac; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getInterfaceMac() { + return _interfaceMac; + } + + public long getNetworkId() { + return _networkId; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java new file mode 100644 index 0000000000..43d3222169 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +import com.cloud.host.Host; + +public class StartupBrocadeVcsCommand extends StartupCommand { + + public StartupBrocadeVcsCommand() { + super(Host.Type.L2Networking); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java new file mode 100644 index 0000000000..5ade8158dd --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java @@ -0,0 +1,128 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.BrocadeVcsDeviceResponse; +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.BrocadeVcsDeviceVO; +import com.cloud.network.brocade.Constants; +import com.cloud.network.element.BrocadeVcsElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "addBrocadeVcsDevice", responseObject = BrocadeVcsDeviceResponse.class, description = "Adds a Brocade VCS Switch", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class AddBrocadeVcsDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "addbrocadevcsdeviceresponse"; + @Inject + protected BrocadeVcsElementService brocadeVcsElementService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = true, description = "the Physical Network ID") + private Long physicalNetworkId; + + @Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "Hostname of ip address of the Brocade VCS Switch.") + private String host; + + @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Credentials to access the Brocade VCS Switch API") + private String username; + + @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Credentials to access the Brocade VCS Switch API") + private String password; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getHost() { + return host; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + BrocadeVcsDeviceVO brocadeVcsDeviceVO = brocadeVcsElementService.addBrocadeVcsDevice(this); + if (brocadeVcsDeviceVO != null) { + BrocadeVcsDeviceResponse response = brocadeVcsElementService.createBrocadeVcsDeviceResponse(brocadeVcsDeviceVO); + response.setObjectName("brocadevcsdevice"); + response.setResponseName(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Brocade VCS Switch due to internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return Constants.EVENT_EXTERNAL_VCS_CONTROLLER_ADD; + } + + @Override + public String getEventDescription() { + return "Adding a Brocade VCS Switch"; + } +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java new file mode 100644 index 0000000000..6b7ccf85d5 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java @@ -0,0 +1,105 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.BrocadeVcsDeviceResponse; +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.brocade.Constants; +import com.cloud.network.element.BrocadeVcsElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "deleteBrocadeVcsDevice", responseObject = SuccessResponse.class, description = " delete a Brocade VCS Switch", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class DeleteBrocadeVcsDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "deletebrocadevcsdeviceresponse"; + @Inject + protected BrocadeVcsElementService brocadeVcsElementService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = Constants.BROCADE_VCS_DEVICE_ID, type = CommandType.UUID, entityType = BrocadeVcsDeviceResponse.class, required = true, description = "Brocade Switch ID") + private Long brocadeVcsDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getBrocadeVcsDeviceId() { + return brocadeVcsDeviceId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result = brocadeVcsElementService.deleteBrocadeVcsDevice(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Brocade VCS Switch."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return Constants.EVENT_EXTERNAL_VCS_CONTROLLER_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting Brocade VCS Switch"; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java new file mode 100644 index 0000000000..584a6e665b --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java @@ -0,0 +1,104 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ResponseObject.ResponseView; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.NetworkResponse; + +import com.cloud.api.response.BrocadeVcsDeviceResponse; +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.brocade.Constants; +import com.cloud.network.element.BrocadeVcsElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "listBrocadeVcsDeviceNetworks", responseObject = NetworkResponse.class, description = "lists network that are using a brocade vcs switch", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class ListBrocadeVcsDeviceNetworksCmd extends BaseListCmd { + + public static final Logger s_logger = Logger.getLogger(ListBrocadeVcsDeviceNetworksCmd.class.getName()); + private static final String s_name = "listbrocadevcsdevicenetworks"; + @Inject + protected BrocadeVcsElementService brocadeVcsElementService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = Constants.BROCADE_VCS_DEVICE_ID, type = CommandType.UUID, entityType = BrocadeVcsDeviceResponse.class, required = true, description = "brocade vcs switch ID") + private Long brocadeVcsDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getBrocadeVcsDeviceId() { + return brocadeVcsDeviceId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + List networks = brocadeVcsElementService.listBrocadeVcsDeviceNetworks(this); + ListResponse response = new ListResponse(); + List networkResponses = new ArrayList(); + + if (networks != null && !networks.isEmpty()) { + for (Network network : networks) { + NetworkResponse networkResponse = _responseGenerator.createNetworkResponse(ResponseView.Full, network); + networkResponses.add(networkResponse); + } + } + + response.setResponses(networkResponses); + response.setResponseName(getCommandName()); + setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java new file mode 100644 index 0000000000..3fc2be09c4 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java @@ -0,0 +1,108 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; + +import com.cloud.api.response.BrocadeVcsDeviceResponse; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.network.brocade.Constants; +import com.cloud.network.element.BrocadeVcsElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "listBrocadeVcsDevices", responseObject = BrocadeVcsDeviceResponse.class, description = "Lists Brocade VCS Switches", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class ListBrocadeVcsDevicesCmd extends BaseListCmd { + private static final String s_name = "listbrocadevcsdeviceresponse"; + + @Inject + protected BrocadeVcsElementService brocadeVcsElementService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the Physical Network ID") + private Long physicalNetworkId; + + @Parameter(name = Constants.BROCADE_VCS_DEVICE_ID, type = CommandType.UUID, entityType = BrocadeVcsDeviceResponse.class, description = "Brocade VCS switch ID") + private Long brocadeVcsDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getBrocadeVcsDeviceId() { + return brocadeVcsDeviceId; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { + try { + List brocadeDevices = brocadeVcsElementService.listBrocadeVcsDevices(this); + ListResponse response = new ListResponse(); + List brocadeDevicesResponse = new ArrayList(); + + if (brocadeDevices != null && !brocadeDevices.isEmpty()) { + for (BrocadeVcsDeviceVO brocadeDeviceVO : brocadeDevices) { + BrocadeVcsDeviceResponse brocadeDeviceResponse = brocadeVcsElementService.createBrocadeVcsDeviceResponse(brocadeDeviceVO); + brocadeDevicesResponse.add(brocadeDeviceResponse); + } + } + + response.setResponses(brocadeDevicesResponse); + response.setResponseName(getCommandName()); + setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java b/plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java new file mode 100644 index 0000000000..60edbcf4e7 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java @@ -0,0 +1,74 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.network.brocade.Constants; +import com.cloud.serializer.Param; + +@EntityReference(value = BrocadeVcsDeviceVO.class) +public class BrocadeVcsDeviceResponse extends BaseResponse { + @SerializedName(Constants.BROCADE_VCS_DEVICE_ID) + @Param(description = "device id of the Brocade Vcs") + private String id; + + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) + @Param(description = "the physical Network to which this Brocade VCS belongs to") + private String physicalNetworkId; + + @SerializedName(ApiConstants.PROVIDER) + @Param(description = "name of the provider") + private String providerName; + + @SerializedName(Constants.BROCADE_VCS_DEVICE_NAME) + @Param(description = "device name") + private String deviceName; + + @SerializedName(ApiConstants.HOST_NAME) + @Param(description = "the principal switch Ip address") + private String hostName; + + public void setId(String vcsDeviceId) { + this.id = vcsDeviceId; + } + + public void setPhysicalNetworkId(final String physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setProviderName(final String providerName) { + this.providerName = providerName; + } + + public void setDeviceName(final String deviceName) { + this.deviceName = deviceName; + } + + public void setHostName(final String hostName) { + this.hostName = hostName; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java new file mode 100644 index 0000000000..e229e3c8b8 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java @@ -0,0 +1,99 @@ +// +// 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; + +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 org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "external_brocade_vcs_devices") +public class BrocadeVcsDeviceVO implements InternalIdentity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "host_id") + private long hostId; + + @Column(name = "physical_network_id") + private long physicalNetworkId; + + @Column(name = "provider_name") + private String providerName; + + @Column(name = "device_name") + private String deviceName; + + public BrocadeVcsDeviceVO() { + uuid = UUID.randomUUID().toString(); + } + + public BrocadeVcsDeviceVO(final long hostId, long physicalNetworkId, final String providerName, final String deviceName) { + super(); + this.hostId = hostId; + this.physicalNetworkId = physicalNetworkId; + this.providerName = providerName; + this.deviceName = deviceName; + uuid = UUID.randomUUID().toString(); + } + + @Override + public long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public long getHostId() { + return hostId; + } + + public String getProviderName() { + return providerName; + } + + public String getDeviceName() { + return deviceName; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java new file mode 100644 index 0000000000..fd3bc97216 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java @@ -0,0 +1,72 @@ +// 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; + +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 org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "brocade_network_vlan_map") +public class BrocadeVcsNetworkVlanMappingVO implements InternalIdentity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "network_id") + private long networkId; + + @Column(name = "vlan_id") + private int vlanId; + + public BrocadeVcsNetworkVlanMappingVO() { + } + + public BrocadeVcsNetworkVlanMappingVO(long networkId, int vlanId) { + this.networkId = networkId; + this.vlanId = vlanId; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + + public int getVlanId() { + return vlanId; + } + + public void setVlanId(int vlanId) { + this.vlanId = vlanId; + } + + @Override + public long getId() { + return id; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java new file mode 100644 index 0000000000..d5f06f8998 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java @@ -0,0 +1,521 @@ +// 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.brocade; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.Charset; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.log4j.Logger; + +import com.cloud.network.schema.interfacevlan.InterfaceVlan; +import com.cloud.network.schema.interfacevlan.Interface; +import com.cloud.network.schema.interfacevlan.Vlan; +import com.cloud.network.schema.portprofile.PortProfile; +import com.cloud.network.schema.portprofile.PortProfile.Activate; +import com.cloud.network.schema.portprofile.PortProfile.Static; +import com.cloud.network.schema.portprofile.PortProfileGlobal; +import com.cloud.network.schema.portprofile.VlanProfile; +import com.cloud.network.schema.portprofile.VlanProfile.Switchport; +import com.cloud.network.schema.portprofile.VlanProfile.Switchport.Mode; +import com.cloud.network.schema.portprofile.VlanProfile.Switchport.Trunk; +import com.cloud.network.schema.portprofile.VlanProfile.Switchport.Trunk.Allowed; +import com.cloud.network.schema.portprofile.VlanProfile.SwitchportBasic; +import com.cloud.network.schema.portprofile.VlanProfile.SwitchportBasic.Basic; +import com.cloud.network.schema.showvcs.Output; + +public class BrocadeVcsApi { + private static final Logger s_logger = Logger.getLogger(BrocadeVcsApi.class); + + private String _host; + private String _adminuser; + private String _adminpass; + + protected DefaultHttpClient _client; + + protected HttpRequestBase createMethod(String type, String uri) throws BrocadeVcsApiException { + String url; + try { + url = new URL(Constants.PROTOCOL, _host, Constants.PORT, uri).toString(); + } catch (MalformedURLException e) { + s_logger.error("Unable to build Brocade Switch API URL", e); + throw new BrocadeVcsApiException("Unable to build Brocade Switch API URL", e); + } + + if ("post".equalsIgnoreCase(type)) { + return new HttpPost(url); + } else if ("get".equalsIgnoreCase(type)) { + return new HttpGet(url); + } else if ("delete".equalsIgnoreCase(type)) { + return new HttpDelete(url); + } else if ("patch".equalsIgnoreCase(type)) { + return new HttpPatch(url); + } else { + throw new BrocadeVcsApiException("Requesting unknown method type"); + } + } + + public BrocadeVcsApi(String address, String username, String password) { + _host = address; + _adminuser = username; + _adminpass = password; + _client = new DefaultHttpClient(); + _client.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(_adminuser, _adminpass)); + + } + + /* + * Get Operational Status + */ + public Output getSwitchStatus() throws BrocadeVcsApiException { + return executeRetreiveStatus(Constants.STATUS_URI); + + } + + /* + * Creates a new virtual network. + */ + public boolean createNetwork(int vlanId, long networkId) throws BrocadeVcsApiException { + + if (createInterfaceVlan(vlanId)) { + + PortProfile portProfile = createPortProfile(vlanId, networkId); + + if (portProfile != null) { + return activatePortProfile(portProfile); + } + } + return false; + } + + /* + * Activates a port-profile. + */ + private boolean activatePortProfile(PortProfile portProfile) throws BrocadeVcsApiException { + PortProfileGlobal portProfileGlobal = new PortProfileGlobal(); + portProfile.setVlanProfile(null); + Activate activate = new Activate(); + portProfile.setActivate(activate); + portProfileGlobal.setPortProfile(portProfile); + + //activate port-profile + return executeUpdateObject(portProfileGlobal, Constants.URI); + } + + /* + * Creates AMPP port-profile. + */ + private PortProfile createPortProfile(int vlanId, long networkId) throws BrocadeVcsApiException { + + PortProfile portProfile = new PortProfile(); + portProfile.setName(Constants.PORT_PROFILE_NAME_PREFIX + networkId); + if (executeCreateObject(portProfile, Constants.URI)) { + if (createVlanSubProfile(vlanId, portProfile)) { + return portProfile; + } + } + return null; + } + + /* + * Create vlan sub-profile for port-profile + */ + private boolean createVlanSubProfile(int vlanId, PortProfile portProfile) throws BrocadeVcsApiException { + VlanProfile vlanProfile = new VlanProfile(); + portProfile.setVlanProfile(vlanProfile); + if (executeUpdateObject(portProfile, Constants.URI)) { + return configureVlanSubProfile(vlanId, portProfile); + } + return false; + } + + /* + * Configures vlan sub-profile for port-profile. + * - configure L2 mode for vlan sub-profile + * - configure trunk mode for vlan sub-profile + * - configure allowed VLANs for vlan sub-profile + */ + private boolean configureVlanSubProfile(int vlanId, PortProfile portProfile) throws BrocadeVcsApiException { + SwitchportBasic switchPortBasic = new SwitchportBasic(); + Basic basic = new Basic(); + switchPortBasic.setBasic(basic); + portProfile.getVlanProfile().setSwitchportBasic(switchPortBasic); + // configure L2 mode for vlan sub-profile + if (executeUpdateObject(portProfile, Constants.URI)) { + VlanProfile vlanProfile = new VlanProfile(); + Switchport switchPort = new Switchport(); + Mode mode = new Mode(); + mode.setVlanMode("trunk"); + switchPort.setMode(mode); + vlanProfile.setSwitchport(switchPort); + portProfile.setVlanProfile(vlanProfile); + + // configure trunk mode for vlan sub-profile + if (executeUpdateObject(portProfile, Constants.URI)) { + vlanProfile = new VlanProfile(); + switchPort = new Switchport(); + Trunk trunk = new Trunk(); + Allowed allowed = new Allowed(); + Allowed.Vlan allowedVlan = new Allowed.Vlan(); + allowedVlan.setAdd(vlanId); + allowed.setVlan(allowedVlan); + trunk.setAllowed(allowed); + switchPort.setTrunk(trunk); + vlanProfile.setSwitchport(switchPort); + portProfile.setVlanProfile(vlanProfile); + + //configure allowed VLANs for vlan sub-profile + return executeUpdateObject(portProfile, Constants.URI); + } + } + + return false; + + } + + /* + * Creates a vlan interface. + */ + private boolean createInterfaceVlan(int vlanId) throws BrocadeVcsApiException { + InterfaceVlan interfaceVlan = new InterfaceVlan(); + Interface interfaceObj = new Interface(); + Vlan vlan = new Vlan(); + vlan.setName(vlanId); + interfaceObj.setVlan(vlan); + interfaceVlan.setInterface(interfaceObj); + + return executeUpdateObject(interfaceVlan, Constants.URI); + + } + + /* + * Associates a MAC address to virtual network. + */ + public boolean associateMacToNetwork(long networkId, String macAddress) throws BrocadeVcsApiException { + + PortProfileGlobal portProfileGlobal = new PortProfileGlobal(); + PortProfile portProfile = new PortProfile(); + portProfile.setName(Constants.PORT_PROFILE_NAME_PREFIX + networkId); + Static staticObj = new Static(); + staticObj.setMacAddress(macAddress); + portProfile.setStatic(staticObj); + portProfileGlobal.setPortProfile(portProfile); + + //associates a mac address to a port-profile + return executeUpdateObject(portProfileGlobal, Constants.URI); + } + + /* + * Disassociates a MAC address from virtual network. + */ + public boolean disassociateMacFromNetwork(long networkId, String macAddress) throws BrocadeVcsApiException { + + PortProfileGlobal portProfileGlobal = new PortProfileGlobal(); + PortProfile portProfile = new PortProfile(); + portProfile.setName(Constants.PORT_PROFILE_NAME_PREFIX + networkId); + Static staticObj = new Static(); + staticObj.setOperation("delete"); + staticObj.setMacAddress(macAddress); + portProfile.setStatic(staticObj); + portProfileGlobal.setPortProfile(portProfile); + + //associates a mac address to a port-profile + return executeUpdateObject(portProfileGlobal, Constants.URI); + } + + /* + * Deletes a new virtual network. + */ + public boolean deleteNetwork(int vlanId, long networkId) throws BrocadeVcsApiException { + + if (deactivatePortProfile(networkId)) { + + if (deletePortProfile(networkId)) { + return deleteInterfaceVlan(vlanId); + } + } + return false; + } + + /* + * Deletes a vlan interface. + */ + private boolean deleteInterfaceVlan(int vlanId) throws BrocadeVcsApiException { + InterfaceVlan interfaceVlan = new InterfaceVlan(); + Interface interfaceObj = new Interface(); + Vlan vlan = new Vlan(); + vlan.setOperation("delete"); + vlan.setName(vlanId); + interfaceObj.setVlan(vlan); + interfaceVlan.setInterface(interfaceObj); + + return executeUpdateObject(interfaceVlan, Constants.URI); + + } + + /* + * Deactivates a port-profile. + */ + private boolean deactivatePortProfile(long networkId) throws BrocadeVcsApiException { + PortProfileGlobal portProfileGlobal = new PortProfileGlobal(); + PortProfile portProfile = new PortProfile(); + portProfile.setName(Constants.PORT_PROFILE_NAME_PREFIX + networkId); + Activate activate = new Activate(); + activate.setOperation("delete"); + portProfile.setActivate(activate); + portProfileGlobal.setPortProfile(portProfile); + + //activate port-profile + return executeUpdateObject(portProfileGlobal, Constants.URI); + } + + /* + * Deletes AMPP port-profile. + */ + private boolean deletePortProfile(long networkId) throws BrocadeVcsApiException { + + PortProfile portProfile = new PortProfile(); + portProfile.setName(Constants.PORT_PROFILE_NAME_PREFIX + networkId); + portProfile.setOperation("delete"); + //deletes port-profile + return executeUpdateObject(portProfile, Constants.URI); + } + + protected boolean executeUpdateObject(T newObject, String uri) throws BrocadeVcsApiException { + + boolean result = true; + + if (_host == null || _host.isEmpty() || _adminuser == null || _adminuser.isEmpty() || _adminpass == null || _adminpass.isEmpty()) { + throw new BrocadeVcsApiException("Hostname/credentials are null or empty"); + } + + HttpPatch pm = (HttpPatch)createMethod("patch", uri); + pm.setHeader("Accept", "application/vnd.configuration.resource+xml"); + + pm.setEntity(new StringEntity(convertToString(newObject), ContentType.APPLICATION_XML)); + + HttpResponse response = executeMethod(pm); + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) { + String errorMessage = responseToErrorMessage(response); + pm.releaseConnection(); + s_logger.error("Failed to update object : " + errorMessage); + throw new BrocadeVcsApiException("Failed to update object : " + errorMessage); + } + + pm.releaseConnection(); + + return result; + } + + protected String convertToString(T object) throws BrocadeVcsApiException { + + final StringWriter stringWriter = new StringWriter(); + + try { + final JAXBContext context = JAXBContext.newInstance(object.getClass()); + final Marshaller marshaller = context.createMarshaller(); + + marshaller.marshal(object, stringWriter); + + } catch (JAXBException e) { + s_logger.error("Failed to convert object to string : " + e.getMessage()); + throw new BrocadeVcsApiException("Failed to convert object to string : " + e.getMessage()); + } + + String str = stringWriter.toString(); + s_logger.info(str); + + return str; + + } + + protected Output convertToXML(String object) throws BrocadeVcsApiException { + + Output output = null; + try { + JAXBContext context = JAXBContext.newInstance(Output.class); + + StringReader reader = new StringReader(object); + + final Unmarshaller unmarshaller = context.createUnmarshaller(); + Object result = unmarshaller.unmarshal(reader); + + if (result instanceof Output) { + output = (Output)result; + s_logger.info(output); + } + + } catch (JAXBException e) { + s_logger.error("Failed to convert string to object : " + e.getMessage()); + throw new BrocadeVcsApiException("Failed to convert string to object : " + e.getMessage()); + } + + return output; + + } + + protected boolean executeCreateObject(T newObject, String uri) throws BrocadeVcsApiException { + if (_host == null || _host.isEmpty() || _adminuser == null || _adminuser.isEmpty() || _adminpass == null || _adminpass.isEmpty()) { + throw new BrocadeVcsApiException("Hostname/credentials are null or empty"); + } + + boolean result = true; + HttpPost pm = (HttpPost)createMethod("post", uri); + pm.setHeader("Accept", "application/vnd.configuration.resource+xml"); + pm.setEntity(new StringEntity(convertToString(newObject), ContentType.APPLICATION_XML)); + + HttpResponse response = executeMethod(pm); + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { + String errorMessage = responseToErrorMessage(response); + pm.releaseConnection(); + s_logger.error("Failed to create object : " + errorMessage); + throw new BrocadeVcsApiException("Failed to create object : " + errorMessage); + } + + pm.releaseConnection(); + + return result; + } + + protected Output executeRetreiveStatus(String uri) throws BrocadeVcsApiException { + if (_host == null || _host.isEmpty() || _adminuser == null || _adminuser.isEmpty() || _adminpass == null || _adminpass.isEmpty()) { + throw new BrocadeVcsApiException("Hostname/credentials are null or empty"); + } + + BufferedReader br = null; + String readLine = null; + StringBuffer sb = null; + + HttpPost pm = (HttpPost)createMethod("post", uri); + pm.setHeader("Accept", "application/vnd.operational-state.resource+xml"); + pm.setEntity(new StringEntity("", ContentType.APPLICATION_XML)); + + HttpResponse response = executeMethod(pm); + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + String errorMessage = responseToErrorMessage(response); + pm.releaseConnection(); + s_logger.error("Failed to retreive status : " + errorMessage); + throw new BrocadeVcsApiException("Failed to retreive status : " + errorMessage); + } + + try { + br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), Charset.forName("UTF-8"))); + sb = new StringBuffer(); + + while (((readLine = br.readLine()) != null)) { + s_logger.debug(readLine); + sb.append(readLine); + + } + } catch (Exception e) { + s_logger.error("Failed to get object : " + e.getMessage()); + throw new BrocadeVcsApiException("Failed to get object : " + e.getMessage()); + } + + pm.releaseConnection(); + + return convertToXML(sb.toString()); + } + + protected void executeDeleteObject(String uri) throws BrocadeVcsApiException { + if (_host == null || _host.isEmpty() || _adminuser == null || _adminuser.isEmpty() || _adminpass == null || _adminpass.isEmpty()) { + throw new BrocadeVcsApiException("Hostname/credentials are null or empty"); + } + + HttpDelete dm = (HttpDelete)createMethod("delete", uri); + dm.setHeader("Accept", "application/vnd.configuration.resource+xml"); + + HttpResponse response = executeMethod(dm); + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) { + String errorMessage = responseToErrorMessage(response); + dm.releaseConnection(); + s_logger.error("Failed to delete object : " + errorMessage); + throw new BrocadeVcsApiException("Failed to delete object : " + errorMessage); + } + dm.releaseConnection(); + } + + protected HttpResponse executeMethod(HttpRequestBase method) throws BrocadeVcsApiException { + HttpResponse response = null; + try { + response = _client.execute(method); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + method.releaseConnection(); + response = _client.execute(method); + } + } catch (HttpException e) { + s_logger.error("HttpException caught while trying to connect to the Brocade Switch", e); + method.releaseConnection(); + throw new BrocadeVcsApiException("API call to Brocade Switch Failed", e); + } catch (IOException e) { + s_logger.error("IOException caught while trying to connect to the Brocade Switch", e); + method.releaseConnection(); + throw new BrocadeVcsApiException("API call to Brocade Switch Failed", e); + } + + return response; + } + + private String responseToErrorMessage(HttpResponse response) { + + if ("text/html".equals(response.getEntity().getContentType().getValue())) { + try { + + BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), Charset.forName("UTF-8"))); + + StringBuffer result = new StringBuffer(); + String line = ""; + while ((line = rd.readLine()) != null) { + result.append(line); + } + + return result.toString(); + } catch (IOException e) { + s_logger.debug("Error while loading response body", e); + } + } + return null; + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java new file mode 100644 index 0000000000..76f3079738 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java @@ -0,0 +1,36 @@ +// 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.brocade; + +public class BrocadeVcsApiException extends Exception { + + public BrocadeVcsApiException() { + } + + public BrocadeVcsApiException(String message) { + super(message); + } + + public BrocadeVcsApiException(Throwable cause) { + super(cause); + } + + public BrocadeVcsApiException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java new file mode 100644 index 0000000000..5a9fa0afda --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java @@ -0,0 +1,37 @@ +// 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.brocade; + +public class Constants { + public static final String PROTOCOL = "http"; + + public static final String URI = "/rest/config/running"; + + public static final String STATUS_URI = "/rest/operational-state/show-vcs"; + + public static final int PORT = 80; + + public static final String PORT_PROFILE_NAME_PREFIX = "cloudstack-profile-"; + + public static final String BROCADE_VCS_DEVICE_ID = "vcsdeviceid"; + public static final String BROCADE_VCS_DEVICE_NAME = "brocadedevicename"; + + public static final String EVENT_EXTERNAL_VCS_CONTROLLER_ADD = "PHYSICAL.VCSCONTROLLER.ADD"; + public static final String EVENT_EXTERNAL_VCS_CONTROLLER_DELETE = "PHYSICAL.VCSCONTROLLER.DELETE"; + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java new file mode 100644 index 0000000000..76e36a18f5 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java @@ -0,0 +1,35 @@ +// +// 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.dao; + +import java.util.List; + +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.utils.db.GenericDao; + +public interface BrocadeVcsDao extends GenericDao { + /** + * list all the brocade vcs devices added in to this physical network + * @param physicalNetworkId physical network Id + * @return list of BrocadevcsDeviceVO for this zone and pod. + */ + List listByPhysicalNetwork(final long physicalNetworkId); + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java new file mode 100644 index 0000000000..ec5691adf5 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java @@ -0,0 +1,53 @@ +// +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Component +@Local(value = BrocadeVcsDao.class) +public class BrocadeVcsDaoImpl extends GenericDaoBase implements BrocadeVcsDao { + + protected final SearchBuilder physicalNetworkIdSearch; + + public BrocadeVcsDaoImpl() { + physicalNetworkIdSearch = createSearchBuilder(); + physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), Op.EQ); + physicalNetworkIdSearch.done(); + } + + @Override + public List listByPhysicalNetwork(final long physicalNetworkId) { + SearchCriteria sc = physicalNetworkIdSearch.create(); + sc.setParameters("physicalNetworkId", physicalNetworkId); + return search(sc, null); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java new file mode 100644 index 0000000000..16d29860c8 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// 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.dao; + +import com.cloud.network.BrocadeVcsNetworkVlanMappingVO; +import com.cloud.utils.db.GenericDao; + +public interface BrocadeVcsNetworkVlanMappingDao extends GenericDao { + + /** + * find the mapping for a network + * @param networkId + * the network id + * @return BrocadeNetworkHostMapping for this network id or null if it does not + * exist + */ + public BrocadeVcsNetworkVlanMappingVO findByNetworkId(long networkId); +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java new file mode 100644 index 0000000000..88c52a6bb2 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java @@ -0,0 +1,49 @@ +// 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.dao; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.network.BrocadeVcsNetworkVlanMappingVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Component +@Local(value = BrocadeVcsNetworkVlanMappingDao.class) +public class BrocadeVcsNetworkVlanMappingDaoImpl extends GenericDaoBase implements BrocadeVcsNetworkVlanMappingDao { + + protected final SearchBuilder networkSearch; + + public BrocadeVcsNetworkVlanMappingDaoImpl() { + networkSearch = createSearchBuilder(); + networkSearch.and("network_id", networkSearch.entity().getNetworkId(), Op.EQ); + networkSearch.done(); + + } + + @Override + public BrocadeVcsNetworkVlanMappingVO findByNetworkId(long networkId) { + SearchCriteria sc = networkSearch.create(); + sc.setParameters("network_id", networkId); + return findOneBy(sc); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java new file mode 100644 index 0000000000..b551092300 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java @@ -0,0 +1,467 @@ +// 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.Collections; +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.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.StartupBrocadeVcsCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.api.ApiDBUtils; +import com.cloud.api.commands.AddBrocadeVcsDeviceCmd; +import com.cloud.api.commands.DeleteBrocadeVcsDeviceCmd; +import com.cloud.api.commands.ListBrocadeVcsDeviceNetworksCmd; +import com.cloud.api.commands.ListBrocadeVcsDevicesCmd; +import com.cloud.api.response.BrocadeVcsDeviceResponse; +import com.cloud.configuration.ConfigurationManager; +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.BrocadeVcsDeviceVO; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.Networks; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.dao.BrocadeVcsDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.resource.BrocadeVcsResource; +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.utils.component.AdapterBase; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicDao; + +@Component +@Local(value = {NetworkElement.class}) +public class BrocadeVcsElement extends AdapterBase implements NetworkElement, ResourceStateAdapter, BrocadeVcsElementService { + private static final Logger s_logger = Logger.getLogger(BrocadeVcsElement.class); + + private static final Map> capabilities = setCapabilities(); + + @Inject + NicDao _nicDao; + @Inject + ResourceManager _resourceMgr; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + protected BrocadeVcsDao _brocadeVcsDao; + @Inject + HostDetailsDao _hostDetailsDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + @Inject + NetworkDao _networkDao; + @Inject + NetworkOrchestrationService _networkManager; + @Inject + NetworkModel _networkModel; + @Inject + ConfigurationManager _configMgr; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + VlanDao _vlanDao; + @Inject + IpAddressManager _ipAddrMgr; + + @Override + public Map> getCapabilities() { + return capabilities; + } + + @Override + public Provider getProvider() { + return Network.Provider.BrocadeVcs; + } + + protected boolean canHandle(Network network, Service service) { + s_logger.debug("Checking if BrocadeVcsElement can handle service " + service.getName() + " on network " + network.getDisplayText()); + if (network.getBroadcastDomainType() != BroadcastDomainType.Vcs) { + return false; + } + + if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) { + s_logger.debug("BrocadeVcsElement is not a provider for network " + network.getDisplayText()); + return false; + } + + if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, Network.Provider.BrocadeVcs)) { + s_logger.debug("BrocadeVcsElement can't provide the " + service.getName() + " service on network " + network.getDisplayText()); + return false; + } + + return true; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); + return true; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + s_logger.debug("entering BrocadeVcsElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")"); + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + return true; + } + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + // Nothing to do here. + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return true; + } + + @Override + public boolean verifyServicesCombination(Set services) { + + if (!services.contains(Service.Connectivity)) { + s_logger.warn("Unable to provide services without Connectivity service enabled for this element"); + return false; + } + return true; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // L2 Support + capabilities.put(Service.Connectivity, null); + + return capabilities; + } + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + cmdList.add(AddBrocadeVcsDeviceCmd.class); + cmdList.add(DeleteBrocadeVcsDeviceCmd.class); + cmdList.add(ListBrocadeVcsDeviceNetworksCmd.class); + cmdList.add(ListBrocadeVcsDevicesCmd.class); + return cmdList; + } + + @Override + @DB + public BrocadeVcsDeviceVO addBrocadeVcsDevice(AddBrocadeVcsDeviceCmd cmd) { + ServerResource resource = new BrocadeVcsResource(); + final String deviceName = Network.Provider.BrocadeVcs.getName(); + NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName); + if (networkDevice == null) { + throw new CloudRuntimeException("No network device found for " + deviceName); + } + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); + } + long zoneId = physicalNetwork.getDataCenterId(); + + final 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"); + } + + Map params = new HashMap(); + params.put("guid", UUID.randomUUID().toString()); + params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); + params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); + params.put("name", "Brocade VCS - " + cmd.getHost()); + params.put("ip", cmd.getHost()); + params.put("adminuser", cmd.getUsername()); + params.put("adminpass", cmd.getPassword()); + + Map hostdetails = new HashMap(); + hostdetails.putAll(params); + + try { + resource.configure(cmd.getHost(), hostdetails); + + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); + if (host != null) { + return Transaction.execute(new TransactionCallback() { + @Override + public BrocadeVcsDeviceVO doInTransaction(TransactionStatus status) { + BrocadeVcsDeviceVO brocadeVcsDevice = new BrocadeVcsDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); + _brocadeVcsDao.persist(brocadeVcsDevice); + + DetailVO detail = new DetailVO(host.getId(), "brocadevcsdeviceid", String.valueOf(brocadeVcsDevice.getId())); + _hostDetailsDao.persist(detail); + + return brocadeVcsDevice; + } + }); + } else { + throw new CloudRuntimeException("Failed to add Brocade VCS Switch due to internal error."); + } + } catch (ConfigurationException e) { + throw new CloudRuntimeException(e.getMessage()); + } + + } + + @Override + public BrocadeVcsDeviceResponse createBrocadeVcsDeviceResponse(BrocadeVcsDeviceVO brocadeVcsDeviceVO) { + HostVO brocadeVcsHost = _hostDao.findById(brocadeVcsDeviceVO.getHostId()); + _hostDao.loadDetails(brocadeVcsHost); + + BrocadeVcsDeviceResponse response = new BrocadeVcsDeviceResponse(); + response.setDeviceName(brocadeVcsDeviceVO.getDeviceName()); + PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(brocadeVcsDeviceVO.getPhysicalNetworkId()); + if (pnw != null) { + response.setPhysicalNetworkId(pnw.getUuid()); + } + response.setId(brocadeVcsDeviceVO.getUuid()); + response.setProviderName(brocadeVcsDeviceVO.getProviderName()); + response.setHostName(brocadeVcsHost.getDetail("ip")); + response.setObjectName("brocadevcsdevice"); + return response; + } + + @Override + public boolean deleteBrocadeVcsDevice(DeleteBrocadeVcsDeviceCmd cmd) { + Long brocadeDeviceId = cmd.getBrocadeVcsDeviceId(); + BrocadeVcsDeviceVO brocadeVcsDevice = _brocadeVcsDao.findById(brocadeDeviceId); + if (brocadeVcsDevice == null) { + throw new InvalidParameterValueException("Could not find a brocade vcs switch with id " + brocadeVcsDevice); + } + + // Find the physical network we work for + Long physicalNetworkId = brocadeVcsDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork != null) { + // Lets see if there are networks that use us + // Find the brocade networks on this physical network + List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); + if (networkList != null) { + // Networks with broadcast type vcs are ours + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Vcs) { + if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) { + throw new CloudRuntimeException("This Brocade VCS Switch can not be deleted as there are one or more logical networks provisioned by cloudstack."); + } + } + } + } + } + + HostVO brocadeHost = _hostDao.findById(brocadeVcsDevice.getHostId()); + Long hostId = brocadeHost.getId(); + + brocadeHost.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, brocadeHost); + _resourceMgr.deleteHost(hostId, false, false); + + _brocadeVcsDao.remove(brocadeDeviceId); + return true; + } + + @Override + public List listBrocadeVcsDevices(ListBrocadeVcsDevicesCmd cmd) { + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + Long brocadeVcsDeviceId = cmd.getBrocadeVcsDeviceId(); + List responseList = new ArrayList(); + + if (physicalNetworkId == null && brocadeVcsDeviceId == null) { + throw new InvalidParameterValueException("Either physical network Id or brocade vcs switch Id must be specified"); + } + + if (brocadeVcsDeviceId != null) { + BrocadeVcsDeviceVO brocadeVcsDevice = _brocadeVcsDao.findById(brocadeVcsDeviceId); + if (brocadeVcsDevice == null) { + throw new InvalidParameterValueException("Could not find Brocade VCS Switch with id: " + brocadeVcsDeviceId); + } + responseList.add(brocadeVcsDevice); + } else { + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId); + } + responseList = _brocadeVcsDao.listByPhysicalNetwork(physicalNetworkId); + } + + return responseList; + } + + @Override + public List listBrocadeVcsDeviceNetworks(ListBrocadeVcsDeviceNetworksCmd cmd) { + Long brocadeDeviceId = cmd.getBrocadeVcsDeviceId(); + BrocadeVcsDeviceVO brocadeVcsDevice = _brocadeVcsDao.findById(brocadeDeviceId); + if (brocadeVcsDevice == null) { + throw new InvalidParameterValueException("Could not find a Brocade VCS Switch with id " + brocadeDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = brocadeVcsDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + // No such physical network, so no provisioned networks + return Collections.emptyList(); + } + + // Find the brocade networks on this physical network + List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); + if (networkList == null) { + return Collections.emptyList(); + } + + // Networks with broadcast type vcs are ours + List responseList = new ArrayList(); + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Vcs) { + responseList.add(network); + } + } + + return responseList; + } + + @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 details, List hostTags) { + if (!(startup[0] instanceof StartupBrocadeVcsCommand)) { + return null; + } + host.setType(Host.Type.L2Networking); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (!(host.getType() == Host.Type.L2Networking)) { + return null; + } + return new DeleteHostAnswer(true); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java new file mode 100644 index 0000000000..b8db60cc92 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java @@ -0,0 +1,45 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.network.element; + +import java.util.List; + +import com.cloud.api.commands.AddBrocadeVcsDeviceCmd; +import com.cloud.api.commands.DeleteBrocadeVcsDeviceCmd; +import com.cloud.api.commands.ListBrocadeVcsDeviceNetworksCmd; +import com.cloud.api.commands.ListBrocadeVcsDevicesCmd; +import com.cloud.api.response.BrocadeVcsDeviceResponse; +import com.cloud.network.Network; +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.utils.component.PluggableService; + +public interface BrocadeVcsElementService extends PluggableService { + + public BrocadeVcsDeviceVO addBrocadeVcsDevice(AddBrocadeVcsDeviceCmd cmd); + + public BrocadeVcsDeviceResponse createBrocadeVcsDeviceResponse(BrocadeVcsDeviceVO brocadeDeviceVO); + + boolean deleteBrocadeVcsDevice(DeleteBrocadeVcsDeviceCmd cmd); + + List listBrocadeVcsDeviceNetworks(ListBrocadeVcsDeviceNetworksCmd cmd); + + List listBrocadeVcsDevices(ListBrocadeVcsDevicesCmd cmd); + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java new file mode 100644 index 0000000000..92bf113f9a --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java @@ -0,0 +1,267 @@ +// 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.guru; + +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.AssociateMacToNetworkAnswer; +import com.cloud.agent.api.AssociateMacToNetworkCommand; +import com.cloud.agent.api.CreateNetworkAnswer; +import com.cloud.agent.api.CreateNetworkCommand; +import com.cloud.agent.api.DeleteNetworkAnswer; +import com.cloud.agent.api.DeleteNetworkCommand; +import com.cloud.agent.api.DisassociateMacFromNetworkAnswer; +import com.cloud.agent.api.DisassociateMacFromNetworkCommand; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.network.BrocadeVcsNetworkVlanMappingVO; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkProfile; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetwork.IsolationMethod; +import com.cloud.network.dao.BrocadeVcsDao; +import com.cloud.network.dao.BrocadeVcsNetworkVlanMappingDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.user.Account; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value = NetworkGuru.class) +public class BrocadeVcsGuestNetworkGuru extends GuestNetworkGuru { + private static final Logger s_logger = Logger.getLogger(BrocadeVcsGuestNetworkGuru.class); + + @Inject + NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; + @Inject + ResourceManager _resourceMgr; + @Inject + AgentManager _agentMgr; + @Inject + protected BrocadeVcsDao _brocadeVcsDao; + @Inject + protected BrocadeVcsNetworkVlanMappingDao _brocadeVcsNetworkVlanDao; + @Inject + PhysicalNetworkServiceProviderDao _pNSPDao; + @Inject + HostDao _hostDao; + + public BrocadeVcsGuestNetworkGuru() { + super(); + _isolationMethods = new IsolationMethod[] {IsolationMethod.VCS}; + } + + @Override + protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { + // This guru handles only Guest Isolated network that supports L2 connectivity service + if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated + && isMyIsolationMethod(physicalNetwork) && _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)) { + return true; + } else { + s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); + return false; + } + } + + @Override + public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { + // Check of the isolation type of the related physical network is VLAN + PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId()); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + if (!canHandle(offering, dc.getNetworkType(), physnet)) { + s_logger.debug("Refusing to design this network"); + return null; + } + s_logger.debug("Physical isolation type is VCS, asking GuestNetworkGuru to design this network"); + NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner); + if (networkObject == null) { + return null; + } + // Override the broadcast domain type + networkObject.setBroadcastDomainType(BroadcastDomainType.Vcs); + networkObject.setState(State.Allocated); + + return networkObject; + } + + @Override + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException { + assert (network.getState() == State.Implementing) : "Why are we implementing " + network; + + Network implemented = super.implement(network, offering, dest, context); + + int vlanTag = Integer.parseInt(BroadcastDomainType.getValue(implemented.getBroadcastUri())); + + //get physical network id + Long physicalNetworkId = network.getPhysicalNetworkId(); + + List devices = _brocadeVcsDao.listByPhysicalNetwork(physicalNetworkId); + if (devices.isEmpty()) { + s_logger.error("No Brocade VCS Switch on physical network " + physicalNetworkId); + return null; + } + + for (BrocadeVcsDeviceVO brocadeVcsDevice : devices) { + HostVO brocadeVcsHost = _hostDao.findById(brocadeVcsDevice.getHostId()); + + // create createNetworkCmd instance and agentMgr execute it. + CreateNetworkCommand cmd = new CreateNetworkCommand(vlanTag, network.getId(), context.getDomain().getName() + "-" + context.getAccount().getAccountName()); + CreateNetworkAnswer answer = (CreateNetworkAnswer)_agentMgr.easySend(brocadeVcsHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("CreateNetworkCommand failed"); + s_logger.error("Unable to create network " + network.getId()); + return null; + } + + } + + // Persist the network-vlan mapping from db + BrocadeVcsNetworkVlanMappingVO brocadeVcsNetworkVlanMapping = new BrocadeVcsNetworkVlanMappingVO(network.getId(), vlanTag); + _brocadeVcsNetworkVlanDao.persist(brocadeVcsNetworkVlanMapping); + + return implemented; + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + super.reserve(nic, network, vm, dest, context); + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + + String interfaceMac = nic.getMacAddress(); + + List devices = _brocadeVcsDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No Brocade VCS Switch on physical network " + network.getPhysicalNetworkId()); + return; + } + for (BrocadeVcsDeviceVO brocadeVcsDevice : devices) { + HostVO brocadeVcsHost = _hostDao.findById(brocadeVcsDevice.getHostId()); + + // create AssociateMacToNetworkCmd instance and agentMgr execute it. + AssociateMacToNetworkCommand cmd = new AssociateMacToNetworkCommand(network.getId(), interfaceMac, context.getDomain().getName() + "-" + + context.getAccount().getAccountName()); + AssociateMacToNetworkAnswer answer = (AssociateMacToNetworkAnswer)_agentMgr.easySend(brocadeVcsHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("AssociateMacToNetworkCommand failed"); + throw new InsufficientVirtualNetworkCapacityException("Unable to associate mac " + interfaceMac + " to network " + network.getId(), DataCenter.class, dc.getId()); + } + } + + } + + @Override + public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + + String interfaceMac = nic.getMacAddress(); + + List devices = _brocadeVcsDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No Brocade VCS Switch on physical network " + network.getPhysicalNetworkId()); + return; + } + for (BrocadeVcsDeviceVO brocadeVcsDevice : devices) { + HostVO brocadeVcsHost = _hostDao.findById(brocadeVcsDevice.getHostId()); + + // create DisassociateMacFromNetworkCmd instance and agentMgr execute it. + DisassociateMacFromNetworkCommand cmd = new DisassociateMacFromNetworkCommand(network.getId(), interfaceMac); + DisassociateMacFromNetworkAnswer answer = (DisassociateMacFromNetworkAnswer)_agentMgr.easySend(brocadeVcsHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("DisassociateMacFromNetworkCommand failed"); + s_logger.error("Unable to disassociate mac " + interfaceMac + " from network " + network.getId()); + return; + } + } + super.deallocate(network, nic, vm); + } + + @Override + public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { + return super.release(nic, vm, reservationId); + } + + @Override + public void shutdown(NetworkProfile profile, NetworkOffering offering) { + + super.shutdown(profile, offering); + } + + @Override + public boolean trash(Network network, NetworkOffering offering) { + + int vlanTag = 0; + // Get the network-vlan mapping from db + BrocadeVcsNetworkVlanMappingVO brocadeVcsNetworkVlanMapping = _brocadeVcsNetworkVlanDao.findByNetworkId(network.getId()); + + if (brocadeVcsNetworkVlanMapping != null) { + vlanTag = brocadeVcsNetworkVlanMapping.getVlanId(); + } else { + s_logger.error("Not able to find vlanId for network " + network.getId()); + return false; + } + + List devices = _brocadeVcsDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No Brocade VCS Switch on physical network " + network.getPhysicalNetworkId()); + return false; + } + for (BrocadeVcsDeviceVO brocadeVcsDevice : devices) { + HostVO brocadeVcsHost = _hostDao.findById(brocadeVcsDevice.getHostId()); + + // create deleteNetworkCmd instance and agentMgr execute it. + DeleteNetworkCommand cmd = new DeleteNetworkCommand(vlanTag, network.getId()); + DeleteNetworkAnswer answer = (DeleteNetworkAnswer)_agentMgr.easySend(brocadeVcsHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("DeleteNetworkCommand failed"); + s_logger.error("Unable to delete network " + network.getId()); + return false; + } + } + + // Remove the network-vlan mapping from db + _brocadeVcsNetworkVlanDao.remove(brocadeVcsNetworkVlanMapping.getId()); + return super.trash(network, offering); + } + +} diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java b/plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java new file mode 100644 index 0000000000..0a323992b8 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java @@ -0,0 +1,310 @@ +// 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.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.AssociateMacToNetworkAnswer; +import com.cloud.agent.api.AssociateMacToNetworkCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateNetworkAnswer; +import com.cloud.agent.api.CreateNetworkCommand; +import com.cloud.agent.api.DeleteNetworkAnswer; +import com.cloud.agent.api.DeleteNetworkCommand; +import com.cloud.agent.api.DisassociateMacFromNetworkAnswer; +import com.cloud.agent.api.DisassociateMacFromNetworkCommand; +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.StartupBrocadeVcsCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.network.brocade.BrocadeVcsApi; +import com.cloud.network.brocade.BrocadeVcsApiException; +import com.cloud.network.schema.showvcs.Output; +import com.cloud.network.schema.showvcs.VcsNodeInfo; +import com.cloud.resource.ServerResource; + +public class BrocadeVcsResource implements ServerResource { + private static final Logger s_logger = Logger.getLogger(BrocadeVcsResource.class); + + private String _name; + private String _guid; + private String _zoneId; + private int _numRetries; + + private BrocadeVcsApi _brocadeVcsApi; + + protected BrocadeVcsApi createBrocadeVcsApi(String ip, String username, String password) { + + return new BrocadeVcsApi(ip, username, password); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + + _name = (String)params.get("name"); + if (_name == null) { + throw new ConfigurationException("Unable to find name"); + } + + _guid = (String)params.get("guid"); + if (_guid == null) { + throw new ConfigurationException("Unable to find the guid"); + } + + _zoneId = (String)params.get("zoneId"); + if (_zoneId == null) { + throw new ConfigurationException("Unable to find zone"); + } + + _numRetries = 2; + + String ip = (String)params.get("ip"); + if (ip == null) { + throw new ConfigurationException("Unable to find IP"); + } + + String adminuser = (String)params.get("adminuser"); + if (adminuser == null) { + throw new ConfigurationException("Unable to find admin username"); + } + + String adminpass = (String)params.get("adminpass"); + if (adminpass == null) { + throw new ConfigurationException("Unable to find admin password"); + } + + _brocadeVcsApi = createBrocadeVcsApi(ip, adminuser, adminpass); + + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public Type getType() { + return Host.Type.L2Networking; + } + + @Override + public StartupCommand[] initialize() { + StartupBrocadeVcsCommand sc = new StartupBrocadeVcsCommand(); + sc.setGuid(_guid); + sc.setName(_name); + sc.setDataCenter(_zoneId); + sc.setPrivateIpAddress(""); + sc.setStorageIpAddress(""); + sc.setVersion(BrocadeVcsResource.class.getPackage().getImplementationVersion()); + return new StartupCommand[] {sc}; + } + + @Override + public PingCommand getCurrentStatus(long id) { + + Output output; + try { + output = _brocadeVcsApi.getSwitchStatus(); + } catch (BrocadeVcsApiException e) { + s_logger.error("getSwitchStatus failed", e); + return null; + } + + List vcsNodes = output.getVcsNodes().getVcsNodeInfo(); + if (vcsNodes != null && !vcsNodes.isEmpty()) { + for (VcsNodeInfo vcsNodeInfo : vcsNodes) { + if (!"Online".equals(vcsNodeInfo.getNodeState())) { + s_logger.error("Brocade Switch is not ready: " + id); + return null; + } + } + } + return new PingCommand(Host.Type.L2Networking, id); + + } + + @Override + public Answer executeRequest(Command cmd) { + return executeRequest(cmd, _numRetries); + } + + public Answer executeRequest(Command cmd, int numRetries) { + if (cmd instanceof ReadyCommand) { + return executeRequest((ReadyCommand)cmd); + } else if (cmd instanceof MaintainCommand) { + return executeRequest((MaintainCommand)cmd); + } else if (cmd instanceof CreateNetworkCommand) { + return executeRequest((CreateNetworkCommand)cmd, numRetries); + } else if (cmd instanceof AssociateMacToNetworkCommand) { + return executeRequest((AssociateMacToNetworkCommand)cmd, numRetries); + } else if (cmd instanceof DisassociateMacFromNetworkCommand) { + return executeRequest((DisassociateMacFromNetworkCommand)cmd, numRetries); + } else if (cmd instanceof DeleteNetworkCommand) { + return executeRequest((DeleteNetworkCommand)cmd, numRetries); + } + s_logger.debug("Received unsupported command " + cmd.toString()); + return Answer.createUnsupportedCommandAnswer(cmd); + } + + @Override + public void disconnected() { + } + + @Override + public IAgentControl getAgentControl() { + return null; + } + + @Override + public void setAgentControl(IAgentControl agentControl) { + } + + private Answer executeRequest(CreateNetworkCommand cmd, int numRetries) { + + try { + boolean result = _brocadeVcsApi.createNetwork(cmd.getVlanId(), cmd.getNetworkId()); + return new CreateNetworkAnswer(cmd, result, "Port Profile " + cmd.getNetworkId() + " created"); + } catch (BrocadeVcsApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } else { + return new CreateNetworkAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(AssociateMacToNetworkCommand cmd, int numRetries) { + + try { + + String mac = macReformat64To32(cmd.getInterfaceMac()); + boolean result = _brocadeVcsApi.associateMacToNetwork(cmd.getNetworkId(), mac); + return new AssociateMacToNetworkAnswer(cmd, result, "Association of mac " + cmd.getInterfaceMac() + " to network " + cmd.getNetworkId() + " done"); + } catch (BrocadeVcsApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } else { + return new AssociateMacToNetworkAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(DisassociateMacFromNetworkCommand cmd, int numRetries) { + + try { + + String mac = macReformat64To32(cmd.getInterfaceMac()); + boolean result = _brocadeVcsApi.disassociateMacFromNetwork(cmd.getNetworkId(), mac); + return new DisassociateMacFromNetworkAnswer(cmd, result, "Disassociation of mac " + cmd.getInterfaceMac() + " from network " + cmd.getNetworkId() + " done"); + } catch (BrocadeVcsApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } else { + return new DisassociateMacFromNetworkAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(DeleteNetworkCommand cmd, int numRetries) { + + try { + boolean result = _brocadeVcsApi.deleteNetwork(cmd.getVlanId(), cmd.getNetworkId()); + return new DeleteNetworkAnswer(cmd, result, "Port Profile " + cmd.getNetworkId() + " deleted"); + } catch (BrocadeVcsApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } else { + return new DeleteNetworkAnswer(cmd, e); + } + } + + } + + private String macReformat64To32(String interfaceMac) { + String mac = interfaceMac.replace(":", ""); + mac = mac.substring(0, 4) + "." + mac.substring(4, 8) + "." + mac.subSequence(8, 12); + return mac; + + } + + private Answer executeRequest(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + private Answer executeRequest(MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } + + private Answer retry(Command cmd, int numRetries) { + s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries); + return executeRequest(cmd, numRetries); + } + + @Override + public void setName(String name) { + + } + + @Override + public void setConfigParams(Map params) { + + } + + @Override + public Map getConfigParams() { + + return null; + } + + @Override + public int getRunLevel() { + + return 0; + } + + @Override + public void setRunLevel(int level) { + + } + +} diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java b/plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java new file mode 100644 index 0000000000..4223d4cc7b --- /dev/null +++ b/plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java @@ -0,0 +1,185 @@ +// +// 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.brocade; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.io.IOException; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; + +import com.cloud.network.schema.showvcs.Output; + +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.junit.Before; +import org.junit.Test; + +public class BrocadeVcsApiTest { + protected static final long NETWORK_ID = 42L; + protected static final int VLAN_ID = 14; + private static final String MAC_ADDRESS_32 = "0050.56bf.0002"; + protected static final String OUTPUT_XML_RESPONSE = " Online "; + BrocadeVcsApi api; + DefaultHttpClient client = mock(DefaultHttpClient.class); + HttpRequestBase method; + HttpResponse response; + HttpResponse postResponse; + String type; + String uri; + + @Before + public void setUp() { + api = new BrocadeVcsApi("localhost", "admin", "password") { + + @Override + public HttpRequestBase createMethod(final String newType, final String newUri) { + type = newType; + uri = newUri; + return method; + } + + @Override + public HttpResponse executeMethod(HttpRequestBase method) throws BrocadeVcsApiException { + return response; + } + + @Override + protected boolean executeCreateObject(T newObject, String uri) throws BrocadeVcsApiException { + + return true; + } + }; + + api._client = client; + + } + + @Test + public void testGetSwitchStatus() throws BrocadeVcsApiException, IOException { + // Prepare + + method = mock(HttpPost.class); + + response = mock(HttpResponse.class); + final StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(response.getStatusLine()).thenReturn(statusLine); + when(response.getEntity()).thenReturn(new StringEntity(OUTPUT_XML_RESPONSE)); + + // Execute + Output result = api.getSwitchStatus(); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong URI for get SwitchStatus REST service", Constants.STATUS_URI, uri); + assertEquals("Wrong HTTP method for get SwitchStatus REST service", "post", type); + assertEquals("Wrong state for get SwitchStatus REST service", "Online", result.getVcsNodes().getVcsNodeInfo().get(0).getNodeState()); + } + + @Test + public void testCreateNetwork() throws BrocadeVcsApiException, IOException { + // Prepare + + method = mock(HttpPatch.class); + + response = mock(HttpResponse.class); + final StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + when(response.getStatusLine()).thenReturn(statusLine); + + // Execute + api.createNetwork(VLAN_ID, NETWORK_ID); + + // Assert + verify(method, times(6)).releaseConnection(); + assertEquals("Wrong URI for Network creation REST service", Constants.URI, uri); + assertEquals("Wrong HTTP method for Network creation REST service", "patch", type); + } + + @Test + public void testDeleteNetwork() throws BrocadeVcsApiException, IOException { + // Prepare + + method = mock(HttpPatch.class); + + response = mock(HttpResponse.class); + final StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + when(response.getStatusLine()).thenReturn(statusLine); + + // Execute + api.deleteNetwork(VLAN_ID, NETWORK_ID); + + // Assert + verify(method, times(3)).releaseConnection(); + assertEquals("Wrong URI for Network creation REST service", Constants.URI, uri); + assertEquals("Wrong HTTP method for Network creation REST service", "patch", type); + } + + @Test + public void testAssociateMacToNetwork() throws BrocadeVcsApiException, IOException { + // Prepare + + method = mock(HttpPatch.class); + + response = mock(HttpResponse.class); + final StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + when(response.getStatusLine()).thenReturn(statusLine); + + // Execute + api.associateMacToNetwork(NETWORK_ID, MAC_ADDRESS_32); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong URI for Network creation REST service", Constants.URI, uri); + assertEquals("Wrong HTTP method for Network creation REST service", "patch", type); + } + + @Test + public void testDisassociateMacFromNetwork() throws BrocadeVcsApiException, IOException { + // Prepare + + method = mock(HttpPatch.class); + + response = mock(HttpResponse.class); + final StatusLine statusLine = mock(StatusLine.class); + when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + when(response.getStatusLine()).thenReturn(statusLine); + + // Execute + api.disassociateMacFromNetwork(NETWORK_ID, MAC_ADDRESS_32); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong URI for Network creation REST service", Constants.URI, uri); + assertEquals("Wrong HTTP method for Network creation REST service", "patch", type); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java b/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java new file mode 100644 index 0000000000..bf30bd01fc --- /dev/null +++ b/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java @@ -0,0 +1,590 @@ +// +// 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.guru; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.AssociateMacToNetworkAnswer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateNetworkAnswer; +import com.cloud.agent.api.DeleteNetworkAnswer; +import com.cloud.agent.api.DisassociateMacFromNetworkAnswer; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.BrocadeVcsDeviceVO; +import com.cloud.network.BrocadeVcsNetworkVlanMappingVO; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.BrocadeVcsDao; +import com.cloud.network.dao.BrocadeVcsNetworkVlanMappingDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.vm.Nic.ReservationStrategy; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; + +public class BrocadeVcsGuestNetworkGuruTest { + private static final long NETWORK_ID = 42L; + PhysicalNetworkDao physnetdao = mock(PhysicalNetworkDao.class); + BrocadeVcsDao vcsdao = mock(BrocadeVcsDao.class); + BrocadeVcsNetworkVlanMappingDao vcsmapdao = mock(BrocadeVcsNetworkVlanMappingDao.class); + DataCenterDao dcdao = mock(DataCenterDao.class); + NetworkOfferingServiceMapDao nosd = mock(NetworkOfferingServiceMapDao.class); + AgentManager agentmgr = mock(AgentManager.class); + NetworkOrchestrationService netmgr = mock(NetworkOrchestrationService.class); + NetworkModel netmodel = mock(NetworkModel.class); + + HostDao hostdao = mock(HostDao.class); + NetworkDao netdao = mock(NetworkDao.class); + GuestNetworkGuru guestGuru = mock(GuestNetworkGuru.class); + BrocadeVcsGuestNetworkGuru guru; + + @Before + public void setUp() { + + guru = new BrocadeVcsGuestNetworkGuru(); + ((GuestNetworkGuru)guru)._physicalNetworkDao = physnetdao; + guru._brocadeVcsDao = vcsdao; + guru._brocadeVcsNetworkVlanDao = vcsmapdao; + guru._hostDao = hostdao; + guru._ntwkOfferingSrvcDao = nosd; + guru._dcDao = dcdao; + guru._agentMgr = agentmgr; + + final DataCenterVO dc = mock(DataCenterVO.class); + when(dc.getNetworkType()).thenReturn(NetworkType.Advanced); + when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24"); + + when(dcdao.findById((Long)any())).thenReturn(dc); + } + + @Test + public void testCanHandle() { + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VCS"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported TrafficType != Guest + when(offering.getTrafficType()).thenReturn(TrafficType.Management); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: GuestType Shared + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: Basic networking + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true); + + // Not supported: IsolationMethod != VCS + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + } + + @Test + public void testDesign() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VCS"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork != null); + assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vcs); + } + + @Test + public void testDesignNoIsolationMethodVCS() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testDesignNoConnectivityInOffering() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VCS"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(false); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testImplement() throws InsufficientVirtualNetworkCapacityException, URISyntaxException { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VCS"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + mock(DeploymentPlan.class); + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("vlan://14")); + + final DeployDestination dest = mock(DeployDestination.class); + + final DataCenter dc = mock(DataCenter.class); + when(dest.getDataCenter()).thenReturn(dc); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + List devices = new ArrayList(); + devices.add(brocadeDevice); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext res = mock(ReservationContext.class); + when(res.getDomain()).thenReturn(dom); + when(res.getAccount()).thenReturn(acc); + + when(guestGuru.implement(network, offering, dest, res)).thenReturn(network); + + final CreateNetworkAnswer answer = mock(CreateNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + final Network implementednetwork = guru.implement(network, offering, dest, res); + assertTrue(implementednetwork != null); + verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testImplementFail() throws InsufficientVirtualNetworkCapacityException, URISyntaxException { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VCS"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(false); + + mock(DeploymentPlan.class); + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("vlan://14")); + + final DeployDestination dest = mock(DeployDestination.class); + + final DataCenter dc = mock(DataCenter.class); + when(dest.getDataCenter()).thenReturn(dc); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = mock(List.class); + when(devices.isEmpty()).thenReturn(true); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext res = mock(ReservationContext.class); + when(res.getDomain()).thenReturn(dom); + when(res.getAccount()).thenReturn(acc); + + when(guestGuru.implement(network, offering, dest, res)).thenReturn(network); + + final CreateNetworkAnswer answer = mock(CreateNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + final Network implementednetwork = guru.implement(network, offering, dest, res); + assertTrue(implementednetwork == null); + verify(agentmgr, times(0)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testReserve() throws InsufficientVirtualNetworkCapacityException, URISyntaxException, InsufficientAddressCapacityException { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("vlan://14")); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NicProfile nic = mock(NicProfile.class); + when(nic.getMacAddress()).thenReturn("macaddress"); + when(nic.getReservationStrategy()).thenReturn(ReservationStrategy.Start); + + final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class); + + final DeployDestination dest = mock(DeployDestination.class); + + final DataCenterVO dc = mock(DataCenterVO.class); + when(dest.getDataCenter()).thenReturn(dc); + when(dcdao.findById((long)anyInt())).thenReturn(dc); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + List devices = new ArrayList(); + devices.add(brocadeDevice); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext res = mock(ReservationContext.class); + when(res.getDomain()).thenReturn(dom); + when(res.getAccount()).thenReturn(acc); + + final AssociateMacToNetworkAnswer answer = mock(AssociateMacToNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.reserve(nic, network, vmProfile, dest, res); + verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testReserveFail() throws InsufficientVirtualNetworkCapacityException, URISyntaxException, InsufficientAddressCapacityException { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("vlan://14")); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NicProfile nic = mock(NicProfile.class); + when(nic.getMacAddress()).thenReturn("macaddress"); + when(nic.getReservationStrategy()).thenReturn(ReservationStrategy.Start); + + final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class); + + final DeployDestination dest = mock(DeployDestination.class); + + final DataCenterVO dc = mock(DataCenterVO.class); + when(dest.getDataCenter()).thenReturn(dc); + when(dcdao.findById((long)anyInt())).thenReturn(dc); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = mock(List.class); + when(devices.isEmpty()).thenReturn(true); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext res = mock(ReservationContext.class); + when(res.getDomain()).thenReturn(dom); + when(res.getAccount()).thenReturn(acc); + + final AssociateMacToNetworkAnswer answer = mock(AssociateMacToNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.reserve(nic, network, vmProfile, dest, res); + verify(agentmgr, times(0)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testDeallocate() { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NicProfile nic = mock(NicProfile.class); + when(nic.getMacAddress()).thenReturn("macaddress"); + when(nic.getReservationStrategy()).thenReturn(ReservationStrategy.Start); + + final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = new ArrayList(); + devices.add(brocadeDevice); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final DisassociateMacFromNetworkAnswer answer = mock(DisassociateMacFromNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.deallocate(network, nic, vmProfile); + verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testDeallocateFail() { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NicProfile nic = mock(NicProfile.class); + when(nic.getMacAddress()).thenReturn("macaddress"); + when(nic.getReservationStrategy()).thenReturn(ReservationStrategy.Start); + + final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = mock(List.class); + when(devices.isEmpty()).thenReturn(true); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final DisassociateMacFromNetworkAnswer answer = mock(DisassociateMacFromNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.deallocate(network, nic, vmProfile); + verify(agentmgr, times(0)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testTrash() { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsNetworkVlanMappingVO mapping = mock(BrocadeVcsNetworkVlanMappingVO.class); + when(mapping.getVlanId()).thenReturn(14); + when(vcsmapdao.findByNetworkId(anyLong())).thenReturn(mapping); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = new ArrayList(); + devices.add(brocadeDevice); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final DeleteNetworkAnswer answer = mock(DeleteNetworkAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentmgr.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + when(vcsdao.remove((long)anyInt())).thenReturn(true); + + final boolean result = guru.trash(network, offering); + assertTrue(result == true); + verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any()); + } + + @Test + public void testTrashFail() { + + final NetworkVO network = mock(NetworkVO.class); + when(network.getName()).thenReturn("testnetwork"); + when(network.getState()).thenReturn(State.Implementing); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final HostVO brocadeHost = mock(HostVO.class); + when(hostdao.findById(anyLong())).thenReturn(brocadeHost); + when(brocadeHost.getId()).thenReturn(NETWORK_ID); + + when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(NETWORK_ID); + + final BrocadeVcsNetworkVlanMappingVO mapping = mock(BrocadeVcsNetworkVlanMappingVO.class); + when(mapping.getVlanId()).thenReturn(14); + when(vcsmapdao.findByNetworkId(anyLong())).thenReturn(mapping); + when(vcsmapdao.remove(anyLong())).thenReturn(true); + + final BrocadeVcsDeviceVO brocadeDevice = mock(BrocadeVcsDeviceVO.class); + when(brocadeDevice.getHostId()).thenReturn(NETWORK_ID); + + final List devices = mock(List.class); + when(devices.isEmpty()).thenReturn(true); + when(vcsdao.listByPhysicalNetwork(anyLong())).thenReturn(devices); + + final boolean result = guru.trash(network, offering); + assertTrue(result == false); + verify(agentmgr, times(0)).easySend(eq(NETWORK_ID), (Command)any()); + } +} diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java b/plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java new file mode 100644 index 0000000000..f903d0e1c1 --- /dev/null +++ b/plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java @@ -0,0 +1,261 @@ +// +// 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.junit.Before; +import org.junit.Test; + +import com.cloud.agent.api.AssociateMacToNetworkAnswer; +import com.cloud.agent.api.AssociateMacToNetworkCommand; +import com.cloud.agent.api.CreateNetworkAnswer; +import com.cloud.agent.api.CreateNetworkCommand; +import com.cloud.agent.api.DeleteNetworkAnswer; +import com.cloud.agent.api.DeleteNetworkCommand; +import com.cloud.agent.api.DisassociateMacFromNetworkAnswer; +import com.cloud.agent.api.DisassociateMacFromNetworkCommand; +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.host.Host; +import com.cloud.network.brocade.BrocadeVcsApi; +import com.cloud.network.brocade.BrocadeVcsApiException; +import com.cloud.network.schema.showvcs.Output; +import com.cloud.network.schema.showvcs.VcsNodeInfo; +import com.cloud.network.schema.showvcs.VcsNodes; + +public class BrocadeVcsResourceTest { + + private static final long NETWORK_ID = 42L; + private static final int VLAN_ID = 14; + private static final String MAC_ADDRESS_32 = "0050.56bf.0002"; + private static final String MAC_ADDRESS_64 = "00:50:56:bf:00:02"; + BrocadeVcsApi api = mock(BrocadeVcsApi.class); + BrocadeVcsResource resource; + Map parameters; + + @Before + public void setUp() throws ConfigurationException { + resource = new BrocadeVcsResource() { + @Override + protected BrocadeVcsApi createBrocadeVcsApi(String ip, String username, String password) { + return api; + } + }; + + parameters = new HashMap(); + parameters.put("name", "vcstestdevice"); + parameters.put("ip", "127.0.0.1"); + parameters.put("adminuser", "adminuser"); + parameters.put("guid", "aaaaa-bbbbb-ccccc"); + parameters.put("zoneId", "blublub"); + parameters.put("adminpass", "adminpass"); + } + + @Test(expected = ConfigurationException.class) + public void resourceConfigureFailure() throws ConfigurationException { + resource.configure("BrocadeVcsResource", Collections. emptyMap()); + } + + @Test + public void resourceConfigure() throws ConfigurationException { + resource.configure("BrocadeVcsResource", parameters); + assertTrue("Incorrect resource name", "vcstestdevice".equals(resource.getName())); + + assertTrue("Incorrect resource type", resource.getType() == Host.Type.L2Networking); + } + + @Test + public void testInitialization() throws ConfigurationException { + resource.configure("BrocadeVcsResource", parameters); + + final StartupCommand[] sc = resource.initialize(); + assertTrue(sc.length == 1); + assertTrue("Incorrect startup command GUID", "aaaaa-bbbbb-ccccc".equals(sc[0].getGuid())); + assertTrue("Incorrect Brocade device name", "vcstestdevice".equals(sc[0].getName())); + assertTrue("Incorrect Data Center", "blublub".equals(sc[0].getDataCenter())); + } + + @Test + public void testPingCommandStatusOk() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + final VcsNodeInfo nodeInfo = mock(VcsNodeInfo.class); + when(nodeInfo.getNodeState()).thenReturn("Online"); + + List nodes = new ArrayList(); + nodes.add(nodeInfo); + + final VcsNodes vcsNodes = mock(VcsNodes.class); + final Output output = mock(Output.class); + when(output.getVcsNodes()).thenReturn(vcsNodes); + when(vcsNodes.getVcsNodeInfo()).thenReturn(nodes); + when(api.getSwitchStatus()).thenReturn(output); + + final PingCommand ping = resource.getCurrentStatus(42); + assertTrue(ping != null); + assertTrue(ping.getHostId() == 42); + assertTrue(ping.getHostType() == Host.Type.L2Networking); + + } + + @Test + public void testPingCommandStatusFail() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + final VcsNodeInfo nodeInfo = mock(VcsNodeInfo.class); + when(nodeInfo.getNodeState()).thenReturn("Offline"); + + List nodes = new ArrayList(); + nodes.add(nodeInfo); + + final VcsNodes vcsNodes = mock(VcsNodes.class); + final Output output = mock(Output.class); + when(output.getVcsNodes()).thenReturn(vcsNodes); + when(vcsNodes.getVcsNodeInfo()).thenReturn(nodes); + when(api.getSwitchStatus()).thenReturn(output); + + final PingCommand ping = resource.getCurrentStatus(42); + assertTrue(ping == null); + } + + @Test + public void testPingCommandStatusApiException() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + when(api.getSwitchStatus()).thenThrow(new BrocadeVcsApiException()); + + final PingCommand ping = resource.getCurrentStatus(42); + assertTrue(ping == null); + } + + @Test + public void testRetries() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.createNetwork(VLAN_ID, NETWORK_ID)).thenThrow(new BrocadeVcsApiException()).thenThrow(new BrocadeVcsApiException()).thenReturn(true); + + final CreateNetworkCommand cmd = new CreateNetworkCommand(VLAN_ID, NETWORK_ID, "owner"); + final CreateNetworkAnswer answer = (CreateNetworkAnswer)resource.executeRequest(cmd); + assertTrue(answer.getResult()); + + } + + @Test + public void testCreateNetworkApi() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.createNetwork(VLAN_ID, NETWORK_ID)).thenReturn(true); + + final CreateNetworkCommand cmd = new CreateNetworkCommand(VLAN_ID, NETWORK_ID, "owner"); + final CreateNetworkAnswer answer = (CreateNetworkAnswer)resource.executeRequest(cmd); + //verify(api).createNetwork(VLAN_ID, NETWORK_ID); + assertTrue(answer.getResult()); + + } + + @Test + public void testCreateNetworkApiException() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.createNetwork(VLAN_ID, NETWORK_ID)).thenThrow(new BrocadeVcsApiException()); + + final CreateNetworkCommand cmd = new CreateNetworkCommand(VLAN_ID, NETWORK_ID, "owner"); + final CreateNetworkAnswer answer = (CreateNetworkAnswer)resource.executeRequest(cmd); + assertFalse(answer.getResult()); + + } + + @Test + public void testDeleteNetworkApi() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.deleteNetwork(VLAN_ID, NETWORK_ID)).thenReturn(true); + + final DeleteNetworkCommand cmd = new DeleteNetworkCommand(VLAN_ID, NETWORK_ID); + final DeleteNetworkAnswer answer = (DeleteNetworkAnswer)resource.executeRequest(cmd); + assertTrue(answer.getResult()); + } + + @Test + public void testDeleteNetworkApiException() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.deleteNetwork(VLAN_ID, NETWORK_ID)).thenThrow(new BrocadeVcsApiException()); + + final DeleteNetworkCommand cmd = new DeleteNetworkCommand(VLAN_ID, NETWORK_ID); + final DeleteNetworkAnswer answer = (DeleteNetworkAnswer)resource.executeRequest(cmd); + assertFalse(answer.getResult()); + } + + @Test + public void testAssociateMacToNetworkApi() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.associateMacToNetwork(NETWORK_ID, MAC_ADDRESS_32)).thenReturn(true); + + final AssociateMacToNetworkCommand cmd = new AssociateMacToNetworkCommand(NETWORK_ID, MAC_ADDRESS_64, "owner"); + final AssociateMacToNetworkAnswer answer = (AssociateMacToNetworkAnswer)resource.executeRequest(cmd); + assertTrue(answer.getResult()); + } + + @Test + public void testAssociateMacToNetworkApiException() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.associateMacToNetwork(NETWORK_ID, MAC_ADDRESS_32)).thenThrow(new BrocadeVcsApiException()); + + final AssociateMacToNetworkCommand cmd = new AssociateMacToNetworkCommand(NETWORK_ID, MAC_ADDRESS_64, "owner"); + final AssociateMacToNetworkAnswer answer = (AssociateMacToNetworkAnswer)resource.executeRequest(cmd); + assertFalse(answer.getResult()); + } + + @Test + public void testDisassociateMacFromNetworkApi() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.disassociateMacFromNetwork(NETWORK_ID, MAC_ADDRESS_32)).thenReturn(true); + + final DisassociateMacFromNetworkCommand cmd = new DisassociateMacFromNetworkCommand(NETWORK_ID, MAC_ADDRESS_64); + final DisassociateMacFromNetworkAnswer answer = (DisassociateMacFromNetworkAnswer)resource.executeRequest(cmd); + assertTrue(answer.getResult()); + } + + @Test + public void testDisassociateMacFromNetworkApiException() throws ConfigurationException, BrocadeVcsApiException { + resource.configure("BrocadeVcsResource", parameters); + + when(api.disassociateMacFromNetwork(NETWORK_ID, MAC_ADDRESS_32)).thenThrow(new BrocadeVcsApiException()); + + final DisassociateMacFromNetworkCommand cmd = new DisassociateMacFromNetworkCommand(NETWORK_ID, MAC_ADDRESS_64); + final DisassociateMacFromNetworkAnswer answer = (DisassociateMacFromNetworkAnswer)resource.executeRequest(cmd); + assertFalse(answer.getResult()); + } +} diff --git a/plugins/pom.xml b/plugins/pom.xml index eff5a01856..b3890c07c8 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -64,6 +64,7 @@ network-elements/netscaler network-elements/nicira-nvp network-elements/bigswitch-vns + network-elements/brocade-vcs network-elements/midonet network-elements/stratosphere-ssp network-elements/opendaylight diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index 6cb81c65fa..d727f21546 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -244,6 +244,26 @@ CREATE VIEW `cloud`.`volume_view` AS and async_job.instance_type = 'Volume' and async_job.job_status = 0; +CREATE TABLE `cloud`.`external_brocade_vcs_devices` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which brocade vcs switch is added', + `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this brocade vcs switch', + `device_name` varchar(255) NOT NULL COMMENT 'name of the brocade vcs switch', + `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external brocade vcs switch', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_brocade_vcs_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_brocade_vcs_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`brocade_network_vlan_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `network_id` bigint unsigned NOT NULL COMMENT 'id of the network', + `vlan_id` int(10) COMMENT 'vlan id of the network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_brocade_network_vlan_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + /* As part of the separation of Xen and XenServer, update the column for the network labels */ ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host'; diff --git a/test/integration/component/test_brocade_vcs.py b/test/integration/component/test_brocade_vcs.py new file mode 100644 index 0000000000..556de285c3 --- /dev/null +++ b/test/integration/component/test_brocade_vcs.py @@ -0,0 +1,333 @@ +# 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. + +""" P1 tests for brocade +""" +#Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources, + random_gen, validateList) +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Host, + Network, + NATRule, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.sshClient import SshClient +from marvin.codes import PASS +import time + + +class Services: + """Test brocade plugin + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "virtual_machine": { + "displayname": "TestVM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "brocade": { + "ipaddress": '10.24.51.45', + "username": 'admin', + "password": 'password123' + }, + "network_offering": { + "name": 'Brocade', + "displaytext": 'Brocade', + "guestiptype": 'Isolated', + "supportedservices": 'SourceNat,Connectivity', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "SourceNat": 'VirtualRouter', + "Connectivity" : 'BrocadeVcs' + }, + }, + "network": { + "name": "Brocade", + "displaytext": "Brocade", + }, + "ostype": 'CentOS 5.3 (64-bit)', + # Cent OS 5.3 (64 bit) + "sleep": 60, + "timeout": 10 + } + +class TestBrocadeVcs(cloudstackTestCase): + + + @classmethod + def setUpClass(cls): + cls._cleanup = [] + cls.testClient = super(TestBrocadeVcs, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.brocade_services = cls.services["brocade"] + try: + + """ Adds Brocade device and enables NS provider""" + cmd = listPhysicalNetworks.listPhysicalNetworksCmd() + cmd.zoneid = cls.zone.id + physical_networks = cls.api_client.listPhysicalNetworks(cmd) + if isinstance(physical_networks, list): + physical_network = physical_networks[0] + cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() + cmd.name = 'BrocadeVcs' + cmd.physicalnetworkid = physical_network.id + nw_service_providers = cls.api_client.listNetworkServiceProviders(cmd) + + if isinstance(nw_service_providers, list): + brocade_provider = nw_service_providers[0] + else: + cmd1 = addNetworkServiceProvider.addNetworkServiceProviderCmd() + cmd1.name = 'BrocadeVcs' + cmd1.physicalnetworkid = physical_network.id + brocade_provider = cls.api_client.addNetworkServiceProvider(cmd1) + + cmd2 = addBrocadeVcsDevice.addBrocadeVcsDeviceCmd() + cmd2.physicalnetworkid = physical_network.id + cmd2.username = cls.brocade_services["username"] + cmd2.password = cls.brocade_services["password"] + cmd2.hostname = cls.brocade_services["ipaddress"] + cls.brocade = cls.api_client.addBrocadeVcsDevice(cmd2) + + if brocade_provider.state != 'Enabled': + cmd = updateNetworkServiceProvider.updateNetworkServiceProviderCmd() + cmd.id = brocade_provider.id + cmd.state = 'Enabled' + cls.api_client.updateNetworkServiceProvider(cmd) + + + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + cls._cleanup.append(cls.network_offering) + + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise Exception ("Warning: Exception in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cmd = deleteBrocadeVcsDevice.deleteBrocadeVcsDeviceCmd() + cmd.vcsdeviceid = cls.brocade.vcsdeviceid + cls.brocade = cls.api_client.deleteBrocadeVcsDevice(cmd) + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + #cleanup_resources(self.apiclient, self.cleanup) + interval = Configurations.list( + self.apiclient, + name='network.gc.interval' + ) + wait = Configurations.list( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + + @attr(tags = ["advancedns"]) + def test_network_vcs(self): + """Test Brocade Network and VM Creation + """ + + + # Validate the following + # 1. Deploy the first VM using a network from the above created + # Network offering. + # 2. Deploy another VM. + # 3. Delete The VMs and the Network + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network.id) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Deploying another VM in account: %s" % + self.account.name) + + # Spawn an instance in that network + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + # Deleting a single VM + VirtualMachine.delete(virtual_machine_1, self.apiclient) + VirtualMachine.expung(virtual_machine_1, self.apiclient) + + + # Deleting a single VM + VirtualMachine.delete(virtual_machine_2, self.apiclient) + VirtualMachine.expung(virtual_machine_2, self.apiclient) + + + # Delete Network + Network.delete(self.network, self.apiclient) + + return + diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index bcc8417c3c..1ad493d59a 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -132,6 +132,7 @@ 'StaticRoute': 'VPC', 'Tags': 'Resource tags', 'NiciraNvpDevice': 'Nicira NVP', + 'BrocadeVcsDevice': 'Brocade VCS', 'BigSwitchVnsDevice': 'BigSwitch VNS', 'NuageVsp': 'Nuage VSP', 'AutoScale': 'AutoScale', diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index c84d0ddea0..beb082b4f7 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -352,6 +352,7 @@ dictionary = { 'label.add.new.tier': '', 'label.add.NiciraNvp.device': '', 'label.add.NuageVsp.device': '', +'label.add.BrocadeVcs.device': '', 'label.add.pod': '', 'label.add.port.forwarding.rule': '', 'label.add.primary.storage': '', @@ -509,6 +510,7 @@ dictionary = { 'label.delete.NetScaler': '', 'label.delete.NiciraNvp': '', 'label.delete.NuageVsp': '', +'label.delete.BrocadeVcs': '', 'label.delete.project': '', 'label.delete.SRX': '', 'label.delete.PA': '', @@ -868,6 +870,7 @@ dictionary = { 'label.nicira.controller.address': '', 'label.nicira.l3gatewayserviceuuid': '', 'label.nicira.transportzoneuuid': '', +'label.brocade.vcs.address': '', 'label.nics': '', 'label.no.actions': '', 'label.no.alerts': '', @@ -1433,6 +1436,7 @@ dictionary = { 'message.configuring.storage.traffic': '', 'message.confirm.action.force.reconnect': '', 'message.confirm.delete.F5': '', +'message.confirm.delete.BrocadeVcs': '', 'message.confirm.delete.NetScaler': '', 'message.confirm.delete.NuageVsp': '', 'message.confirm.delete.SRX': '', @@ -1738,6 +1742,8 @@ dictionary = { 'label.palo.alto.details': '', 'label.added.nicira.nvp.controller': '', 'label.nicira.nvp.details': '', +'label.added.brocade.vcs.switch': '', +'label.brocade.vcs.details': '', 'label.added.new.bigswitch.vns.controller': '', 'label.bigswitch.vns.details': '', 'label.dedicate': '', diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 502007f501..4e0d78a08d 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -5807,6 +5807,206 @@ } } } + }, + // Brocade Vcs provider detail view + brocadeVcs: { + type: 'detailView', + id: 'brocadeVcsProvider', + label: 'label.brocadeVcs', + viewAll: { + label: 'label.devices', + path: '_zone.brocadeVcsDevices' + }, + tabs: { + details: { + title: 'label.details', + fields:[ { + name: { + label: 'label.name' + } + }, + { + state: { + label: 'label.state' + } + }], + dataProvider: function (args) { + refreshNspData("BrocadeVcs"); + var providerObj; + $(nspHardcodingArray).each(function () { + if (this.id == "brocadeVcs") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('brocadeVcs') + }); + } + } + }, + actions: { + add: { + label: 'label.add.BrocadeVcs.device', + createForm: { + title: 'label.add.BrocadeVcs.device', + preFilter: function (args) { + }, + // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + } + } + }, + action: function (args) { + if (nspMap[ "brocadeVcs"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BrocadeVcs&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function (json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBrocadeVcsProviderIntervalID = setInterval(function () { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function (json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + clearInterval(addBrocadeVcsProviderIntervalID); + if (result.jobstatus == 1) { + nspMap[ "brocadeVcs"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addBrocadeVcsDevice(args, selectedPhysicalNetworkObj, "addBrocadeVcsDevice", "addbrocadevcsdeviceresponse", "brocadevcsdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=BrocadeVcs failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function (XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=BrocadeVcs failed. Error: " + errorMsg); + } + }); + }, + g_queryAsyncJobResultInterval); + } + }); + } else { + addBrocadeVcsDevice(args, selectedPhysicalNetworkObj, "addBrocadeVcsDevice", "addbrocadevcsdeviceresponse", "brocadevcsdevice") + } + }, + messages: { + notification: function (args) { + return 'label.add.BrocadeVcs.device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function (args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "brocadeVcs"].id + "&state=Enabled"), + dataType: "json", + success: function (json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function (json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function (args) { + return 'message.confirm.enable.provider'; + }, + notification: function () { + return 'label.enable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + disable: { + label: 'label.disable.provider', + action: function (args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "brocadeVcs"].id + "&state=Disabled"), + dataType: "json", + success: function (json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function (json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function (args) { + return 'message.confirm.disable.provider'; + }, + notification: function () { + return 'label.disable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + destroy: { + label: 'label.shutdown.provider', + action: function (args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap[ "brocadeVcs"].id), + dataType: "json", + success: function (json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function (args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function (args) { + return 'label.shutdown.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + } }, // BigSwitch Vns provider detail view bigswitchVns: { @@ -12039,6 +12239,166 @@ } } } + }, + // BrocadeVcs devices listView + brocadeVcsDevices: { + id: 'brocadeVcsDevices', + title: 'label.devices', + listView: { + id: 'brocadeVcsDevices', + fields: { + hostname: { + label: 'label.brocade.vcs.address' + } + }, + actions: { + add: { + label: 'label.add.BrocadeVcs.device', + createForm: { + title: 'label.add.BrocadeVcs.device', + preFilter: function (args) { + }, + // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + } + } + }, + action: function (args) { + if (nspMap[ "brocadeVcs"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BrocadeVcs&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function (json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBrocadeVcsProviderIntervalID = setInterval(function () { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function (json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; // Job has not completed + } else { + clearInterval(addBrocadeVcsProviderIntervalID); + if (result.jobstatus == 1) { + nspMap[ "brocadeVcs"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addBrocadeVcsDevice(args, selectedPhysicalNetworkObj, "addBrocadeVcsDevice", "addbrocadevcsdeviceresponse", "brocadevcsdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=BrocadeVcs failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function (XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=BrocadeVcs failed. Error: " + errorMsg); + } + }); + }, + g_queryAsyncJobResultInterval); + } + }); + } else { + addBrocadeVcsDevice(args, selectedPhysicalNetworkObj, "addBrocadeVcsDevice", "addbrocadevcsdeviceresponse", "brocadevcsdevice") + } + }, + messages: { + notification: function (args) { + return 'label.added.brocade.vcs.switch'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + dataProvider: function (args) { + $.ajax({ + url: createURL("listBrocadeVcsDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + data: { + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function (json) { + var items = json.listbrocadevcsdeviceresponse.brocadevcsdevice; + args.response.success({ + data: items + }); + } + }); + }, + detailView: { + name: 'label.brocade.vcs.details', + actions: { + 'remove': { + label: 'label.delete.BrocadeVcs', + messages: { + confirm: function (args) { + return 'message.confirm.delete.BrocadeVcs'; + }, + notification: function (args) { + return 'label.delete.BrocadeVcs'; + } + }, + action: function (args) { + $.ajax({ + url: createURL("deleteBrocadeVcsDevice&vcsdeviceid=" + args.context.brocadeVcsDevices[0].vcsdeviceid), + dataType: "json", + async: true, + success: function (json) { + var jid = json.deletebrocadevcsdeviceresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + fields:[ { + vcsdeviceid: { + label: 'label.id' + }, + hostname: { + label: 'label.ip.address' + } + }], + dataProvider: function (args) { + $.ajax({ + url: createURL("listBrocadeVcsDevices&vcsdeviceid=" + args.context.brocadeVcsDevices[0].vcsdeviceid), + dataType: "json", + async: true, + success: function (json) { + var item = json.listbrocadevcsdeviceresponse.brocadevcsdevice[0]; + args.response.success({ + data: item + }); + } + }); + } + } + } + } + } }, bigswitchVnsDevices: { id: 'bigswitchVnsDevices', @@ -19204,7 +19564,34 @@ } }); } - + + function addBrocadeVcsDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { + var array1 =[]; + array1.push("&physicalnetworkid=" + physicalNetworkObj.id); + array1.push("&username=" + todb(args.data.username)); + array1.push("&password=" + todb(args.data.password)); + array1.push("&hostname=" + todb(args.data.host)); + + $.ajax({ + url: createURL(apiCmd + array1.join("")), + dataType: "json", + type: "POST", + success: function (json) { + var jid = json[apiCmdRes].jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function (json) { + var item = json.queryasyncjobresultresponse.jobresult[apiCmdObj]; + + return item; + } + } + }); + } + }); + } + function addOpenDaylightController(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { var array1 =[]; array1.push("&physicalnetworkid=" + physicalNetworkObj.id); @@ -19955,6 +20342,9 @@ break; case "NiciraNvp": nspMap[ "niciraNvp"] = items[i]; + break; + case "BrocadeVcs": + nspMap[ "brocadeVcs"] = items[i]; break; case "BigSwitchVns": nspMap[ "bigswitchVns"] = items[i]; @@ -19988,6 +20378,11 @@ id: 'niciraNvp', name: 'Nicira Nvp', state: nspMap.niciraNvp ? nspMap.niciraNvp.state: 'Disabled' + }, + { + id: 'brocadeVcs', + name: 'Brocade', + state: nspMap.brocadeVcs ? nspMap.brocadeVcs.state: 'Disabled' }, { id: 'bigswitchVns', diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 645c2b1b94..f3a1aaeccd 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -729,7 +729,10 @@ }).html('L3VPN'), $('