From f8681de07cb9a286ed5d02f08433cca065a06716 Mon Sep 17 00:00:00 2001 From: Ian Southam Date: Tue, 14 Jan 2014 14:59:54 +0100 Subject: [PATCH 001/180] Invalid reference to a class which has been moved Signed-off-by: Hugo Trippaers --- .../cloudstack/core/spring-server-core-managers-context.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d4ee85e4569..c447057a42b 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 @@ -124,7 +124,7 @@ - + From f58d77c8d1fd9eb2bee927f7d92e50ba1553c7b6 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Wed, 15 Jan 2014 02:51:15 +0530 Subject: [PATCH 002/180] CLOUDSTACK-5689: System vm creation on local storage fails for hyper-v. A null pointer exception was getting generated when a VolumeTO object was serialized to create an answer object. If a local storage is used the uri field will be null. Added null checks for the same. --- .../HypervResource/CloudStackTypes.cs | 33 ++++++++++++++----- .../HypervResourceController.cs | 11 ++----- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 89f0814214e..847380cb115 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -61,7 +61,7 @@ namespace HypervResource get { string uncPath = null; - if (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem")) + if (uri != null && (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem"))) { uncPath = @"\\" + uri.Host + uri.LocalPath; } @@ -73,8 +73,13 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + string user = null; + if (uri != null) + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + user = System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + } + return user; } } @@ -82,8 +87,13 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + string password = null; + if (uri != null) + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + password = System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + } + return password; } } @@ -91,12 +101,17 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - if (queryDictionary["domain"] != null) + string domain = null; + if (uri != null) { - return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + if (queryDictionary["domain"] != null) + { + domain = System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + } + else domain = uri.Host; } - else return uri.Host; + return domain; } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 18f3158da46..94837a2becd 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1474,15 +1474,8 @@ namespace HypervResource { // TODO: thin provision instead of copying the full file. File.Copy(srcFile, destFile); - VolumeObjectTO volume = new VolumeObjectTO(); - volume.path = destFile; - volume.dataStore = destVolumeObjectTO.dataStore; - volume.name = destVolumeObjectTO.name; - volume.size = ulong.Parse(destVolumeObjectTO.size.ToString()); - volume.format = destVolumeObjectTO.format; - volume.nfsDataStore = destVolumeObjectTO.nfsDataStore; - volume.primaryDataStore = destVolumeObjectTO.primaryDataStore; - JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, volume); + destVolumeObjectTO.path = destFile; + JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO); newData = ansObj; result = true; } From 6282e8e9ca8906952b9d710ad1e439c965e0a0b0 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 14 Jan 2014 10:54:49 -0800 Subject: [PATCH 003/180] CLOUDSTACK-5557: UI > Network > VPC > Router > Public IP Address > fix a bug that Configuration tab was wrongly hidden. --- ui/scripts/network.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 610b1bdc2dc..c404b55b9b7 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -2222,7 +2222,11 @@ } } - if (ipAddress.vpcid || ipAddress.issourcenat) { + if (ipAddress.issourcenat) { + disableIpRules = true; + } + + if (('vpc' in args.context) == false && ipAddress.vpcid != null) { //from Guest Network section, don't show Configuration(ipRules) tab on VPC IP disableIpRules = true; } From 4215d697530f75d1c8d4343a3e519e1d70b39efd Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 14 Jan 2014 11:07:44 -0800 Subject: [PATCH 004/180] Instances UI: Don't show 'view host' link if VM is stopped --- ui/scripts/instances.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index d4a5482d84b..05c5f79474b 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -355,9 +355,9 @@ label: 'label.affinity.groups' }, { path: '_zone.hosts', - label: 'label.hosts', + label: 'label.host', preFilter: function(args) { - return isAdmin(); + return isAdmin() && args.context.instances[0].hostid; }, updateContext: function(args) { var instance = args.context.instances[0]; From ba96c8cadfa4b1dc7ee74fdb26ba5cea87e29b91 Mon Sep 17 00:00:00 2001 From: Sateesh Chodapuneedi Date: Wed, 15 Jan 2014 01:38:34 +0530 Subject: [PATCH 005/180] CLOUDSTACK-5408 [Automation] Failed to deploy vm in vmware environment with error "due to java.io.IOException: Cannot run program "mount": java.io.IOException: error=12, Cannot allocate memory" Bump up RAM size of system offering for SSVM to 512MB Signed-off-by: Sateesh Chodapuneedi --- .../cloud/upgrade/dao/Upgrade421to430.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java index 268a27d2582..bf08e877ced 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java @@ -63,6 +63,49 @@ public class Upgrade421to430 implements DbUpgrade { @Override public void performDataMigration(Connection conn) { encryptLdapConfigParams(conn); + upgradeMemoryOfSsvmOffering(conn); + } + + private void upgradeMemoryOfSsvmOffering(Connection conn) { + PreparedStatement updatePstmt = null; + PreparedStatement selectPstmt = null; + ResultSet selectResultSet = null; + int newRamSize = 512; //512MB + long serviceOfferingId = 0; + + /** + * Pick first row in service_offering table which has system vm type as secondary storage vm. User added offerings would start from 2nd row onwards. + * We should not update/modify any user-defined offering. + */ + + try { + selectPstmt = conn.prepareStatement("SELECT id FROM `cloud`.`service_offering` WHERE vm_type='secondarystoragevm'"); + updatePstmt = conn.prepareStatement("UPDATE `cloud`.`service_offering` SET ram_size=? WHERE id=?'"); + selectResultSet = selectPstmt.executeQuery(); + if(selectResultSet.next()) { + serviceOfferingId = selectResultSet.getLong("id"); + } + + updatePstmt.setInt(1, newRamSize); + updatePstmt.setLong(2, serviceOfferingId); + updatePstmt.executeUpdate(); + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to upgrade ram_size of service offering for secondary storage vm. ", e); + } finally { + try { + if (selectPstmt != null) { + selectPstmt.close(); + } + if (selectResultSet != null) { + selectResultSet.close(); + } + if (updatePstmt != null) { + updatePstmt.close(); + } + } catch (SQLException e) { + } + } + s_logger.debug("Done upgrading RAM for service offering of Secondary Storage VM to " + newRamSize); } private void encryptLdapConfigParams(Connection conn) { From 2893120f2abcd640d954c7476613a6566eef344e Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 14 Jan 2014 12:56:52 -0800 Subject: [PATCH 006/180] Remove old/obsolete UI qunit tests --- ui/tests/index.html | 61 +-- ui/tests/test.cloudBrowser.js | 116 ----- ui/tests/test.core.js | 79 ---- ui/tests/test.detailView.js | 799 --------------------------------- ui/tests/test.listView.js | 527 ---------------------- ui/tests/test.multiEdit.js | 55 --- ui/tests/test.notifications.js | 107 ----- 7 files changed, 1 insertion(+), 1743 deletions(-) delete mode 100644 ui/tests/test.cloudBrowser.js delete mode 100644 ui/tests/test.core.js delete mode 100644 ui/tests/test.detailView.js delete mode 100644 ui/tests/test.listView.js delete mode 100644 ui/tests/test.multiEdit.js delete mode 100644 ui/tests/test.notifications.js diff --git a/ui/tests/index.html b/ui/tests/index.html index fcb7305a7ce..5539e0f5382 100644 --- a/ui/tests/index.html +++ b/ui/tests/index.html @@ -34,70 +34,11 @@ under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/ui/tests/test.cloudBrowser.js b/ui/tests/test.cloudBrowser.js deleted file mode 100644 index 4a27821285b..00000000000 --- a/ui/tests/test.cloudBrowser.js +++ /dev/null @@ -1,116 +0,0 @@ -// 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. -(function($) { - var $browser, $breadcrumbs, $browserContainer; - - module('Browser', { - setup: function() { - $.fx.off = true; - $browser = $('
').addClass('browser-test').appendTo('#qunit-fixture'); - $breadcrumbs = $('
').attr('id', 'breadcrumbs').appendTo($browser); - $browserContainer = $('
').addClass('container').appendTo($browser); - ok($browserContainer.cloudBrowser(), 'Browser initialized'); - equal($breadcrumbs.find('ul').size(), 1, 'Breadcrumbs initialized'); - } - }); - - // Browser tests - test('Add panel', function() { - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add panel'); - equal($browser.find('.panel').size(), 1, 'Browser has 1 panel'); - equal($breadcrumbs.find('ul li').size(), 1, 'Browser has 1 breadcrumb'); - equal($breadcrumbs.find('ul li:first span').html(), 'testPanel123', 'Panel has correct title'); - }); - - test('Add a second panel', function() { - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add first panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel456' }), 'Add second panel'); - equal($browser.find('.panel').size(), 2, 'Browser has 2 panels'); - equal($breadcrumbs.find('ul li').size(), 2, 'Browser has 2 breadcrumbs'); - equal($breadcrumbs.find('ul li:last span').html(), 'testPanel456', 'New panel has correct title'); - equal($breadcrumbs.find('ul li:first span').html(), 'testPanel123', 'First panel still has correct title'); - }); - - test('Add maximized panel', function() { - var $maximizedPanel, $normalPanel; - - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }, 'Add first panel')); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel456' }, 'Add normal-sized-panel')); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel789', maximizeIfSelected: true }), 'Add maximized panel'); - - $maximizedPanel = $browserContainer.find('.panel:last'); - $normalPanel = $browserContainer.find('.panel:first').next(); - - ok($maximizedPanel.hasClass('always-maximized'), 'Maximized panel has maximized class'); - ok(!$normalPanel.hasClass('always-maximized'), 'Normal panel has maximized class'); - equal($maximizedPanel.width(), $browserContainer.width(), 'Maximized panel covers full width of browser container'); - notEqual($normalPanel.width(), $browserContainer.width(), 'Normal panel doesn\'t have maximized appearance'); - }); - - test('Select panel', function() { - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add first panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel456' }), 'Add second panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel789' }), 'Add third panel'); - - stop(); - $browserContainer.cloudBrowser('selectPanel', { - panel: $browser.find('.panel:first').next(), - complete: function() { - start(); - ok(true, 'Select second panel'); - } - }); - - equal($browser.find('.panel').size(), 2, 'Browser has 2 panels'); - equal($breadcrumbs.find('ul li:first span').html(), 'testPanel123', 'First panel still has correct title'); - equal($breadcrumbs.find('ul li:last span').html(), 'testPanel456', 'Second panel still has correct title'); - equal($breadcrumbs.find('ul li').size(), 2, 'Browser has 2 breadcrumbs'); - - stop(); - $browserContainer.cloudBrowser('selectPanel', { - panel: $browser.find('.panel:first'), - complete: function() { - start(); - ok(true, 'Select first panel'); - } - }); - - equal($browser.find('.panel').size(), 1, 'Browser has 1 panel'); - equal($breadcrumbs.find('ul li:first span').html(), 'testPanel123', 'First panel still has correct title'); - equal($breadcrumbs.find('ul li').size(), 1, 'Browser has 1 breadcrumb'); - }); - - test('Remove all panels', function() { - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add first panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel456' }), 'Add second panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel789' }), 'Add third panel'); - equal($browserContainer.find('.panel').size(), 3, 'Correct # of panels'); - ok($browserContainer.cloudBrowser('removeAllPanels'), 'Remove all panels'); - equal($browserContainer.find('.panel').size(), 0, 'All panels removed'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add 1 panel'); - equal($browserContainer.find('.panel').size(), 1, 'Correct # of panels'); - }); - - test('Maximize panel', function() { - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel123' }), 'Add first panel'); - ok($browserContainer.cloudBrowser('addPanel', { title: 'testPanel456' }), 'Add second panel'); - equal($browserContainer.find('.panel').size(), 2, 'Correct # of panels'); - ok($browserContainer.cloudBrowser('toggleMaximizePanel', { panel: $browserContainer.find('.panel:first')}), 'Maximize first panel'); - ok($browserContainer.find('.panel:first').hasClass('maximized'), 'First panel has maximized style'); - ok(!$browserContainer.find('.panel:last').hasClass('maximized'), 'Last panel has correct style'); - }); -}(jQuery)); diff --git a/ui/tests/test.core.js b/ui/tests/test.core.js deleted file mode 100644 index 8ccab7d9e20..00000000000 --- a/ui/tests/test.core.js +++ /dev/null @@ -1,79 +0,0 @@ -// 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. -(function($) { - var $cloudStack, cloudStack; - - module('Core widget', { - setup: function() { - cloudStack = { - sections: { - home: { - show: function() { return $('
').addClass('test123'); } - }, - sectionA: {}, - sectionB: {}, - sectionC: {} - }, - - home: 'home' - }; - - $cloudStack = $('
'); - ok($cloudStack.cloudStack(cloudStack), 'Basic widget initialized'); - } - }); - - test('Container/wrappers', function() { - equal($cloudStack.find('[cloudStack-container]').size(), 1, 'Main sub-container present'); - equal($cloudStack.find('#main-area').size(), 1, 'Main area present'); - }); - - test('Header', function() { - var $header = $cloudStack.find('#header'); - var $userOptions = $cloudStack.find('#user-options'); - var $notifications = $header.find('.button.notifications'); - var $notificationTotal = $notifications.find('.total span'); - var $viewSwitcher = $header.find('.button.view-switcher'); - - equal($header.size(), 1, 'Header present'); - equal($userOptions.size(), 1, 'User options present'); - equal($userOptions.find('a').size(), 2, 'User options has correct # of options'); - equal($notifications.size(), 1, 'Notifications present'); - equal($notificationTotal.html(), '0', 'Notifications initialized properly'); - equal($viewSwitcher.size(), 1, 'View switcher present'); - }); - - test('Navigation', function() { - var $navigation = $cloudStack.find('#navigation'); - - equal($navigation.size(), 1, 'Navigation present'); - equal($navigation.find('li').size(), 4, 'Navigation has correct # of nav items'); - }); - - test('Browser / page generation', function() { - var $browser = $cloudStack.find('#browser'); - var $browserContainer = $browser.find('.container'); - var $homePage = $browserContainer.find('.panel div.test123'); - var $breadcrumbs = $browser.find('#breadcrumbs li'); - var $homeBreadcrumb = $browser.find('#breadcrumbs .home'); - - equal($browser.size(), 1, 'Browser intialized'); - equal($homePage.size(), 1, 'Home page is visible'); - equal($breadcrumbs.size(), 0, 'No initial breadcrumbs'); - equal($homeBreadcrumb.size(), 1, 'Home breadcrumb active'); - }); -}(jQuery)); diff --git a/ui/tests/test.detailView.js b/ui/tests/test.detailView.js deleted file mode 100644 index 6098300811e..00000000000 --- a/ui/tests/test.detailView.js +++ /dev/null @@ -1,799 +0,0 @@ -// 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. -(function($) { - module('Detail view', { - setup: function() { - cloudStack.dialog.__confirm = cloudStack.dialog.confirm; - cloudStack.ui.notifications.__add = cloudStack.ui.notifications.add; - $.fn.__cloudBrowser = $.fn.cloudBrowser; - $.fn.__listView = $.fn.listView; - $.fn.__dataTable = $.fn.dataTable; - $.fn.__is = $.fn.is; - - $.fn.is = function(args) { - if (args == ':visible') - return true; // No test elems will ever be shown, so just pretend they are visible - - return true; - }; - }, - - teardown: function() { - cloudStack.dialog.confirm = cloudStack.dialog.__confirm; - cloudStack.ui.notifications.add = cloudStack.ui.notifications.__add; - $.fn.cloudBrowser = $.fn.__cloudBrowser; - $.fn.listView = $.fn.__listView; - $.fn.dataTable = $.fn.__dataTable; - $.fn.is = $.fn.__is; - } - }); - - test('Basic', function() { - var detailView = { - tabs: { - tabA: { - title: 'tabA', - fields: [{}], - dataProvider: function() {} - }, - tabB: { - title: 'tabB', - fields: [{}], - dataProvider: function() {} - } - } - }; - - var $detailView = $('
'); - - ok($detailView.detailView(detailView), 'Create detail view'); - equal($detailView.find('.ui-tabs-nav li').size(), 2, 'Detail view has correct tab count'); - equal($detailView.find('.ui-tabs-nav li:first a').html(), 'tabA', 'First tab has correct title'); - equal($detailView.find('.ui-tabs-nav li:last a').html(), 'tabB', 'Last tab has correct title'); - }); - - test('Data provider', function() { - var detailView = { - tabs: { - tabA: { - title: 'tabA', - fields: [{ - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' } - }], - dataProvider: function(args) { - start(); - ok(args.response.success({ - data: { - fieldA: 'dataProviderFieldA', - fieldB: 'dataProviderFieldB' - } - }), 'Call success'); - equal($detailView.find('tr').size(), 2, 'Correct fields rendered'); - equal($detailView.find('tr:first td:first').html(), 'fieldA', 'First field has correct label'); - equal($detailView.find('tr:first td:last').html(), 'dataProviderFieldA', 'First field has correct content'); - equal($detailView.find('tr:last td:first').html(), 'fieldB', 'Last field has correct label'); - equal($detailView.find('tr:last td:last').html(), 'dataProviderFieldB', 'Last field has correct content'); - } - } - } - }; - var $detailView = $('
'); - - stop(); - - // Test first tab - $detailView = $detailView.detailView(detailView); - - // Test last tab - $detailView.find('.ui-tabs-nav li:last').click(); - }); - - test('Data provider, multiple tabs', function() { - var detailView = { - tabs: { - tabA: { - title: 'tabA', - fields: [{ - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' } - }], - dataProvider: function(args) { - start(); - ok(args.response.success({ - data: { - fieldA: 'dataProviderFieldA', - fieldB: 'dataProviderFieldB' - } - }), 'Call success'); - equal($detailView.find('tr').size(), 2, 'Correct fields rendered'); - equal($detailView.find('tr:first td:first').html(), 'fieldA', 'First field has correct label'); - equal($detailView.find('tr:first td:last').html(), 'dataProviderFieldA', 'First field has correct content'); - equal($detailView.find('tr:last td:first').html(), 'fieldB', 'Last field has correct label'); - equal($detailView.find('tr:last td:last').html(), 'dataProviderFieldB', 'Last field has correct content'); - } - }, - - tabB: { - title: 'tabB', - fields: [{ - fieldC: { label: 'fieldC' }, - fieldD: { label: 'fieldD' }, - fieldC: { label: 'fieldE' }, - fieldD: { label: 'fieldF' } - }], - dataProvider: function(args) { - start(); - ok(args.response.success({ - data: { - fieldC: 'dataProviderFieldC', - fieldD: 'dataProviderFieldD', - fieldE: 'dataProviderFieldE', - fieldF: 'dataProviderFieldF' - } - }), 'Call success'); - equal($detailView.find('tr').size(), 4, 'Correct fields rendered'); - equal($detailView.find('tr:first td:first').html(), 'fieldC', 'First field has correct label'); - equal($detailView.find('tr:first td:last').html(), 'dataProviderFieldC', 'First field has correct content'); - equal($detailView.find('tr:last td:first').html(), 'fieldF', 'Last field has correct label'); - equal($detailView.find('tr:last td:last').html(), 'dataProviderFieldF', 'Last field has correct content'); - } - } - } - }; - var $detailView = $('
'); - - stop(); - - // Test first tab - $detailView = $detailView.detailView(detailView); - - // Test last tab - $detailView.find('.ui-tabs-nav li:last').click(); - }); - - test('Field pre-filter', function() { - var detailView = { - tabs: { - tabA: { - title: 'tabA', - fields: { - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' }, - fieldC: { label: 'fieldC' }, - fieldD: { label: 'fieldD' } - }, - preFilter: function(args) { - return ['fieldB', 'fieldC']; - }, - dataProvider: function (args) { - args.response.success({ - data: { - fieldA: 'fieldAContent', - fieldB: 'fieldBContent', - fieldC: 'fieldCContent', - fieldD: 'fieldDContent' - } - }); - - start(); - equal($detailView.find('tr').size(), 2, 'Correct fields rendered'); - equal($detailView.find('tr:first td:first').html(), 'fieldA', 'First field has correct label'); - equal($detailView.find('tr:first td:last').html(), 'fieldAContent', 'First field has correct content'); - equal($detailView.find('tr:last td:first').html(), 'fieldD', 'Last field has correct label'); - equal($detailView.find('tr:last td:last').html(), 'fieldDContent', 'Last field has correct content'); - } - } - } - }; - var $detailView = $('
'); - - stop(); - - $detailView.detailView(detailView); - }); - - test('Action', function() { - var detailView = { - actions: { - actionA: { - label: 'testActionA', - action: function(args) { - start(); - ok(args.response.success(), 'Call success from action A'); - }, - messages: { - confirm: function() { return 'testActionAConfirm'; }, - notification: function() { return 'testActionANotification'; } - } - }, - actionB: { - label: 'testActionB', - action: function(args) { - start(); - ok(args.response.success(), 'Call success from action B'); - }, - messages: { - confirm: function() { return 'testActionBConfirm'; }, - notification: function() { return 'testActionBNotification'; } - }, - notification: { - poll: function(args) { - start(); - ok(args.complete(), 'Call complete from async action B'); - } - } - } - }, - tabs: { - tabA: { - title: 'tabA', - fields: { - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' } - }, - dataProvider: function(args) { - args.response.success({ - data: { - fieldA: 'fieldAContent', - fieldB: 'fieldBContent' - } - }); - } - } - } - }; - var $detailView = $('
'); - - $detailView.detailView(detailView).appendTo('#qunit-fixture'); - - equal($detailView.find('.detail-actions').size(), 1, 'Action container present'); - equal($detailView.find('.detail-actions .action').size(), 2, 'Correct action count'); - equal($detailView.find('.detail-actions .action.actionA').size(), 1, 'actionA present'); - equal($detailView.find('.detail-actions .action.actionB').size(), 1, 'actionB present'); - - cloudStack.dialog.confirm = function(args) { - start(); - equal(args.message, 'testActionAConfirm', 'Correct confirmation message for action A'); - stop(); - - args.action(); // Perform action - }; - - cloudStack.ui.notifications.add = function(notification, success, successArgs) { - stop(); - equal(notification.desc, 'testActionANotification', 'Correct notification message for action A'); - start(); - }; - - $detailView.find('.detail-actions .action.actionA a').click(); // triggers action, not action's container - - cloudStack.dialog.confirm = function(args) { - start(); - equal(args.message, 'testActionBConfirm', 'Correct confirmation message for action B'); - stop(); - - args.action(); // Perform action - }; - - cloudStack.ui.notifications.add = function(notification, success, successArgs) { - start(); - equal(notification.desc, 'testActionBNotification', 'Correct notification message for action B'); - stop(); - notification.poll({ complete: function() { return true; } }); - }; - - $detailView.find('.detail-actions .action.actionB a').click(); // triggers action, not action's container - }); - - test('Action filter', function() { - var detailView = { - actions: { - actionA: { - label: 'testActionA', - action: function(args) {} - }, - actionB: { - label: 'testActionB', - action: function(args) {} - } - }, - tabs: { - tabA: { - title: 'tabA', - fields: { - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' } - }, - dataProvider: function(args) { - args.response.success({ - actionFilter: function() { - return ['actionA']; - }, - data: { - fieldA: 'fieldAContent', - fieldB: 'fieldBContent' - } - }); - } - } - } - }; - var $detailView = $('
'); - - $detailView.detailView(detailView).appendTo('#qunit-fixture'); - - equal($detailView.find('.detail-actions .action').size(), 1, 'Correct action count'); - equal($detailView.find('.detail-actions .action.actionA').size(), 1, 'actionA present'); - notEqual($detailView.find('.detail-actions .action.actionB').size(), 1, 'actionB not present'); - }); - - test('Refresh', function() { - var dataA = ['dataLoad1A', 'dataLoad2A']; - var dataB = ['dataLoad1B', 'dataLoad2B']; - var index = 0; - - var detailView = { - tabs: { - tabA: { - title: 'tabA', - fields: { - fieldA: { label: 'fieldA' } - }, - dataProvider: function(args) { - args.response.success({ data: { fieldA: dataA[index] }}); - start(); - equal($detailView.find('tr td:last').html(), dataA[index], 'Tab A data correct for load ' + (index + 1)); - index++; - } - }, - tabB: { - title: 'tabB', - fields: { - fieldB: { label: 'fieldB' } - }, - dataProvider: function(args) { - args.response.success({ data: { fieldB: dataB[index] }}); - start(); - equal($detailView.find('tr td:last').html(), dataB[index], 'Tab B data correct for load ' + (index + 1)); - index++; - } - } - } - }; - var $detailView = $('
'); - - stop(); - $detailView.detailView(detailView).appendTo('#qunit-fixture'); - - stop(); - $detailView.find('.button.refresh').click(); - - stop(); - index = 0; - $detailView.find('.ui-tabs-nav li.last a').click(); - - stop(); - $detailView.find('.button.refresh').click(); - }); - - test('View all, 1 section', function() { - var $browser = $('
').appendTo('#qunit-fixture'); - var detailView = { - $browser: $browser, - context: {}, - viewAll: { label: 'testListView', path: 'testListView' }, - tabs: { - tabA: { - title: 'tabA', - fields: [{ fieldA: { label: 'fieldA' }}], - dataProvider: function(args) { args.response.success({ data: { fieldA: 'fieldAContent' } }); start(); } - } - } - }; - var testListView = {}; - var $detailView = $('
').appendTo('#qunit-fixture'); - - $('
').attr('cloudStack-container', true).data('cloudStack-args', { - sections: { - testListView: testListView - } - }).appendTo('#qunit-fixture'); - - stop(); - - $.fn.cloudBrowser = function(cmd, args) {}; - $browser.cloudBrowser(); - $detailView.detailView(detailView); - - equal($detailView.find('.detail-group.actions td.view-all').size(), 1, 'Detail view has view all button'); - - stop(); - - $.fn.listView = function(args, options) { - start(); - ok(true, 'List view called'); - equal(args, testListView, 'Correct list view passed'); - ok(args.$browser.size(), 'Browser passed in args'); - ok($.isPlainObject(args.ref), 'Ref passed in args'); - equal(args.id, 'testListView', 'Correct section ID'); - - return this; - }; - - $.fn.cloudBrowser = function(cmd, args) { - start(); - equal(cmd, 'addPanel', 'Browser add panel called'); - stop(); - args.complete($('
')); - }; - - $detailView.find('.view-all a').click(); - }); - - test('View all, subsections', function() { - var $browser = $('
').appendTo('#qunit-fixture'); - var detailView = { - $browser: $browser, - context: {}, - viewAll: { label: 'testListView', path: 'testSection.listViewB' }, - tabs: { - tabA: { - title: 'tabA', - fields: [{ fieldA: { label: 'fieldA' }}], - dataProvider: function(args) { args.response.success({ data: { fieldA: 'fieldAContent' } }); start(); } - } - } - }; - var listViewA = {}; - var listViewB = {}; - var $detailView = $('
').appendTo('#qunit-fixture'); - - $('
').attr('cloudStack-container', true).data('cloudStack-args', { - sections: { - testSection: { - sections: { - listViewA: { listView: listViewA }, - listViewB: { listView: listViewB } - } - } - } - }).appendTo('#qunit-fixture'); - - stop(); - - $.fn.cloudBrowser = function(cmd, args) {}; - $browser.cloudBrowser(); - $detailView.detailView(detailView); - - equal($detailView.find('.detail-group.actions td.view-all').size(), 1, 'Detail view has view all button'); - - stop(); - - $.fn.listView = function(args, options) { - start(); - ok(true, 'List view called'); - equal(args.listView, listViewB, 'Correct list view passed'); - ok(args.$browser.size(), 'Browser passed in args'); - ok($.isPlainObject(args.ref), 'Ref passed in args'); - equal(args.id, 'testSection', 'Correct section ID'); - - return this; - }; - - $.fn.cloudBrowser = function(cmd, args) { - start(); - equal(cmd, 'addPanel', 'Browser add panel called'); - stop(); - args.complete($('
')); - }; - - $detailView.find('.view-all a').click(); - }); - - test('Pre-action', function() { - var detailView = { - actions: { - test: { - label: 'test', - preAction: function() { - start(); - ok(true, 'Pre-action called'); - - return false; - }, - action: function() { - ok(false, 'Action called; pre-action should have blocked it'); - }, - messages: { notification: function() { return 'notification'; }} - } - }, - tabs: { - test: { - title: 'test', - label: 'testAction', - fields: [{ - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' } - }], - dataProvider: function(args) { args.response.success({ data: {} }); } - } - } - }; - var $detailView = $('
'); - - stop(); - $detailView.detailView(detailView); - $detailView.find('.action.test a').click(); - }); - - test('Update data, from list view row', function() { - var detailView = { - section: 'testListView', - context: { - testListView: [{ - fieldA: 'fieldA-1', - fieldB: 'fieldB-1', - fieldC: 'fieldC-1' - }] - }, - actions: { - updateDataTestSync: { - label: 'updateDataTestSync', - preAction: function(args) { return true; }, - action: function(args) { - args.response.success({ - data: { - fieldA: 'fieldA-2', - fieldB: 'fieldB-2' - } - }); - - start(); - equal($detailView.data('view-args').context.testListView[0].fieldA, 'fieldA-2', 'Correct context value for fieldA'); - equal($detailView.data('view-args').context.testListView[0].fieldB, 'fieldB-2', 'Correct context value for fieldB'); - equal($detailView.data('view-args').context.testListView[0].fieldC, 'fieldC-1', 'Correct context value for fieldC'); - equal($detailView.find('tr.fieldA .value').html(), 'fieldA-2', 'Correct table value for fieldA'); - equal($detailView.find('tr.fieldB .value').html(), 'fieldB-2', 'Correct table value for fieldB'); - equal($detailView.find('tr.fieldC .value').html(), 'fieldC-1', 'Correct table value for fieldC'); - }, - messages: { notification: function() { return 'notification'; }} - } - }, - tabs: { - test: { - title: 'test', - fields: [{ - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' }, - fieldC: { label: 'fieldC' } - }], - dataProvider: function(args) { - args.response.success({ - data: args.context.testListView[0] - }); - } - } - } - }; - var $detailView = $('
'); - var $listView = $('
').addClass('list-view'); - var $listViewRow = $('
').data('json-obj', detailView.context.testListView[0]).appendTo($listView); - var $cloudStackContainer = $('
').attr('cloudStack-container', true).data('cloudStack-args', { - sections: { - testListView: {} - } - }).appendTo('#qunit-fixture'); - - $.fn.dataTable = function() { return this; }; - $.fn.listView = function(args1, args2) { - if (args1 == 'replaceItem') - args2.after(args2.$row.data('json-obj', args2.data)); - - return this; - }; - - cloudStack.ui.notifications.add = function(notification, complete) { - complete(); - }; - cloudStack.dialog.confirm = function(args) { - args.action(); - }; - $detailView.data('list-view-row', $listViewRow); - $detailView.detailView(detailView); - - stop(); - $detailView.find('.action.updateDataTestSync a').click(); - }); - - - test('Update data async, from list view row', function() { - var detailView = { - section: 'testListView', - context: { - testListView: [{ - fieldA: 'fieldA-1', - fieldB: 'fieldB-1', - fieldC: 'fieldC-1', - state: 'on' - }] - }, - actions: { - updateDataTestAsync: { - label: 'updateDataTestAsync', - preAction: function(args) { - start(); - ok(true, 'Pre-action called'); - equal($detailView.data('view-args').context.testListView[0].fieldA, 'fieldA-1', 'Pre-action: Correct context value for fieldA'); - equal($detailView.data('view-args').context.testListView[0].fieldB, 'fieldB-1', 'Pre-action: Correct context value for fieldB'); - equal($detailView.data('view-args').context.testListView[0].fieldC, 'fieldC-1', 'Pre-action: Correct context value for fieldC'); - stop(); - - return true; - }, - action: function(args) { - args.response.success(); - }, - messages: { notification: function() { return 'notification'; }}, - notification: { - poll: function(args) { - args.complete({ - data: { - fieldA: 'fieldA-2', - fieldB: 'fieldB-2', - state: 'off' - } - }); - - start(); - equal($detailView.data('view-args').context.testListView[0].fieldA, 'fieldA-2', 'Correct context value for fieldA'); - equal($detailView.data('view-args').context.testListView[0].fieldB, 'fieldB-2', 'Correct context value for fieldB'); - equal($detailView.data('view-args').context.testListView[0].fieldC, 'fieldC-1', 'Correct context value for fieldC'); - equal($detailView.find('tr.fieldA .value').html(), 'fieldA-2', 'Correct table value for fieldA'); - equal($detailView.find('tr.fieldB .value').html(), 'fieldB-2', 'Correct table value for fieldB'); - equal($detailView.find('tr.fieldC .value').html(), 'fieldC-1', 'Correct table value for fieldC'); - - equal($detailView.find('.action').size(), 1, 'Correct action count'); - equal($detailView.find('.action.updateDataTestAsync').size(), 1, 'updateDataTestAsync present'); - equal($detailView.find('.action.filteredAction').size(), 0, 'filteredAction not present'); - stop(); - } - } - }, - - filteredAction: { - label: 'filteredAction', - action: function() {}, - messages: { notification: function() { return 'notification'; } } - } - }, - tabs: { - test: { - title: 'test', - fields: [{ - fieldA: { label: 'fieldA' }, - fieldB: { label: 'fieldB' }, - fieldC: { label: 'fieldC' } - }], - dataProvider: function(args) { - args.response.success({ - data: args.context.testListView[0], - actionFilter: function(args) { - if (args.context.testListView[0].state == 'on') { - return ['updateDataTestAsync', 'filteredAction']; - } - - return ['updateDataTestAsync']; - } - }); - } - } - } - }; - var $detailView = $('
'); - var $listView = $('
').addClass('list-view'); - var $listViewRow = $('
').data('json-obj', detailView.context.testListView[0]).appendTo($listView); - var $cloudStackContainer = $('
').attr('cloudStack-container', true).data('cloudStack-args', { - sections: { - testListView: {} - } - }).appendTo('#qunit-fixture'); - - $.fn.dataTable = function() { return this; }; - $.fn.listView = function(args1, args2) { - if (args1 == 'replaceItem') - args2.after(args2.$row.data('json-obj', args2.data)); - - return this; - }; - - cloudStack.ui.notifications.add = function(notification, complete) { - notification.poll({ complete: complete }); - }; - cloudStack.dialog.confirm = function(args) { - args.action(); - }; - $detailView.data('list-view-row', $listViewRow); - $detailView.detailView(detailView); - - equal($detailView.find('.action').size(), 2, 'Correct action count'); - equal($detailView.find('.action.updateDataTestAsync').size(), 1, 'updateDataTestAsync present'); - equal($detailView.find('.action.filteredAction').size(), 1, 'filteredAction present'); - - stop(); - $detailView.find('.action.updateDataTestAsync a').click(); - $detailView.data('view-args').actions.updateDataTestAsync.preAction = function(args) { - start(); - equal($detailView.data('view-args').context.testListView[0].fieldA, 'fieldA-2', 'Pre-action: Correct context value for fieldA'); - equal($detailView.data('view-args').context.testListView[0].fieldB, 'fieldB-2', 'Pre-action: Correct context value for fieldB'); - equal($detailView.data('view-args').context.testListView[0].fieldC, 'fieldC-1', 'Pre-action: Correct context value for fieldC'); - ok(true, 'Pre-action called'); - - return false; - }; - $detailView.find('.action.updateDataTestAsync a').click(); - }); - - test('Update context', function() { - var detailView = { - context: { - listViewItemA: [ - { fieldA: 'fieldAContent' } - ] - // listViewItemB [not stored yet] - }, - - tabFilter: function(args) { - start(); - ok($.isArray(args.context.listViewItemB), 'updateContext called before tabFilter'); - stop(); - - return []; - }, - - // updateContext is executed every time a data provider is called - updateContext: function(args) { - start(); - ok(true, 'updateContext called'); - equal(args.context.listViewItemA[0].fieldA, 'fieldAContent', 'updateContext: Item A present in context'); - stop(); - - return { - listViewItemB: [ - { fieldB: 'fieldBContent' } - ] - }; - }, - - tabs: { - test: { - title: 'test', - fields: { fieldA: { label: 'fieldA'}, fieldB: { label: 'fieldB' }}, - dataProvider: function(args) { - start(); - equal(args.context.listViewItemA[0].fieldA, 'fieldAContent', 'dataProvider: Item A present in context'); - equal(args.context.listViewItemB[0].fieldB, 'fieldBContent', 'dataProvider: Item B present in context'); - } - } - } - }; - var $detailView = $('
'); - - stop(); - $detailView.detailView(detailView); - }); -}(jQuery)); diff --git a/ui/tests/test.listView.js b/ui/tests/test.listView.js deleted file mode 100644 index 3449ab29234..00000000000 --- a/ui/tests/test.listView.js +++ /dev/null @@ -1,527 +0,0 @@ -// 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. -(function($) { - module('List view', { - setup: function() { - $.fx.off = true; - cloudStack.debug = true; - }, - teardown: function() { - // Cleanup notification box - $('.notification-box').remove(); - } - }); - - test('Basic', function() { - var listView = { - listView: { - section: 'test123', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - dataProvider: function(args) { - args.response.success({ - data: [] - }); - } - } - }; - var $listView; - - ok($listView = $('
').listView(listView), 'Initialize list view'); - equal($listView.find('.list-view').size(), 1, 'List view has container div'); - equal($listView.find('.list-view.test123').size(), 1, 'Container div has section ID as CSS class'); - equal($listView.find('.list-view table').size(), 2, 'List view has split tables'); - equal($listView.find('.list-view .fixed-header table thead tr').size(), 1, 'List view has fixed table header'); - equal($listView.find('.list-view .fixed-header table thead th').size(), 2, 'List view has correct column headers'); - equal($listView.find('.list-view .fixed-header table thead th:first').html(), 'testFieldA', 'First header has correct label'); - ok($listView.find('.list-view .fixed-header table thead th:first').hasClass('fieldA'), 'First header has correct class'); - ok($listView.find('.list-view .fixed-header table thead th:last').hasClass('fieldB'), 'First header has correct class'); - equal($listView.find('.list-view .fixed-header table thead th:last').html(), 'testFieldB', 'First header has correct label'); - equal($listView.find('.list-view table tbody tr').size(), 1, 'List view has table body'); - equal($listView.find('.toolbar').size(), 1, 'List view has toolbar'); - equal($listView.find('.toolbar .text-search .search-bar input[type=text]').size(), 1, 'Toolbar has search box'); - equal($listView.find('.toolbar .text-search .search-bar input[type=text]').size(), 1, 'Toolbar has search box'); - equal($listView.find('.toolbar .text-search .button.search').size(), 1, 'Toolbar has search button'); - ok(!$listView.find('.toolbar .filters').size(), 'Toolbar doesn\'t have filters'); - }); - - test('Data provider', function() { - var $listView = $('
'); - - stop(); - $listView.listView({ - context: { - tests: [] - }, - listView: { - section: 'test', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - dataProvider: function(args) { - start(); - equal(args.page, 1, 'Correct page # passed'); - equal(args.filterBy.search.value, '', 'No search params specified'); - ok($.isArray(args.context.tests), 'Context passed'); - args.response.success({ - data: [ - { - fieldA: '1A', - fieldB: '1B' - }, - { - fieldA: '2A', - fieldB: '2B' - }, - { - fieldA: '3A', - fieldB: '3B' - } - ] - }); - stop(); - setTimeout(function() { - start(); - equal($listView.find('tbody tr').size(), 3, 'Data row count is correct'); - equal($listView.find('tbody tr:first td.fieldA span').html(), '1A', 'Correct table item value for first row'); - equal($listView.find('tbody tr:first td.fieldB span').html(), '1B', 'Correct table item value for first row'); - equal($listView.find('tbody tr:last td.fieldA span').html(), '3A', 'Correct table item value for last row'); - equal($listView.find('tbody tr:last td.fieldB span').html(), '3B', 'Correct table item value for last row'); - }); - } - } - }); - }); - - test('Pre-filter', function() { - var $listView = $('
'); - - stop(); - $listView.listView({ - listView: { - section: 'test', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' }, - fieldC: { label: 'testFieldC' } - }, - preFilter: function(args) { - return ['fieldC']; - }, - dataProvider: function(args) { - args.response.success({ - data: [ - { - fieldA: '1A', - fieldB: '1B', - fieldC: '1C' - } - ] - }); - setTimeout(function() { - start(); - equal($listView.find('thead th').size(), 2, 'Correct # of filtered columns present'); - equal($listView.find('tbody tr:first td').size(), 2, 'Correct # of body columns present'); - equal($listView.find('tbody tr:first td.fieldA span').html(), '1A', 'Correct table item value for data row'); - equal($listView.find('tbody tr:first td.fieldB span').html(), '1B', 'Correct table item value for data row'); - }); - } - } - }); - }); - - test('Section select', function() { - var $listView = $('
'); - - ok($listView.listView({ - sectionSelect: { - label: 'testSectionSelect' - }, - sections: { - sectionA: { - type: 'select', - title: 'sectionA', - listView: { - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - dataProvider: function(args) { - args.response.success({ - data: [ - { - fieldA: '1A', - fieldB: '1B' - }, - { - fieldA: '2A', - fieldB: '2B' - } - ] - }); - } - } - }, - - sectionB: { - type: 'select', - title: 'sectionB', - listView: { - fields: { - fieldC: { label: 'testFieldC' }, - fieldD: { label: 'testFieldD' }, - fieldE: { label: 'testFieldE' } - }, - dataProvider: function(args) { - args.response.success({ - data: [ - { - fieldC: '1C', - fieldD: '1D', - fieldE: '1E' - }, - { - fieldC: '2C', - fieldD: '2D', - fieldE: '2E' - }, - { - fieldC: '3C', - fieldD: '3D', - fieldE: '3E' - }, - { - fieldC: '4C', - fieldD: '4D', - fieldE: '4E' - } - ] - }); - } - } - } - } - })); - - equal($listView.find('.toolbar .section-switcher').size(), 1, - 'Section switcher present in toolbar'); - equal($listView.find('.toolbar .section-switcher .section-select select').size(), 1, - 'Section select present'); - equal($listView.find('.toolbar .section-switcher .section-select label').html(), - 'testSectionSelect' + ':', - 'Section select label is correct'); - equal($listView.find('.toolbar .section-switcher .section-select select option').size(), 2, - 'Selectable sections present as options'); - equal($listView.find('.toolbar .section-switcher .section-select select option:first').html(), 'sectionA', - 'First select has correct title'); - equal($listView.find('.toolbar .section-switcher .section-select select option:selected')[0], - $listView.find('.toolbar .section-switcher .section-select select option:first')[0], - 'First section option is selected by default'); - equal($listView.find('.toolbar .section-switcher .section-select select option:last').html(), 'sectionB', 'Last select has correct title'); - equal($listView.find('.list-view thead th').size(), 2, 'Correct list view column count present'); - equal($listView.find('.list-view thead th:first').html(), 'testFieldA', 'Column 1 is labeled correctly'); - equal($listView.find('.list-view thead th:last').html(), 'testFieldB', 'Column 2 is labeled correctly'); - equal($listView.find('.list-view tbody tr').size(), 2, 'Correct # of data rows present'); - equal($listView.find('.list-view tbody tr:first td').size(), 2, 'Correct # of data columns present'); - - $listView.find('.toolbar .section-switcher select').val('sectionB'); - stop(); - ok($listView.find('.toolbar .section-switcher select').change(), 'Change section'); - start(); - - equal($listView.find('.list-view thead th').size(), 3, 'Correct list view column count present'); - equal($listView.find('.list-view thead th:first').html(), 'testFieldC', 'Column 1 is labeled correctly'); - equal($($listView.find('.list-view thead th')[1]).html(), 'testFieldD', 'Column 2 is labeled correctly'); - equal($listView.find('.list-view thead th:last').html(), 'testFieldE', 'Column 3 is labeled correctly'); - equal($listView.find('.list-view tbody tr').size(), 4, 'Correct # of data rows present'); - equal($listView.find('.list-view tbody tr:first td').size(), 3, 'Correct # of data columns present'); - equal($listView.find('.list-view tbody tr:first td:first span').html(), '1C', 'First table cell has correct data'); - equal($listView.find('.list-view tbody tr:last td:last span').html(), '4E', 'Last table cell has correct data'); - - $listView.find('.toolbar .section-switcher select').val('sectionA'); - stop(); - ok($listView.find('.toolbar .section-switcher select').change(), 'Change section'); - start(); - equal($listView.find('.toolbar .section-switcher .section-select select option:last').html(), 'sectionB', 'Last select has correct title'); - equal($listView.find('.list-view thead th').size(), 2, 'Correct list view column count present'); - equal($listView.find('.list-view thead th:first').html(), 'testFieldA', 'Column 1 is labeled correctly'); - equal($listView.find('.list-view thead th:last').html(), 'testFieldB', 'Column 2 is labeled correctly'); - equal($listView.find('.list-view tbody tr').size(), 2, 'Correct # of data rows present'); - equal($listView.find('.list-view tbody tr:first td').size(), 2, 'Correct # of data columns present'); - equal($listView.find('.list-view tbody tr:first td:first span').html(), '1A', 'First table cell has correct data'); - equal($listView.find('.list-view tbody tr:last td:last span').html(), '2B', 'Last table cell has correct data'); - }); - - test('Basic sync action', function() { - var $cloudStack = $('
').appendTo('#qunit-fixture'); - var listView = { - listView: { - section: 'test123', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - actions: { - basicSync: { - label: 'basicAction', - messages: { - confirm: function() { - return 'basicActionConfirm'; - }, - notification: function() { - return 'basicActionNotification'; - } - }, - action: function(args) { - args.response.success(); - } - } - }, - dataProvider: function(args) { - args.response.success({ - data: [ - { - fieldA: '1A', - fieldB: '1B', - fieldC: '1C' - }, - { - fieldA: '2A', - fieldB: '2B', - fieldC: '2C' - } - ] - }); - } - } - }; - - // CloudStack object is needed for notification handling for actions - var cloudStack = { - sections: { - testActions: listView - }, - - home: 'testActions' - }; - - ok($cloudStack.cloudStack(cloudStack), 'Initialize cloudStack widget w/ list view'); - - var $listView = $cloudStack.find('.list-view'); - - equal($listView.find('table thead th').size(), 3, 'Correct header column count'); - equal($listView.find('table thead th.actions').size(), 1, 'Action header column present'); - equal($listView.find('table tbody tr:first td').size(), 3, 'Correct data column count'); - equal($listView.find('table tbody tr:first td.actions').size(), 1, 'Action data column present'); - equal($listView.find('table tbody tr:first td.actions .action').size(), 1, 'Correct action count'); - equal($listView.find('table tbody tr:first td.actions .action:first .icon').size(), 1, 'Action has icon'); - ok($listView.find('table tbody tr:first td.actions .action:first').hasClass('basicSync'), - 'First action has ID as CSS class'); - ok($listView.find('td.actions .action:first').click(), 'Click first action'); - equal($('.ui-dialog.confirm .message').html(), 'basicActionConfirm', 'Confirmation message present'); - - // Make sure dialog is cleaned up -- always put below all confirm tests - $(':ui-dialog, .overlay').appendTo('#qunit-fixture'); - - ok($('.ui-dialog.confirm .ui-button.ok').click(), 'Confirm action'); - equal($cloudStack.find('.notifications .total span').html(), '1', 'Notification total increased'); - equal($('.notification-box ul li').size(), 1, 'Notification list has 1 item'); - equal($('.notification-box ul li span').html(), 'basicActionNotification', 'Notification list item has correct label'); - ok($('.notification-box ul li').hasClass('pending'), 'Notification has pending state'); - stop(); - setTimeout(function() { - start(); - ok(!$('.notification-box ul li').hasClass('pending'), 'Notification has completed state'); - }); - }); - - test('Async action', function() { - var $cloudStack = $('
').appendTo('#qunit-fixture'); - var listView = { - listView: { - id: 'testAsyncListView', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - actions: { - asyncTest: { - label: 'asyncAction', - messages: { - confirm: function() { - return 'asyncActionConfirm'; - }, - notification: function() { - return 'asyncActionNotification'; - } - }, - action: function(args) { - ok($.isArray(args.context.testAsyncListView), 'List view context passed'); - args.response.success({ - _custom: { - jobId: 'job123' - } - }); - }, - notification: { - interval: 0, - poll: function(args) { - start(); - equal(args._custom.jobId, 'job123', 'Job ID passed correctly'); - args.complete(); - } - } - } - }, - dataProvider: function(args) { - args.response.success({ - data: [ - { - fieldA: '1A', - fieldB: '1B', - fieldC: '1C' - }, - { - fieldA: '2A', - fieldB: '2B', - fieldC: '2C' - } - ] - }); - } - } - }; - - // CloudStack object is needed for notification handling for actions - var cloudStack = { - sections: { - testActions: listView - }, - - home: 'testActions' - }; - - ok($cloudStack.cloudStack(cloudStack), 'Initialize cloudStack widget w/ list view'); - - var $listView = $cloudStack.find('.list-view'); - - equal($listView.find('table thead th').size(), 3, 'Correct header column count'); - equal($listView.find('table thead th.actions').size(), 1, 'Action header column present'); - equal($listView.find('table tbody tr:first td').size(), 3, 'Correct data column count'); - equal($listView.find('table tbody tr:first td.actions').size(), 1, 'Action data column present'); - equal($listView.find('table tbody tr:first td.actions .action').size(), 1, 'Correct action count'); - equal($listView.find('table tbody tr:first td.actions .action:first .icon').size(), 1, 'Action has icon'); - ok($listView.find('table tbody tr:first td.actions .action:first').hasClass('asyncTest'), - 'First action has ID as CSS class'); - ok($listView.find('td.actions .action:first').click(), 'Click first action'); - equal($('.ui-dialog.confirm .message').html(), 'asyncActionConfirm', 'Confirmation message present'); - - // Make sure dialog is cleaned up -- always put below all confirm tests - $(':ui-dialog, .overlay').appendTo('#qunit-fixture'); - - ok($('.ui-dialog.confirm .ui-button.ok').click(), 'Confirm action'); - equal($cloudStack.find('.notifications .total span').html(), '1', 'Notification total increased'); - equal($('.notification-box ul li').size(), 1, 'Notification list has 1 item'); - equal($('.notification-box ul li span').html(), 'asyncActionNotification', 'Notification list item has correct label'); - ok($('.notification-box ul li').hasClass('pending'), 'Notification has pending state'); - stop(); - }); - - test('Action filter', function() { - var $cloudStack = $('
').appendTo('#qunit-fixture'); - var listView = { - listView: { - id: 'testAsyncListView', - fields: { - fieldA: { label: 'testFieldA' }, - fieldB: { label: 'testFieldB' } - }, - actions: { - actionA: { - label: 'actionA', - messages: { - confirm: function() { return ''; }, - notification: function() { return ''; } - }, - action: function(args) { args.response.success(); } - }, - actionB: { - label: 'actionB [HIDDEN]', - messages: { - confirm: function() { return ''; }, - notification: function() { return ''; } - }, - action: function(args) { args.response.success(); } - }, - actionC: { - label: 'actionC', - messages: { - confirm: function() { return ''; }, - notification: function() { return ''; } - }, - action: function(args) { args.response.success(); } - } - }, - dataProvider: function(args) { - args.response.success({ - actionFilter: function() { - return ['actionA', 'actionC']; - }, - data: [ - { - fieldA: '1A', - fieldB: '1B', - fieldC: '1C' - }, - { - fieldA: '2A', - fieldB: '2B', - fieldC: '2C' - } - ] - }); - } - } - }; - - // CloudStack object is needed for notification handling for actions - var cloudStack = { - sections: { - testActions: listView - }, - - home: 'testActions' - }; - - ok($cloudStack.cloudStack(cloudStack), 'Initialize cloudStack widget w/ list view'); - - var $listView = $cloudStack.find('.list-view'); - - equal($listView.find('table thead th').size(), 3, 'Correct header column count'); - equal($listView.find('table thead th.actions').size(), 1, 'Action header column present'); - equal($listView.find('table tbody tr:first td.actions').size(), 1, 'Action data column present'); - equal($listView.find('table tbody tr:first td.actions .action').size(), 3, 'Correct action count (all)'); - equal($listView.find('table tbody tr:first td.actions .action:not(.disabled)').size(), 2, 'Correct action count (enabled)'); - ok($listView.find('table tbody tr:first td.actions .action:first').hasClass('actionA'), - 'First action has correct ID'); - ok($listView.find('table tbody tr:first td.actions .action:last').hasClass('actionC'), - 'Last action has correct ID'); - }); -}(jQuery)); diff --git a/ui/tests/test.multiEdit.js b/ui/tests/test.multiEdit.js deleted file mode 100644 index aea072935fe..00000000000 --- a/ui/tests/test.multiEdit.js +++ /dev/null @@ -1,55 +0,0 @@ -// 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. -(function($) { - module('Mutli-edit'); - - test('Basic', function() { - var multiEdit = { - fields: { - fieldA: { edit: true, label: 'fieldA' }, - fieldB: { edit: true, label: 'fieldB' }, - add: { label: 'add', addButton: true } - }, - add: { - label: 'addAction', - action: function() {} - }, - dataProvider: function() {} - }; - var $multiEdit = $('
'); - - ok($multiEdit.multiEdit(multiEdit), 'Initialize multi-edit'); - equal($multiEdit.find('div.multi-edit').size(), 1, 'Main container div correct'); - equal($multiEdit.find('.multi-edit form').size(), 1, 'Multi-edit has form'); - equal($multiEdit.find('.multi-edit form table.multi-edit').size(), 1, 'Form has table'); - equal($multiEdit.find('.multi-edit form table thead tr').size(), 1, 'Header present'); - equal($multiEdit.find('.multi-edit form table tbody tr').size(), 1, 'Form body present'); - equal($multiEdit.find('.multi-edit .data .data-body').size(), 1, 'Data body present'); - - // Header items - equal($multiEdit.find('.multi-edit form table thead th.fieldA[rel=fieldA]').html(), 'fieldA', 'fieldA has correct header'); - equal($multiEdit.find('.multi-edit form table thead th.fieldB[rel=fieldB]').html(), 'fieldB', 'fieldB has correct header'); - equal($multiEdit.find('.multi-edit form table thead th.add[rel=add]').html(), 'add', 'Add action column has correct header'); - - // Form items - equal($multiEdit.find('.multi-edit form table tbody td.fieldA[rel=fieldA] input[name=fieldA]').size(), 1, 'fieldA has correct input'); - equal($multiEdit.find('.multi-edit form table tbody td.fieldA[rel=fieldA] input[type=text]').size(), 1, 'fieldA has text-based input'); - equal($multiEdit.find('.multi-edit form table tbody td.fieldB[rel=fieldB] input[name=fieldB]').size(), 1, 'fieldB has correct input'); - equal($multiEdit.find('.multi-edit form table tbody td.fieldB[rel=fieldB] input[type=text]').size(), 1, 'fieldB has text-based input'); - equal($multiEdit.find('.multi-edit form table tbody td.add[rel=add] .button.add-vm').html(), 'addAction', 'Add action column has correct content'); - }); -}(jQuery)); diff --git a/ui/tests/test.notifications.js b/ui/tests/test.notifications.js deleted file mode 100644 index b0ce313e5cd..00000000000 --- a/ui/tests/test.notifications.js +++ /dev/null @@ -1,107 +0,0 @@ -// 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. -(function($) { - var $notifications, $notificationBox, - $cloudStack, cloudStack; - - module('Notifications', { - setup: function() { - $.fx.off = true; - - cloudStack = { - sections: { - home: { - show: function() { return $('
').addClass('test123'); } - }, - sectionA: { - show: function() { return $('
').addClass('notification123'); } - } - }, - - home: 'home' - }; - - $cloudStack = $('
').appendTo($('#qunit-fixture')); - ok($cloudStack.cloudStack(cloudStack), 'Basic widget initialized'); - - // Need to cleanup here -- not handled by widget - $('.notification-box').remove(); - - $notifications = $('
').appendTo($cloudStack); - ok($notifications.notifications(), 'Initialize notifications widget'); - $notificationBox = $('.notification-box'); - } - }); - - test('Widget setup', function() { - ok($notifications.hasClass('notifications'), 'Correct styling assigned'); - equal($notificationBox.size(), 1, 'Notification box present'); - }); - - test('Add notification via widget', function() { - stop(); - $notifications.notifications('add', { // Basic notification - desc: 'testNotification123', - interval: 0, - poll: function(args) { - var $li = $notificationBox.find('li'); - - start(); - equal($li.size(), 1, 'Notification added to list'); - equal($li.find('span').html(), 'testNotification123', 'Notification description correct'); - ok($li.hasClass('pending'), 'Notification item has pending state'); - ok($notificationBox.find('.button.clear-list').click(), 'Clear list button click'); - equal($notificationBox.find('li').size(), 1, 'Notification list still has correct number of items'); - args.complete(); - ok(!$li.hasClass('pending'), 'Notification item has non-pending (complete) state'); - - stop(); - $notifications.notifications('add', { // More comprehensive notification - desc: 'testNotification456', - interval: 0, - _custom: { - attrA: '123', - attrB: '456' - }, - section: 'sectionA', - poll: function(args) { - var $li = $notificationBox.find('li'); - - start(); - equal($li.size(), 2, 'Notification list is correct'); - ok($.isPlainObject(args._custom), '_custom present'); - equal(args._custom.attrA, '123', '_custom attr A correct'); - equal(args._custom.attrB, '456', '_custom attr B correct'); - ok($li.filter(':last').hasClass('pending'), 'New notification item has pending state'); - ok(!$li.filter(':first').hasClass('pending'), 'First notification item still has non-pending (complete) state'); - ok($notificationBox.find('.button.clear-list').click(), 'Clear list button click'); - ok(!$notificationBox.find('li:first').is(':visible'), 'First (completed) notification item cleared'); - args.complete(); - ok(!$li.hasClass('pending'), 'All notifications item has non-pending (complete) state'); - equal($li.filter(':last').data('notification-section'), 'sectionA', 'Section data is correct in last notification'); - equal($li.filter(':first').find('span').html(), 'testNotification123', 'First notification description correct'); - equal($li.filter(':last').find('span').html(), 'testNotification456', 'Second notification description correct'); - $li.filter(':last').find('span').click(); - equal($cloudStack.find('.notification123').size(), 1, 'Notification item text goes to correct section on click'); - ok($li.filter(':last').find('.remove').click(), 'Remove first item'); - equal($notificationBox.find('li').size(), 0, 'Notification list has no items anymore'); - } - }); - } - }); - }); -}(jQuery)); From 68b8891c620e78009ec4dbcbd326e4bbfa79da4e Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 14 Jan 2014 11:21:25 -0800 Subject: [PATCH 007/180] Removed all reminants of the IdentityService. Created the KeysManager to move the management of keys out of management server --- api/src/com/cloud/server/ResourceTag.java | 38 ++- .../org/apache/cloudstack/api/BaseCmd.java | 9 +- .../cloudstack/api/IdentityService.java | 23 -- awsapi/pom.xml | 4 - deps/XenServerJava/pom.xml | 1 - ...spring-engine-schema-core-daos-context.xml | 1 - engine/storage/integration-test/pom.xml | 2 - .../framework/config/ConfigDepot.java | 2 + .../config/impl/ConfigDepotImpl.java | 8 +- framework/security/pom.xml | 8 +- ...spring-framework-security-core-context.xml | 1 + .../framework/security/keys/KeysManager.java | 21 +- .../security/keys/KeysManagerImpl.java | 127 ++++++++ plugins/hypervisors/hyperv/pom.xml | 1 - plugins/hypervisors/kvm/pom.xml | 2 - plugins/hypervisors/xen/pom.xml | 2 - .../resources/components-example.xml | 1 - .../network-elements/juniper-contrail/pom.xml | 2 - .../IntegrationTestConfiguration.java | 5 +- server/pom.xml | 1 - .../spring-server-core-managers-context.xml | 4 - server/src/com/cloud/api/ApiDBUtils.java | 8 - .../src/com/cloud/configuration/Config.java | 3 - .../AgentBasedConsoleProxyManager.java | 12 +- .../com/cloud/consoleproxy/AgentHookBase.java | 25 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 70 ++--- .../com/cloud/server/ManagementServer.java | 8 - .../cloud/server/ManagementServerImpl.java | 73 ----- .../cloud/servlet/ConsoleProxyServlet.java | 27 +- .../cloud/tags/TaggedResourceManagerImpl.java | 277 ++++++------------ .../uuididentity/IdentityServiceImpl.java | 44 --- .../cloud/uuididentity/dao/IdentityDao.java | 38 --- .../uuididentity/dao/IdentityDaoImpl.java | 241 --------------- .../test/resources/network-mgr-component.xml | 1 - services/console-proxy-rdp/rdpconsole/pom.xml | 1 - systemvm/pom.xml | 3 - 36 files changed, 337 insertions(+), 757 deletions(-) delete mode 100644 api/src/org/apache/cloudstack/api/IdentityService.java rename server/src/com/cloud/uuididentity/dao/IdentityVO.java => framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java (50%) create mode 100644 framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java delete mode 100644 server/src/com/cloud/uuididentity/IdentityServiceImpl.java delete mode 100644 server/src/com/cloud/uuididentity/dao/IdentityDao.java delete mode 100644 server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 89458fc9614..41931f0949b 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -24,25 +24,49 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit // FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code public enum ResourceObjectType { - UserVm(true, true), Template(true, true), ISO(true, false), Volume(true, true), Snapshot(true, false), Network(true, true), Nic(false, true), LoadBalancer(true, true), PortForwardingRule( - true, true), FirewallRule(true, true), SecurityGroup(true, false), PublicIpAddress(true, true), Project(true, false), Vpc(true, true), NetworkACL(true, true), StaticRoute( - true, false), VMSnapshot(true, false), RemoteAccessVpn(true, true), Zone(false, true), ServiceOffering(false, true), Storage(false, true), PrivateGateway(false, - true), NetworkACLList(false, true), VpnGateway(false, true), CustomerGateway(false, true), VpnConnection(false, true), User(true, true), DiskOffering(false, true); + UserVm(true, true), + Template(true, true), + ISO(true, false), + Volume(true, true), + Snapshot(true, false), + Network(true, true), + Nic(false, true), + LoadBalancer(true, true), + PortForwardingRule(true, true), + FirewallRule(true, true), + SecurityGroup(true, false), + PublicIpAddress(true, true), + Project(true, false), + Vpc(true, true), + NetworkACL(true, true), + StaticRoute(true, false), + VMSnapshot(true, false), + RemoteAccessVpn(true, true), + Zone(false, true), + ServiceOffering(false, true), + Storage(false, true), + PrivateGateway(false, true), + NetworkACLList(false, true), + VpnGateway(false, true), + CustomerGateway(false, true), + VpnConnection(false, true), + User(true, true), + DiskOffering(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; - this.metadataSupport = resourceMetadataSupport; + metadataSupport = resourceMetadataSupport; } private final boolean resourceTagsSupport; private final boolean metadataSupport; public boolean resourceTagsSupport() { - return this.resourceTagsSupport; + return resourceTagsSupport; } public boolean resourceMetadataSupport() { - return this.metadataSupport; + return metadataSupport; } } diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 0cfb9509395..4229ec9302b 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -26,6 +26,8 @@ import java.util.regex.Pattern; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; @@ -33,7 +35,6 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.usage.UsageService; -import org.apache.log4j.Logger; import com.cloud.configuration.ConfigurationService; import com.cloud.domain.Domain; @@ -153,8 +154,6 @@ public abstract class BaseCmd { @Inject public ResourceLimitService _resourceLimitService; @Inject - public IdentityService _identityService; - @Inject public StorageNetworkService _storageNetworkService; @Inject public TaggedResourceService _taggedResourceService; @@ -358,11 +357,11 @@ public abstract class BaseCmd { } public void setFullUrlParams(Map map) { - this.fullUrlParams = map; + fullUrlParams = map; } public Map getFullUrlParams() { - return this.fullUrlParams; + return fullUrlParams; } public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { diff --git a/api/src/org/apache/cloudstack/api/IdentityService.java b/api/src/org/apache/cloudstack/api/IdentityService.java deleted file mode 100644 index 8451945ef81..00000000000 --- a/api/src/org/apache/cloudstack/api/IdentityService.java +++ /dev/null @@ -1,23 +0,0 @@ -// 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; - -public interface IdentityService { - Long getIdentityId(String tableName, String identityString); - - String getIdentityUuid(String tableName, String identityString); -} diff --git a/awsapi/pom.xml b/awsapi/pom.xml index f0312309b98..cb0a88df7d1 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -223,7 +223,6 @@ org.slf4j slf4j-api - 1.6.1 runtime @@ -271,8 +270,6 @@ org.bouncycastle bcprov-jdk16 - - 1.45 runtime @@ -320,7 +317,6 @@ org.apache.maven.plugins maven-checkstyle-plugin - ${cs.checkstyle.version} none diff --git a/deps/XenServerJava/pom.xml b/deps/XenServerJava/pom.xml index 5c885b49808..9bba24ba4e1 100644 --- a/deps/XenServerJava/pom.xml +++ b/deps/XenServerJava/pom.xml @@ -40,7 +40,6 @@ org.apache.maven.plugins maven-checkstyle-plugin - ${cs.checkstyle.version} none diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 6dd1d4b491c..1a400e049e0 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -171,7 +171,6 @@ - diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index e002ab3345c..7bb27e060e4 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -119,8 +119,6 @@ org.apache.httpcomponents httpclient - - 4.2.2 compile diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java index 7df00493d45..50e9d898a50 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java @@ -27,4 +27,6 @@ public interface ConfigDepot { ConfigKey get(String paramName); Set> getConfigListByScope(String scope); + + void set(ConfigKey key, T value); } diff --git a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java b/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java index 2f6e524e860..929b299be7c 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java @@ -172,7 +172,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { @Inject public void setScopedStorages(List scopedStorages) { - this._scopedStorages = scopedStorages; + _scopedStorages = scopedStorages; } public List getConfigurables() { @@ -181,7 +181,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { @Inject public void setConfigurables(List configurables) { - this._configurables = configurables; + _configurables = configurables; } @Override @@ -189,4 +189,8 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { return _scopeLevelConfigsMap.get(ConfigKey.Scope.valueOf(scope)); } + @Override + public void set(ConfigKey key, T value) { + _configDao.update(key.key(), value.toString()); + } } diff --git a/framework/security/pom.xml b/framework/security/pom.xml index a5fa5f07a51..42627f524a8 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -25,7 +25,7 @@ cloudstack-framework 4.4.0-SNAPSHOT ../pom.xml - + org.apache.cloudstack @@ -42,6 +42,10 @@ cloud-framework-ipc ${project.version} + + commons-codec + commons-codec + org.apache.cloudstack cloud-framework-db @@ -51,6 +55,6 @@ org.apache.cloudstack cloud-framework-config ${project.version} - + diff --git a/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml b/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml index 3775565aeea..fe05bc11bb8 100644 --- a/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml +++ b/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml @@ -28,4 +28,5 @@ > + diff --git a/server/src/com/cloud/uuididentity/dao/IdentityVO.java b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java similarity index 50% rename from server/src/com/cloud/uuididentity/dao/IdentityVO.java rename to framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java index c40f40bc702..d6d2e0149d2 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityVO.java +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java @@ -14,12 +14,25 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.uuididentity.dao; +package org.apache.cloudstack.framework.security.keys; -import javax.persistence.Entity; +import org.apache.cloudstack.framework.config.ConfigKey; /** + * + * Started this file to manage keys. Will be needed by other services. + * */ -@Entity -public class IdentityVO { +public interface KeysManager { + final ConfigKey EncryptionKey = new ConfigKey("Hidden", String.class, "security.encryption.key", null, "base64 encoded key data", false); + final ConfigKey EncryptionIV = new ConfigKey("Hidden", String.class, "security.encryption.iv", null, "base64 encoded IV data", false); + final ConfigKey HashKey = new ConfigKey("Hidden", String.class, "security.hash.key", null, "for generic key-ed hash", false); + + String getEncryptionKey(); + + String getEncryptionIV(); + + void resetEncryptionKeyIV(); + + String getHashKey(); } 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 new file mode 100644 index 00000000000..550bd155c95 --- /dev/null +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java @@ -0,0 +1,127 @@ +// 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.framework.security.keys; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.inject.Inject; +import javax.net.ssl.KeyManager; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.framework.config.ConfigDepot; +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.framework.config.impl.ConfigurationVO; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +/** + * To be perfectly honest, I'm not sure why we need this class. This used + * to be in ManagementServerImpl. I moved the functionality because it seems + * many features will need this. However, the right thing will be for setup + * and upgrade to take care of key generation. Here, the methods appear to + * mainly be used for dynamic generation. I added this class because after + * talking to Kelven, we think there will be other functionalities we need + * to centralize to this class. We'll see how that works out. + * + * There's multiple problems here that we need to fix. + * - Multiple servers can be generating keys. This is not atomic. + * - The functionality of generating the keys should be moved over to setup/upgrade. + * + */ +public class KeysManagerImpl implements KeysManager, Configurable { + private static final Logger s_logger = Logger.getLogger(KeysManagerImpl.class); + + @Inject + ConfigurationDao _configDao; + @Inject + ConfigDepot _configDepot; + + @Override + public String getHashKey() { + String value = HashKey.value(); + if (value == null) { + _configDepot.set(HashKey, getBase64EncodedRandomKey(128)); + } + + return HashKey.value(); + } + + @Override + public String getEncryptionKey() { + String value = EncryptionKey.value(); + if (value == null) { + _configDepot.set(EncryptionKey, getBase64EncodedRandomKey(128)); + } + return EncryptionKey.value(); + } + + @Override + public String getEncryptionIV() { + String value = EncryptionIV.value(); + if (value == null) { + _configDepot.set(EncryptionIV, getBase64EncodedRandomKey(128)); + } + return EncryptionIV.value(); + } + + private static String getBase64EncodedRandomKey(int nBits) { + SecureRandom random; + try { + random = SecureRandom.getInstance("SHA1PRNG"); + byte[] keyBytes = new byte[nBits / 8]; + random.nextBytes(keyBytes); + return Base64.encodeBase64URLSafeString(keyBytes); + } catch (NoSuchAlgorithmException e) { + s_logger.error("Unhandled exception: ", e); + } + return null; + } + + @Override + @DB + public void resetEncryptionKeyIV() { + + SearchBuilder sb = _configDao.createSearchBuilder(); + sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.done(); + + SearchCriteria sc = sb.create(); + sc.setParameters("name1", EncryptionKey.key()); + sc.setParameters("name2", EncryptionIV.key()); + + _configDao.expunge(sc); + } + + @Override + public String getConfigComponentName() { + return KeyManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {EncryptionKey, EncryptionIV, HashKey}; + } + +} diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index 162fd641023..fca7cd93680 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -90,7 +90,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.12 diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 81cc372116e..5eba1e08f83 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -67,7 +67,6 @@ org.apache.maven.plugins maven-dependency-plugin - 2.5.1 copy-dependencies @@ -85,7 +84,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.14 **/Qemu*.java diff --git a/plugins/hypervisors/xen/pom.xml b/plugins/hypervisors/xen/pom.xml index 7011218bdbc..39c0908070e 100644 --- a/plugins/hypervisors/xen/pom.xml +++ b/plugins/hypervisors/xen/pom.xml @@ -33,8 +33,6 @@ org.apache.httpcomponents httpclient - - 4.2.2 compile diff --git a/plugins/network-elements/dns-notifier/resources/components-example.xml b/plugins/network-elements/dns-notifier/resources/components-example.xml index 418835a299f..5977387a28b 100755 --- a/plugins/network-elements/dns-notifier/resources/components-example.xml +++ b/plugins/network-elements/dns-notifier/resources/components-example.xml @@ -185,7 +185,6 @@ under the License. - diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 7b377a0cb59..ae6961e10a2 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -85,7 +85,6 @@ com.google.guava guava - ${cs.guava.version} net.juniper.contrail @@ -95,7 +94,6 @@ mysql mysql-connector-java - ${cs.mysql.version} provided diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java index 2a2babc67aa..416653d0a53 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java @@ -21,6 +21,7 @@ import java.io.IOException; import javax.inject.Inject; +import org.eclipse.jetty.security.IdentityService; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -42,7 +43,6 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl; -import org.apache.cloudstack.api.IdentityService; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; @@ -270,7 +270,6 @@ import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; -import com.cloud.uuididentity.dao.IdentityDaoImpl; import com.cloud.vm.ItWorkDaoImpl; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDaoImpl; @@ -298,7 +297,7 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, EventUtils.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, FirewallRulesDaoImpl.class, GuestOSCategoryDaoImpl.class, GuestOSDaoImpl.class, HostDaoImpl.class, HostDetailsDaoImpl.class, HostJoinDaoImpl.class, HostPodDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, HypervisorCapabilitiesDaoImpl.class, HypervisorGuruManagerImpl.class, - IdentityDaoImpl.class, ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, + ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, InstanceGroupVMMapDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, LBStickinessPolicyDaoImpl.class, LaunchPermissionDao.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, ManagementServerHostDaoImpl.class, MockAccountManager.class, NetworkACLDaoImpl.class, NetworkACLItemDaoImpl.class, NetworkACLManagerImpl.class, diff --git a/server/pom.xml b/server/pom.xml index 86e7b76a6c2..1646dc706df 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -189,7 +189,6 @@ maven-antrun-plugin - 1.7 generate-resource 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 c447057a42b..53a294e4e00 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 @@ -120,12 +120,8 @@ - - - - diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 4414e3b18f0..a23244b86f0 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -738,14 +738,6 @@ public class ApiDBUtils { return s_vmDao.findById(vmId); } - public static long getMemoryOrCpuCapacitybyHost(Long hostId, short capacityType) { - // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) - // so if this Utils class can have some kind of config rather than a static initializer (maybe from - // management server instantiation?) then maybe the management server method can be moved entirely - // into this utils class. - return s_ms.getMemoryOrCpuCapacityByHost(hostId, capacityType); - } - public static long getStorageCapacitybyPool(Long poolId, short capacityType) { // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) // so if this Utils class can have some kind of config rather than a static initializer (maybe from diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 0c581415f07..9117bc45e9d 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -1372,9 +1372,6 @@ public enum Config { "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.", null), //NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"), - HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null), - EncryptionKey("Hidden", ManagementServer.class, String.class, "security.encryption.key", null, "base64 encoded key data", null), - EncryptionIV("Hidden", ManagementServer.class, String.class, "security.encryption.iv", null, "base64 encoded IV data", null), RouterRamSize("Hidden", NetworkOrchestrationService.class, Integer.class, "router.ram.size", "128", "Default RAM for router VM (in MB).", null), DefaultPageSize("Advanced", ManagementServer.class, Long.class, "default.page.size", "500", "Default page size for API list* commands", null), diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 20366095048..3a1c387c344 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -25,6 +25,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import com.cloud.agent.AgentManager; @@ -53,7 +54,6 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol protected HostDao _hostDao; @Inject protected UserVmDao _userVmDao; - private String _instance; protected String _consoleProxyUrlDomain; @Inject private VMInstanceDao _instanceDao; @@ -74,11 +74,13 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol ConfigurationDao _configDao; @Inject ManagementServer _ms; + @Inject + KeysManager _keysMgr; public class AgentBasedAgentHook extends AgentHookBase { - public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, ms); + public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr); } @Override @@ -119,11 +121,9 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol _sslEnabled = true; } - _instance = configs.get("instance.name"); - _consoleProxyUrlDomain = configs.get("consoleproxy.url.domain"); - _listener = new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _ms)); + _listener = new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr)); _agentMgr.registerForHostEvents(_listener, true, true, false); if (s_logger.isInfoEnabled()) { diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java index 57fa43a6aaf..9dfffd4b98f 100644 --- a/server/src/com/cloud/consoleproxy/AgentHookBase.java +++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java @@ -26,6 +26,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import com.cloud.agent.AgentManager; @@ -45,7 +46,6 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; -import com.cloud.server.ManagementServer; import com.cloud.servlet.ConsoleProxyPasswordBasedEncryptor; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.utils.Ternary; @@ -65,17 +65,16 @@ public abstract class AgentHookBase implements AgentHook { ConfigurationDao _configDao; AgentManager _agentMgr; KeystoreManager _ksMgr; - ManagementServer _ms; final Random _random = new Random(System.currentTimeMillis()); - private String _hashKey; + KeysManager _keysMgr; - public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - this._instanceDao = instanceDao; - this._hostDao = hostDao; - this._agentMgr = agentMgr; - this._configDao = cfgDao; - this._ksMgr = ksMgr; - this._ms = ms; + public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + _instanceDao = instanceDao; + _hostDao = hostDao; + _agentMgr = agentMgr; + _configDao = cfgDao; + _ksMgr = ksMgr; + _keysMgr = keysMgr; } @Override @@ -230,15 +229,15 @@ public abstract class AgentHookBase implements AgentHook { // if we failed after reset, something is definitely wrong for (int i = 0; i < 2; i++) { - key = _ms.getEncryptionKey(); - iv = _ms.getEncryptionIV(); + key = _keysMgr.getEncryptionKey(); + iv = _keysMgr.getEncryptionIV(); keyIvPair = new ConsoleProxyPasswordBasedEncryptor.KeyIVPair(key, iv); if (keyIvPair.getIvBytes() == null || keyIvPair.getIvBytes().length != 16 || keyIvPair.getKeyBytes() == null || keyIvPair.getKeyBytes().length != 16) { s_logger.warn("Console access AES KeyIV sanity check failed, reset and regenerate"); - _ms.resetEncryptionKeyIV(); + _keysMgr.resetEncryptionKeyIV(); } else { break; } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 466ebc28beb..47330d7a826 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -36,6 +36,7 @@ import com.google.gson.GsonBuilder; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreDao; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import org.apache.cloudstack.framework.security.keystore.KeystoreVO; @@ -54,7 +55,6 @@ import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.manager.Commands; -import com.cloud.certificate.dao.CertificateDao; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.ZoneConfig; @@ -99,16 +99,13 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.DateUtil; @@ -182,57 +179,44 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject private ConfigurationDao _configDao; @Inject - private CertificateDao _certDao; - @Inject private VMInstanceDao _instanceDao; @Inject private TemplateDataStoreDao _vmTemplateStoreDao; @Inject private AgentManager _agentMgr; @Inject - private StorageManager _storageMgr; + private NetworkOrchestrationService _networkMgr; @Inject - NetworkOrchestrationService _networkMgr; + private NetworkModel _networkModel; @Inject - NetworkModel _networkModel; + private AccountManager _accountMgr; @Inject - AccountManager _accountMgr; + private ServiceOfferingDao _offeringDao; @Inject - ServiceOfferingDao _offeringDao; + private DiskOfferingDao _diskOfferingDao; @Inject - DiskOfferingDao _diskOfferingDao; + private NetworkOfferingDao _networkOfferingDao; @Inject - NetworkOfferingDao _networkOfferingDao; + private PrimaryDataStoreDao _storagePoolDao; @Inject - PrimaryDataStoreDao _storagePoolDao; + private UserVmDetailsDao _vmDetailsDao; @Inject - UserVmDetailsDao _vmDetailsDao; + private ResourceManager _resourceMgr; @Inject - ResourceManager _resourceMgr; + private NetworkDao _networkDao; @Inject - NetworkDao _networkDao; + private RulesManager _rulesMgr; @Inject - RulesManager _rulesMgr; + private IPAddressDao _ipAddressDao; @Inject - TemplateManager templateMgr; + private KeysManager _keysMgr; @Inject - IPAddressDao _ipAddressDao; - @Inject - ManagementServer _ms; - @Inject - ClusterManager _clusterMgr; + private VirtualMachineManager _itMgr; private ConsoleProxyListener _listener; private ServiceOfferingVO _serviceOffering; - NetworkOffering _publicNetworkOffering; - NetworkOffering _managementNetworkOffering; - NetworkOffering _linkLocalNetworkOffering; - - @Inject - private VirtualMachineManager _itMgr; - /* * private final ExecutorService _requestHandlerScheduler = Executors.newCachedThreadPool(new * NamedThreadFactory("Request-handler")); @@ -267,8 +251,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy public class VmBasedAgentHook extends AgentHookBase { - public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, ms); + public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr); } @Override @@ -884,14 +868,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy return l.size() < launchLimit; } - private HypervisorType currentHypervisorType(long dcId) { - List l = - _consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping, - VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdowned, VirtualMachine.State.Unknown); - - return l.size() > 0 ? l.get(0).getHypervisorType() : HypervisorType.Any; - } - private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo) { if (proxyCountInfo.getCount() * _capacityPerProxy - vmCountInfo.getCount() <= _standbyCapacity) { @@ -969,11 +945,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy } } else { if (s_logger.isDebugEnabled()) { - if (template == null) { - s_logger.debug("Zone host is ready, but console proxy template is null"); - } else { - s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); - } + s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); } } } @@ -1262,7 +1234,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy value = agentMgrConfigs.get("port"); _mgmtPort = NumbersUtil.parseInt(value, 8250); - _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _ms)); + _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr)); _agentMgr.registerForHostEvents(_listener, true, true, false); _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this); @@ -1677,13 +1649,11 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Override public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { - // TODO Auto-generated method stub return null; } @Override public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - // TODO Auto-generated method stub return null; } @@ -1704,7 +1674,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject public void setConsoleProxyAllocators(List consoleProxyAllocators) { - this._consoleProxyAllocators = consoleProxyAllocators; + _consoleProxyAllocators = consoleProxyAllocators; } } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index b93e0276584..5a6ca78a9eb 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -61,12 +61,4 @@ public interface ManagementServer extends ManagementService, PluggableService { public long getMemoryOrCpuCapacityByHost(Long hostId, short capacityType); - String getHashKey(); - - String getEncryptionKey(); - - String getEncryptionIV(); - - void resetEncryptionKeyIV(); - } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index a015b4b0c2f..59767f3fb15 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -19,8 +19,6 @@ package com.cloud.server; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.URLDecoder; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -756,9 +754,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject ClusterManager _clusterMgr; - private String _hashKey = null; - private String _encryptionKey = null; - private String _encryptionIV = null; @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @@ -942,15 +937,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return result; } - private Date massageDate(Date date, int hourOfDay, int minute, int second) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.set(Calendar.HOUR_OF_DAY, hourOfDay); - cal.set(Calendar.MINUTE, minute); - cal.set(Calendar.SECOND, second); - return cal.getTime(); - } - @Override public List searchForClusters(long zoneId, Long startIndex, Long pageSizeVal, String hypervisorType) { Filter searchFilter = new Filter(ClusterVO.class, "id", true, startIndex, pageSizeVal); @@ -3391,65 +3377,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return result; } - @Override - public String getHashKey() { - // although we may have race conditioning here, database transaction serialization should - // give us the same key - if (_hashKey == null) { - _hashKey = _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), getBase64EncodedRandomKey(128), Config.HashKey.getDescription()); - } - return _hashKey; - } - - @Override - public String getEncryptionKey() { - if (_encryptionKey == null) { - _encryptionKey = _configDao.getValueAndInitIfNotExist(Config.EncryptionKey.key(), Config.EncryptionKey.getCategory(), getBase64EncodedRandomKey(128), - Config.EncryptionKey.getDescription()); - } - return _encryptionKey; - } - - @Override - public String getEncryptionIV() { - if (_encryptionIV == null) { - _encryptionIV = _configDao.getValueAndInitIfNotExist(Config.EncryptionIV.key(), Config.EncryptionIV.getCategory(), getBase64EncodedRandomKey(128), - Config.EncryptionIV.getDescription()); - } - return _encryptionIV; - } - - @Override - @DB - public void resetEncryptionKeyIV() { - - SearchBuilder sb = _configDao.createSearchBuilder(); - sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.done(); - - SearchCriteria sc = sb.create(); - sc.setParameters("name1", Config.EncryptionKey.key()); - sc.setParameters("name2", Config.EncryptionIV.key()); - - _configDao.expunge(sc); - _encryptionKey = null; - _encryptionIV = null; - } - - private static String getBase64EncodedRandomKey(int nBits) { - SecureRandom random; - try { - random = SecureRandom.getInstance("SHA1PRNG"); - byte[] keyBytes = new byte[nBits / 8]; - random.nextBytes(keyBytes); - return Base64.encodeBase64URLSafeString(keyBytes); - } catch (NoSuchAlgorithmException e) { - s_logger.error("Unhandled exception: ", e); - } - return null; - } - @Override public SSHKeyPair createSSHKeyPair(CreateSSHKeyPairCmd cmd) { Account caller = CallContext.current().getCallingAccount(); diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index 0359a45c8b6..e0deaa21a49 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -43,7 +43,7 @@ import org.springframework.web.context.support.SpringBeanAutowiringSupport; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import org.apache.cloudstack.api.IdentityService; +import org.apache.cloudstack.framework.security.keys.KeysManager; import com.cloud.exception.PermissionDeniedException; import com.cloud.host.HostVO; @@ -81,13 +81,13 @@ public class ConsoleProxyServlet extends HttpServlet { @Inject ManagementServer _ms; @Inject - IdentityService _identityService; - @Inject EntityManager _entityMgr; @Inject UserVmDetailsDao _userVmDetailsDao; + @Inject + KeysManager _keysMgr; - static ManagementServer s_ms; + static KeysManager s_keysMgr; private final Gson _gson = new GsonBuilder().create(); @@ -97,7 +97,7 @@ public class ConsoleProxyServlet extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); - s_ms = _ms; + s_keysMgr = _keysMgr; } @Override @@ -114,7 +114,7 @@ public class ConsoleProxyServlet extends HttpServlet { return; } - if (_ms.getHashKey() == null) { + if (_keysMgr.getHashKey() == null) { s_logger.debug("Console/thumbnail access denied. Ticket service is not ready yet"); sendResponse(resp, "Service is not ready"); return; @@ -165,13 +165,15 @@ public class ConsoleProxyServlet extends HttpServlet { } String vmIdString = req.getParameter("vm"); - Long vmId = _identityService.getIdentityId("vm_instance", vmIdString); - if (vmId == null) { + VirtualMachine vm = _entityMgr.findByUuid(VirtualMachine.class, vmIdString); + if (vm == null) { s_logger.info("invalid console servlet command parameter: " + vmIdString); sendResponse(resp, ""); return; } + Long vmId = vm.getId(); + if (!checkSessionPermision(req, vmId, accountObj)) { sendResponse(resp, "Permission denied"); return; @@ -344,8 +346,8 @@ public class ConsoleProxyServlet extends HttpServlet { } private String getEncryptorPassword() { - String key = _ms.getEncryptionKey(); - String iv = _ms.getEncryptionIV(); + String key = _keysMgr.getEncryptionKey(); + String iv = _keysMgr.getEncryptionIV(); ConsoleProxyPasswordBasedEncryptor.KeyIVPair keyIvPair = new ConsoleProxyPasswordBasedEncryptor.KeyIVPair(key, iv); return _gson.toJson(keyIvPair); @@ -360,8 +362,7 @@ public class ConsoleProxyServlet extends HttpServlet { Ternary parsedHostInfo = parseHostInfo(portInfo.first()); String sid = vm.getVncPassword(); - String tag = String.valueOf(vm.getId()); - tag = _identityService.getIdentityUuid("vm_instance", tag); + String tag = vm.getUuid(); String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); @@ -440,7 +441,7 @@ public class ConsoleProxyServlet extends HttpServlet { long ts = normalizedHashTime.getTime(); ts = ts / 60000; // round up to 1 minute - String secretKey = s_ms.getHashKey(); + String secretKey = s_keysMgr.getHashKey(); SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); mac.init(keySpec); diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index a202ad28517..be896f063bd 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,70 +25,101 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import com.cloud.api.query.dao.ResourceTagJoinDao; -import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.DataCenterVO; import com.cloud.domain.Domain; +import com.cloud.domain.PartOf; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -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.rules.dao.PortForwardingRulesDao; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.NetworkACLItemDao; -import com.cloud.network.vpc.dao.NetworkACLDao; -import com.cloud.network.vpc.dao.StaticRouteDao; -import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.network.vpc.dao.VpcGatewayDao; -import com.cloud.projects.dao.ProjectDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.RemoteAccessVpnVO; +import com.cloud.network.dao.Site2SiteCustomerGatewayVO; +import com.cloud.network.dao.Site2SiteVpnConnectionVO; +import com.cloud.network.dao.Site2SiteVpnGatewayVO; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.PortForwardingRuleVO; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.network.vpc.NetworkACLItemVO; +import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.projects.ProjectVO; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.TaggedResourceService; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; -import com.cloud.user.dao.UserDao; +import com.cloud.user.OwnedBy; +import com.cloud.user.UserVO; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.DbUtil; -import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.uuididentity.dao.IdentityDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.snapshot.VMSnapshotVO; -@Component @Local(value = {TaggedResourceService.class}) public class TaggedResourceManagerImpl extends ManagerBase implements TaggedResourceService { public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class); - private static Map> s_daoMap = new HashMap>(); + private static final Map> s_typeMap = new HashMap>(); + static { + s_typeMap.put(ResourceObjectType.UserVm, UserVmVO.class); + s_typeMap.put(ResourceObjectType.Volume, VolumeVO.class); + s_typeMap.put(ResourceObjectType.Template, VMTemplateVO.class); + s_typeMap.put(ResourceObjectType.ISO, VMTemplateVO.class); + s_typeMap.put(ResourceObjectType.Snapshot, SnapshotVO.class); + s_typeMap.put(ResourceObjectType.Network, NetworkVO.class); + s_typeMap.put(ResourceObjectType.LoadBalancer, LoadBalancerVO.class); + s_typeMap.put(ResourceObjectType.PortForwardingRule, PortForwardingRuleVO.class); + s_typeMap.put(ResourceObjectType.FirewallRule, FirewallRuleVO.class); + s_typeMap.put(ResourceObjectType.SecurityGroup, SecurityGroupVO.class); + s_typeMap.put(ResourceObjectType.PublicIpAddress, IPAddressVO.class); + s_typeMap.put(ResourceObjectType.Project, ProjectVO.class); + s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class); + s_typeMap.put(ResourceObjectType.Nic, NicVO.class); + s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLVO.class); + s_typeMap.put(ResourceObjectType.StaticRoute, StaticRouteVO.class); + s_typeMap.put(ResourceObjectType.VMSnapshot, VMSnapshotVO.class); + s_typeMap.put(ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class); + s_typeMap.put(ResourceObjectType.Zone, DataCenterVO.class); + s_typeMap.put(ResourceObjectType.ServiceOffering, ServiceOfferingVO.class); + s_typeMap.put(ResourceObjectType.Storage, StoragePoolVO.class); + s_typeMap.put(ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class); + s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLItemVO.class); + s_typeMap.put(ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class); + s_typeMap.put(ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class); + s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class); + s_typeMap.put(ResourceObjectType.User, UserVO.class); + s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); + } + @Inject + EntityManager _entityMgr; @Inject AccountManager _accountMgr; @Inject @@ -96,95 +127,11 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Inject ResourceTagJoinDao _resourceTagJoinDao; @Inject - IdentityDao _identityDao; - @Inject DomainManager _domainMgr; - @Inject - UserVmDao _userVmDao; - @Inject - VolumeDao _volumeDao; - @Inject - VMTemplateDao _templateDao; - @Inject - SnapshotDao _snapshotDao; - @Inject - NetworkDao _networkDao; - @Inject - LoadBalancerDao _lbDao; - @Inject - PortForwardingRulesDao _pfDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - SecurityGroupDao _securityGroupDao; - @Inject - RemoteAccessVpnDao _vpnDao; - @Inject - IPAddressDao _publicIpDao; - @Inject - ProjectDao _projectDao; - @Inject - VpcDao _vpcDao; - @Inject - StaticRouteDao _staticRouteDao; - @Inject - VMSnapshotDao _vmSnapshotDao; - @Inject - NicDao _nicDao; - @Inject - NetworkACLItemDao _networkACLItemDao; - @Inject - DataCenterDao _dataCenterDao; - @Inject - ServiceOfferingDao _serviceOffDao; - @Inject - PrimaryDataStoreDao _storagePoolDao; - @Inject - VpcGatewayDao _vpcGatewayDao; - @Inject - NetworkACLDao _networkACLListDao; - @Inject - Site2SiteVpnGatewayDao _vpnGatewayDao; - @Inject - Site2SiteCustomerGatewayDao _customerGatewayDao; - @Inject - Site2SiteVpnConnectionDao _vpnConnectionDao; - @Inject - UserDao _userDao; - @Inject - DiskOfferingDao _diskOffDao; + @Override public boolean configure(String name, Map params) throws ConfigurationException { - s_daoMap.put(ResourceObjectType.UserVm, _userVmDao); - s_daoMap.put(ResourceObjectType.Volume, _volumeDao); - s_daoMap.put(ResourceObjectType.Template, _templateDao); - s_daoMap.put(ResourceObjectType.ISO, _templateDao); - s_daoMap.put(ResourceObjectType.Snapshot, _snapshotDao); - s_daoMap.put(ResourceObjectType.Network, _networkDao); - s_daoMap.put(ResourceObjectType.LoadBalancer, _lbDao); - s_daoMap.put(ResourceObjectType.PortForwardingRule, _pfDao); - s_daoMap.put(ResourceObjectType.FirewallRule, _firewallDao); - s_daoMap.put(ResourceObjectType.SecurityGroup, _securityGroupDao); - s_daoMap.put(ResourceObjectType.PublicIpAddress, _publicIpDao); - s_daoMap.put(ResourceObjectType.Project, _projectDao); - s_daoMap.put(ResourceObjectType.Vpc, _vpcDao); - s_daoMap.put(ResourceObjectType.Nic, _nicDao); - s_daoMap.put(ResourceObjectType.NetworkACL, _networkACLItemDao); - s_daoMap.put(ResourceObjectType.StaticRoute, _staticRouteDao); - s_daoMap.put(ResourceObjectType.VMSnapshot, _vmSnapshotDao); - s_daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDao); - s_daoMap.put(ResourceObjectType.Zone, _dataCenterDao); - s_daoMap.put(ResourceObjectType.ServiceOffering, _serviceOffDao); - s_daoMap.put(ResourceObjectType.Storage, _storagePoolDao); - s_daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDao); - s_daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDao); - s_daoMap.put(ResourceObjectType.VpnGateway, _vpnGatewayDao); - s_daoMap.put(ResourceObjectType.CustomerGateway, _customerGatewayDao); - s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDao); - s_daoMap.put(ResourceObjectType.User, _userDao); - s_daoMap.put(ResourceObjectType.DiskOffering, _diskOffDao); - return true; } @@ -200,59 +147,31 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override public long getResourceId(String resourceId, ResourceObjectType resourceType) { - GenericDao dao = s_daoMap.get(resourceType); - if (dao == null) { - throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType); + Class clazz = s_typeMap.get(resourceType); + Object entity = _entityMgr.findByUuid(clazz, resourceId); + if (entity != null) { + return ((InternalIdentity)entity).getId(); } - Class claz = DbUtil.getEntityBeanType(dao); - - Long identityId = null; - - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - identityId = _identityDao.getIdentityId(tableName, resourceId); - if (identityId != null) { - break; - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } - claz = claz.getSuperclass(); + entity = _entityMgr.findById(clazz, resourceId); + if (entity != null) { + return ((InternalIdentity)entity).getId(); } - - if (identityId == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); - } - return identityId; + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); } private Pair getAccountDomain(long resourceId, ResourceObjectType resourceType) { + Class clazz = s_typeMap.get(resourceType); - Pair pair = null; - GenericDao dao = s_daoMap.get(resourceType); - Class claz = DbUtil.getEntityBeanType(dao); - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - pair = _identityDao.getAccountDomainInfo(tableName, resourceId, resourceType); - if (pair.first() != null || pair.second() != null) { - break; - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } - claz = claz.getSuperclass(); + Object entity = _entityMgr.findById(clazz, resourceId); + Long accountId = null; + Long domainId = null; + if (entity instanceof OwnedBy) { + accountId = ((OwnedBy)entity).getAccountId(); } - Long accountId = pair.first(); - Long domainId = pair.second(); + if (entity instanceof PartOf) { + domainId = ((PartOf)entity).getDomainId(); + } if (accountId == null) { accountId = Account.ACCOUNT_ID_SYSTEM; @@ -327,32 +246,14 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override public String getUuid(String resourceId, ResourceObjectType resourceType) { - GenericDao dao = s_daoMap.get(resourceType); - Class claz = DbUtil.getEntityBeanType(dao); + Class clazz = s_typeMap.get(resourceType); - String identiyUUId = null; - - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - - claz = claz.getSuperclass(); - if (claz == Object.class) { - identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } + Object entity = _entityMgr.findById(clazz, resourceId); + if (entity != null && entity instanceof Identity) { + return ((Identity)entity).getUuid(); } - if (identiyUUId == null) { - return resourceId; - } - - return identiyUUId; + return resourceId; } @Override diff --git a/server/src/com/cloud/uuididentity/IdentityServiceImpl.java b/server/src/com/cloud/uuididentity/IdentityServiceImpl.java deleted file mode 100644 index 039bb318905..00000000000 --- a/server/src/com/cloud/uuididentity/IdentityServiceImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -// 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.uuididentity; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.springframework.stereotype.Component; - -import org.apache.cloudstack.api.IdentityService; - -import com.cloud.utils.component.ManagerBase; -import com.cloud.uuididentity.dao.IdentityDao; - -@Component -@Local(value = {IdentityService.class}) -public class IdentityServiceImpl extends ManagerBase implements IdentityService { - @Inject - private IdentityDao _identityDao; - - @Override - public Long getIdentityId(String tableName, String identityString) { - return _identityDao.getIdentityId(tableName, identityString); - } - - @Override - public String getIdentityUuid(String tableName, String identityString) { - return _identityDao.getIdentityUuid(tableName, identityString); - } -} diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/server/src/com/cloud/uuididentity/dao/IdentityDao.java deleted file mode 100644 index a0978fac17c..00000000000 --- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java +++ /dev/null @@ -1,38 +0,0 @@ -// 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.uuididentity.dao; - -import com.cloud.server.ResourceTag.ResourceObjectType; -import com.cloud.utils.Pair; -import com.cloud.utils.db.GenericDao; - -public interface IdentityDao extends GenericDao { - Long getIdentityId(String tableName, String identityString); - - String getIdentityUuid(String tableName, String identityString); - - void initializeDefaultUuid(String tableName); - - /** - * @param tableName - * @param identityId - * @param resourceType TODO - * @return - */ - Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType); -} diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java deleted file mode 100644 index 3475104dbc3..00000000000 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ /dev/null @@ -1,241 +0,0 @@ -// 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.uuididentity.dao; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.server.ResourceTag.ResourceObjectType; -import com.cloud.utils.Pair; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.TransactionLegacy; - -@Component -@Local(value = {IdentityDao.class}) -public class IdentityDaoImpl extends GenericDaoBase implements IdentityDao { - private static final Logger s_logger = Logger.getLogger(IdentityDaoImpl.class); - - public IdentityDaoImpl() { - } - - @Override - @DB - public Long getIdentityId(String tableName, String identityString) { - assert (tableName != null); - assert (identityString != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s`", tableName)); - pstmt.executeQuery(); - } catch (SQLException e) { - throw new InvalidParameterValueException("uuid field doesn't exist in table " + tableName); - } - - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName) - - // TODO : after graceful period, use following line turn on more secure check - // String.format("SELECT id FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", mapper.entityTableName()) - ); - - long id = 0; - try { - // TODO : use regular expression to determine - id = Long.parseLong(identityString); - } catch (NumberFormatException e) { - // this could happen when it is a uuid string, so catch and ignore it - } - - pstmt.setLong(1, id); - pstmt.setString(2, identityString); - - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - return rs.getLong(1); - } else { - if (id == -1L) - return id; - - throw new InvalidParameterValueException("Object " + tableName + "(uuid: " + identityString + ") does not exist."); - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - return null; - } - - @DB - @Override - public Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType) { - assert (tableName != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - Long domainId = null; - Long accountId = null; - //get domainId - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT domain_id FROM `%s` WHERE id=?", tableName)); - pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - if (rs.getLong(1) != 0) { - domainId = rs.getLong(1); - } - } - } catch (SQLException e) { - } - - //get accountId - try { - String account = "account_id"; - if (resourceType == ResourceObjectType.Project) { - account = "project_account_id"; - } - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT " + account + " FROM `%s` WHERE id=?", tableName)); - pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - if (rs.getLong(1) != 0) { - accountId = rs.getLong(1); - } - } - } catch (SQLException e) { - } - return new Pair(accountId, domainId); - } finally { - txn.close(); - } - } - - @DB - @Override - public String getIdentityUuid(String tableName, String identityString) { - assert (tableName != null); - assert (identityString != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s` WHERE id=? OR uuid=?", tableName) - // String.format("SELECT uuid FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", tableName) - ); - - long id = 0; - try { - // TODO : use regular expression to determine - id = Long.parseLong(identityString); - } catch (NumberFormatException e) { - // this could happen when it is a uuid string, so catch and ignore it - } - - pstmt.setLong(1, id); - pstmt.setString(2, identityString); - - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - String uuid = rs.getString(1); - if (uuid != null && !uuid.isEmpty()) - return uuid; - return identityString; - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - - return identityString; - } - - @Override - @DB - public void initializeDefaultUuid(String tableName) { - assert (tableName != null); - List l = getNullUuidRecords(tableName); - - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - txn.start(); - for (Long id : l) { - setInitialUuid(tableName, id); - } - txn.commit(); - } catch (SQLException e) { - txn.rollback(); - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - } - - @DB - List getNullUuidRecords(String tableName) { - List l = new ArrayList(); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT id FROM `%s` WHERE uuid IS NULL", tableName)); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - l.add(rs.getLong(1)); - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - return l; - } - - @DB - void setInitialUuid(String tableName, long id) throws SQLException { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - - PreparedStatement pstmtUpdate = null; - pstmtUpdate = txn.prepareAutoCloseStatement(String.format("UPDATE `%s` SET uuid=? WHERE id=?", tableName)); - - pstmtUpdate.setString(1, String.valueOf(id)); - pstmtUpdate.setLong(2, id); - pstmtUpdate.executeUpdate(); - } -} diff --git a/server/test/resources/network-mgr-component.xml b/server/test/resources/network-mgr-component.xml index b55a68b0fcf..a0ddce04c0c 100644 --- a/server/test/resources/network-mgr-component.xml +++ b/server/test/resources/network-mgr-component.xml @@ -174,7 +174,6 @@ under the License. - diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml index 5737a858a10..05585a1027a 100755 --- a/services/console-proxy-rdp/rdpconsole/pom.xml +++ b/services/console-proxy-rdp/rdpconsole/pom.xml @@ -72,7 +72,6 @@ org.bouncycastle bcprov-jdk16 - 1.46 diff --git a/systemvm/pom.xml b/systemvm/pom.xml index e8d43efb576..5de6452aa00 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -51,7 +51,6 @@ maven-assembly-plugin - 2.3 systemvm false @@ -71,7 +70,6 @@ maven-resources-plugin - 2.6 copy-resources @@ -102,7 +100,6 @@ maven-antrun-plugin - 1.7 build-cloud-scripts From 3ed605dc9068bc50106b479284933e2bd205240e Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 14 Jan 2014 13:37:35 -0800 Subject: [PATCH 008/180] Add basic list view test --- ui/tests/index.html | 44 ++++++++++++++++++++++++++++---- ui/tests/test.widget.listView.js | 42 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 ui/tests/test.widget.listView.js diff --git a/ui/tests/index.html b/ui/tests/index.html index 5539e0f5382..d44985c341e 100644 --- a/ui/tests/index.html +++ b/ui/tests/index.html @@ -31,14 +31,48 @@ under the License.

    test markup, will be hidden
    - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js new file mode 100644 index 00000000000..96f839db1e7 --- /dev/null +++ b/ui/tests/test.widget.listView.js @@ -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. + +module('List view', { + setup: function() { + window.pageSize = 20; + }, + teardown: function() { + delete window.pageSize; + } +}); + +test('Basic', function() { + var $listView = $('
    ').listView({ + listView: { + fields: {}, + dataProvider: function() {} + } + }).find('.list-view'); + var $toolbar = $listView.find('> .toolbar'); + var $table = $listView.find('> .data-table'); + + equal($listView.size(), 1, 'List view present'); + equal($toolbar.size(), 1, 'Toolbar present'); + equal($table.size(), 1, 'Data table div present'); + equal($table.find('> .fixed-header table thead tr').size(), 1, 'Fixed header present'); + equal($table.find('> table.body tbody').size(), 1, 'Body table present'); +}); From 0bff7056218cda564acfd1ae2080e50f37742deb Mon Sep 17 00:00:00 2001 From: Sachchidanand Vaidya Date: Mon, 13 Jan 2014 17:27:16 -0800 Subject: [PATCH 009/180] Add L3VPN isolation method for contrail plugin Signed-off-by: Sheng Yang --- .../com/cloud/network/PhysicalNetwork.java | 2 +- .../contrail/management/ContrailGuru.java | 26 ++++++++++++++++--- .../management/ManagementServerMock.java | 2 +- ui/scripts/ui-custom/zoneWizard.js | 5 +++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 5c348c21b7a..8cc214e894b 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -33,7 +33,7 @@ public interface PhysicalNetwork extends Identity, InternalIdentity { } public enum IsolationMethod { - VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL; + VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN; } public enum BroadcastDomainRange { diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index 079035b9864..3bc66d16acd 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -37,6 +37,9 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.network.Network; import com.cloud.network.Network.State; import com.cloud.network.NetworkProfile; @@ -47,6 +50,9 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.guru.NetworkGuru; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -68,12 +74,22 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { ContrailManager _manager; @Inject NicDao _nicDao; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + DataCenterDao _dcDao; private static final Logger s_logger = Logger.getLogger(ContrailGuru.class); private static final TrafficType[] TrafficTypes = {TrafficType.Guest}; - private boolean canHandle(NetworkOffering offering) { - return (offering.getName().equals(ContrailManager.offeringName)); + private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) { + if (networkType == NetworkType.Advanced + && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated + && physicalNetwork.getIsolationMethods().contains("L3VPN")) + return true; + + return false; } @Override @@ -83,7 +99,11 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { - if (!canHandle(offering)) { + // Check of the isolation type of the related physical network is L3VPN + 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 network = diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java index 806dd21a07f..cd7ac3537e8 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java @@ -331,7 +331,7 @@ public class ManagementServerMock { } } catch (InvalidParameterValueException e) { List isolationMethods = new ArrayList(); - isolationMethods.add("GRE"); + isolationMethods.add("L3VPN"); _znet = _networkService.createPhysicalNetwork(_zone.getId(), null, null, isolationMethods, BroadcastDomainRange.ZONE.toString(), _zone.getDomainId(), null, "znet"); diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 99aa3b9f20a..4091c035a19 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -723,7 +723,10 @@ }).html('VXLAN'), $('