Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss

This commit is contained in:
Likitha Shetty 2012-03-01 14:39:43 +05:30
commit 25db257a9a
13 changed files with 2082 additions and 48 deletions

View File

@ -322,9 +322,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
@Override
@DB
public void updateConfiguration(long userId, String name, String category, String value) {
if (value != null && (value.trim().isEmpty() || value.equals("null"))) {
value = null;
}
String validationMsg = validateConfigurationValue(name, value);
@ -448,29 +445,39 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (value == null) {
return _configDao.findByName(name);
}
if (value.trim().isEmpty() || value.equals("null")) {
value = null;
}
updateConfiguration(userId, name, config.getCategory(), value);
if (_configDao.getValue(name).equalsIgnoreCase(value)) {
String updatedValue = _configDao.getValue(name);
if ((value == null && updatedValue == null) || updatedValue.equalsIgnoreCase(value)) {
return _configDao.findByName(name);
} else {
throw new CloudRuntimeException("Unable to update configuration parameter " + name);
}
}
private String validateConfigurationValue(String name, String value) {
if (value == null) {
return null;
}
Config c = Config.getConfig(name);
value = value.trim();
if (c == null) {
s_logger.error("Missing configuration variable " + name + " in configuration table");
return "Invalid configuration variable.";
}
Class<?> type = c.getType();
if (value == null) {
if (type.equals(Boolean.class)) {
return "Please enter either 'true' or 'false'.";
}
return null;
}
value = value.trim();
if (type.equals(Boolean.class)) {
if (!(value.equals("true") || value.equals("false"))) {
s_logger.error("Configuration variable " + name + " is expecting true or false in stead of " + value);

View File

@ -4771,6 +4771,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
checkIfPhysicalNetworkIsDeletable(physicalNetworkId);
Transaction txn = Transaction.currentTxn();
txn.start();
// delete vlans for this zone
List<VlanVO> vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId);
for (VlanVO vlan : vlans) {
@ -4795,6 +4797,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
_pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId);
boolean success = _physicalNetworkDao.remove(physicalNetworkId);
txn.commit();
return success;
}

View File

@ -39,6 +39,7 @@ import com.cloud.configuration.Resource.ResourceOwnerType;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceCountVO;
import com.cloud.configuration.ResourceLimit;
import com.cloud.configuration.ResourceLimitVO;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceCountDao;
@ -205,6 +206,12 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
public long findCorrectResourceLimitForAccount(Account account, ResourceType type) {
long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited
//no limits for Admin accounts
if (_accountMgr.isAdmin(account.getType())) {
return max;
}
ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(account.getId(), ResourceOwnerType.Account, type);
// Check if limit is configured for account
@ -496,9 +503,14 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
if (accountId != null) {
Account account = _entityMgr.findById(Account.class, accountId);
if (account.getType() == Account.ACCOUNT_ID_SYSTEM) {
if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
throw new InvalidParameterValueException("Can't update system account");
}
//only Unlimited value is accepted if account is Admin
if (_accountMgr.isAdmin(account.getType()) && max.shortValue() != ResourceLimit.RESOURCE_UNLIMITED) {
throw new InvalidParameterValueException("Only " + ResourceLimit.RESOURCE_UNLIMITED + " limit is supported for Admin accounts");
}
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, account);

View File

@ -793,6 +793,16 @@ public class Upgrade2214to30 implements DbUpgrade {
ResultSet rs = null;
ResultSet rs1 = null;
try {
//check if switch_to_isolated is present; if not - skip this part of the code
try {
pstmt = conn
.prepareStatement("select switch_to_isolated from `cloud`.`networks`");
rs = pstmt.executeQuery();
} catch (Exception ex) {
s_logger.debug("switch_to_isolated field is not present in networks table");
return ;
}
// get all networks that need to be updated to the redundant network offerings
pstmt = conn
.prepareStatement("select id, network_offering_id from `cloud`.`networks` where switch_to_isolated=1");

233
ui/lib/qunit/qunit.css Normal file
View File

@ -0,0 +1,233 @@
/**
* QUnit v1.4.0pre - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 15px 15px 0 0;
-moz-border-radius: 15px 15px 0 0;
-webkit-border-top-right-radius: 15px;
-webkit-border-top-left-radius: 15px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-header label {
display: inline-block;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
box-shadow: inset 0px 2px 13px #999;
-moz-box-shadow: inset 0px 2px 13px #999;
-webkit-box-shadow: inset 0px 2px 13px #999;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
margin: 0.5em;
padding: 0.4em 0.5em 0.4em 0.5em;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #5E740B;
background-color: #fff;
border-left: 26px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 26px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 15px 15px;
-moz-border-radius: 0 0 15px 15px;
-webkit-border-bottom-right-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

1633
ui/lib/qunit/qunit.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -264,8 +264,7 @@
// Plug in hard-coded values specific to quick install
data: {
zone: {
networkType: 'Basic',
domain: 1,
networkType: 'Basic',
networkOfferingId: selectedNetworkOffering.id
},
pluginFrom: {

View File

@ -1546,13 +1546,21 @@
}
],
dataProvider: function(args) {
args.response.success(
{
actionFilter: vmActionfilter,
data: args.context.instances[0]
}
);
dataProvider: function(args) {
$.ajax({
url: createURL("listVirtualMachines&id=" + args.context.instances[0].id),
dataType: "json",
async: true,
success: function(json) {
var jsonObj = json.listvirtualmachinesresponse.virtualmachine[0];
args.response.success(
{
actionFilter: vmActionfilter,
data: jsonObj
}
);
}
});
}
},

View File

@ -52,8 +52,7 @@
* @param sectionID Section's ID to show
* @param args CloudStack3 configuration
*/
var showSection = function(sectionID, args) {
var $browser = $('#browser div.container');
var showSection = function(sectionID, args, $browser) {
var $navItem = $('#navigation').find('li').filter(function() {
return $(this).hasClass(sectionID);
});
@ -244,7 +243,7 @@
// User options
var $options = $('<div>').attr({ id: 'user-options' })
.appendTo($('#header'));
.appendTo($container.find('#header'));
$(['label.logout', 'label.help']).each(function() {
var $link = $('<a>')
.attr({ href: '#' })
@ -263,8 +262,8 @@
});
// Initialize browser
$('#browser div.container').cloudBrowser();
$('#navigation li')
$container.find('#browser div.container').cloudBrowser();
$container.find('#navigation li')
.filter(function() {
return $(this).hasClass(args.home);
})
@ -274,24 +273,26 @@
$.extend($.validator.messages, { required: _l('label.required') });
// Check for pending project invitations
cloudStack.projects.invitationCheck({
context: cloudStack.context,
response: {
success: function(args) {
if (!args.data.length) return;
var projectList = $.map(args.data, function(invitation) {
return '<li>' + invitation.project + '</li>';
}).join('');
if (args.projects) {
args.projects.invitationCheck({
context: cloudStack.context,
response: {
success: function(args) {
if (!args.data.length) return;
var projectList = $.map(args.data, function(invitation) {
return '<li>' + invitation.project + '</li>';
}).join('');
cloudStack.dialog.notice({
message: _l('message.pending.projects.1') +
'<ul>' + projectList + '</ul>' +
'<p>' + _l('message.pending.projects.2') + '</p>'
});
cloudStack.dialog.notice({
message: _l('message.pending.projects.1') +
'<ul>' + projectList + '</ul>' +
'<p>' + _l('message.pending.projects.2') + '</p>'
});
}
}
}
});
});
}
// Hide logo conditionally
if (!args.hasLogo) $('#header .controls').addClass('nologo');
@ -315,6 +316,7 @@
var $target = $(event.target);
var $container = $target.closest('[cloudStack-container]');
var args = $container.data('cloudStack-args');
var $browser = $container.find('#browser .container');
if (!$container.size()) return true;
@ -323,14 +325,14 @@
var $navItem = $target.closest('li.navigation-item');
if ($navItem.is('.disabled')) return false;
showSection($navItem.data('cloudStack-section-id'), args);
showSection($navItem.data('cloudStack-section-id'), args, $browser);
return false;
}
// Browser expand
if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').size()) {
$('#browser div.container').cloudBrowser('toggleMaximizePanel', {
$browser.cloudBrowser('toggleMaximizePanel', {
panel: $target.closest('div.panel')
});
@ -339,7 +341,7 @@
// Home breadcrumb
if ($target.is('#breadcrumbs div.home')) {
showSection(args.home, args);
showSection(args.home, args, $browser);
return false;
}

View File

@ -781,7 +781,7 @@
jsonObj: jsonObj,
context: args.context,
response: {
success: function(args) {
success: function(args) {
if (options.newData) {
$.extend(args.data, options.newData);
}
@ -791,6 +791,9 @@
}
var tabData = $tabContent.data('detail-view-tab-data');
var data = args.data;
$detailView.data('list-view-row').data('json-obj', data); //refresh embedded data in corresponding list view row
var isFirstPanel = $tabContent.index($detailView.find('div.detail-group.ui-tabs-panel')) == 0;
var actionFilter = args.actionFilter;

View File

@ -1017,9 +1017,11 @@
if (internaldns2 != null && internaldns2.length > 0)
array1.push("&internaldns2=" + todb(internaldns2));
if(args.data.zone.ispublic == null) //public checkbox is unchecked
array1.push("&domainid=" + args.data.zone.domain);
if(args.data.pluginFrom == null) { //from zone wizard, not from quick instsaller(args.data.pluginFrom != null && args.data.pluginFrom.name == 'installWizard') who doesn't have public checkbox
if(args.data.zone.ispublic == null) //public checkbox in zone wizard is unchecked
array1.push("&domainid=" + args.data.zone.domain);
}
if(args.data.zone.networkdomain != null && args.data.zone.networkdomain.length > 0)
array1.push("&domain=" + todb(args.data.zone.networkdomain));

79
ui/tests/index.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CloudStack UI Tests</title>
<link rel="stylesheet" href="../lib/qunit/qunit.css" type="text/css" media="screen" />
</head>
<body>
<h1 id="qunit-header">CloudStack UI Tests</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>
<!-- jQuery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<script src="../lib/jquery.easing.js" type="text/javascript"></script>
<script src="../lib/jquery.validate.js" type="text/javascript"></script>
<script src="../lib/jquery-ui/js/jquery-ui.js" type="text/javascript"></script>
<!-- Flot -->
<script src="../lib/excanvas.js"></script>
<script src="../lib/flot/jquery.flot.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.colorhelpers.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.crosshair.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.fillbetween.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.image.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.navigate.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.pie.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.resize.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.selection.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.stack.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.symbol.js" type="text/javascript"></script>
<script src="../lib/flot/jquery.flot.threshold.js" type="text/javascript"></script>
<!-- UI -->
<script src="../scripts/ui/core.js" type="text/javascript"></script>
<script src="../scripts/ui/utils.js" type="text/javascript"></script>
<script src="../scripts/ui/events.js" type="text/javascript"></script>
<script src="../scripts/ui/dialog.js" type="text/javascript"></script>
<!-- UI - Widgets -->
<script src="../scripts/ui/widgets/multiEdit.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/overlay.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/dataTable.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/cloudBrowser.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/listView.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/detailView.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/treeView.js" type="text/javascript"></script>
<script src="../scripts/ui/widgets/notifications.js" type="text/javascript"></script>
<!-- Common libraries -->
<script src="../lib/date.js" type="text/javascript"></script>
<script src="../lib/jquery.cookies.js" type="text/javascript"></script>
<script src="../lib/jquery.timers.js" type="text/javascript"></script>
<script src="../lib/jquery.md5.js" type="text/javascript" ></script>
<!-- CloudStack -->
<script src="../scripts/ui-custom/login.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/projects.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/zoneChart.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/dashboard.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/installWizard.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/instanceWizard.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/ipRules.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/enableStaticNAT.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/securityRules.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/recurringSnapshots.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/physicalResources.js" type="text/javascript"></script>
<script src="../scripts/ui-custom/zoneWizard.js" type="text/javascript"></script>
<!-- qunit -->
<script src="../lib/qunit/qunit.js" type="text/javascript"></script>
<!-- Tests -->
<script src="test.core.js" type="text/javascript"></script>
</body>
</html>

42
ui/tests/test.core.js Normal file
View File

@ -0,0 +1,42 @@
(function($) {
test('Main widget', function() {
var cloudStack = {
sections: {
home: {
show: function() { return $('<div>').addClass('test123'); }
},
sectionA: {},
sectionB: {},
sectionC: {}
},
home: 'home'
};
var $cloudStack = $('<div>');
ok($cloudStack.cloudStack(cloudStack), 'Basic widget initialized');
// Main containers/wrappers
equal($cloudStack.find('[cloudStack-container]').size(), 1, 'Main sub-container present');
equal($cloudStack.find('#main-area').size(), 1, 'Main area present');
// Header
var $header = $cloudStack.find('#header');
var $userOptions = $cloudStack.find('#user-options');
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');
// Navigation
var $navigation = $cloudStack.find('#navigation');
equal($navigation.size(), 1, 'Navigation present');
equal($navigation.find('li').size(), 4, 'Navigation has correct # of nav items');
// Browser / page generation
var $browser = $cloudStack.find('#browser .container');
var $homePage = $browser.find('.panel div.test123');
equal($browser.size(), 1, 'Browser intialized');
equal($homePage.size(), 1, 'Home page is visible');
});
}(jQuery));