diff --git a/api/src/com/cloud/api/response/TemplateResponse.java b/api/src/com/cloud/api/response/TemplateResponse.java index 45e34ffe6ea..afefc644497 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -107,6 +107,9 @@ public class TemplateResponse extends BaseResponse { @SerializedName("isextractable") @Param(description="true if the template is extractable, false otherwise") private Boolean extractable; + @SerializedName("checksum") @Param(description="checksum of the template") + private String checksum; + public Long getObjectId() { return getId(); } @@ -326,4 +329,12 @@ public class TemplateResponse extends BaseResponse { public void setExtractable(Boolean extractable) { this.extractable = extractable; } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 7ea788cbd29..761c28f065f 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1501,6 +1501,8 @@ public class ApiResponseHelper implements ResponseGenerator { if (templateSize > 0) { templateResponse.setSize(templateSize); } + + templateResponse.setChecksum(template.getChecksum()); templateResponse.setObjectName("template"); responses.add(templateResponse); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 0eaaf000369..dc9c9cd275f 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -226,8 +226,14 @@ public enum Config { DefaultPageSize("Advanced", ManagementServer.class, Long.class, "default.page.size", "500", "Default page size for API list* commands", null), - TaskCleanupRetryInterval("Advanced", ManagementServer.class, Integer.class, "task.cleanup.retry.interval", "600", "Time (in seconds) to wait before retrying cleanup of tasks if the cleanup failed previously. 0 means to never retry.", "Seconds"); + TaskCleanupRetryInterval("Advanced", ManagementServer.class, Integer.class, "task.cleanup.retry.interval", "600", "Time (in seconds) to wait before retrying cleanup of tasks if the cleanup failed previously. 0 means to never retry.", "Seconds"), + // Account Default Limits + DefaultMaxAccountUserVms("Account Defaults", ManagementServer.class, Long.class, "max.account.user.vms", "20", "The default maximum number of user VMs that can be deployed for an account", null), + DefaultMaxAccountPublicIPs("Account Defaults", ManagementServer.class, Long.class, "max.account.public.ips", "20", "The default maximum number of public IPs that can be consumed by an account", null), + DefaultMaxAccountTemplates("Account Defaults", ManagementServer.class, Long.class, "max.account.templates", "20", "The default maximum number of templates that can be deployed for an account", null), + DefaultMaxAccountSnapshots("Account Defaults", ManagementServer.class, Long.class, "max.account.snapshots", "20", "The default maximum number of snapshots that can be created for an account", null), + DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null); private final String _category; private final Class _componentClass; @@ -250,6 +256,7 @@ public enum Config { _configs.put("Premium", new ArrayList()); _configs.put("Developer", new ArrayList()); _configs.put("Hidden", new ArrayList()); + _configs.put("Account Defaults", new ArrayList()); // Add values into HashMap for (Config c : Config.values()) { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 55d12dd0044..dd6736dca7a 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -621,6 +621,14 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmd.addVmData("metadata", "instance-id", vmInstanceName); cmd.addVmData("metadata", "vm-id", String.valueOf(vmId)); cmd.addVmData("metadata", "public-keys", publicKey); + + String cloudIdentifier = _configDao.getValue("cloud.identifier"); + if (cloudIdentifier == null) { + cloudIdentifier = ""; + }else{ + cloudIdentifier = "CloudStack-{"+cloudIdentifier+"}"; + } + cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier); return cmd; } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index f046973da8b..0649add389f 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -189,8 +189,6 @@ public class DatabaseConfig { s_configurationDescriptions.put("storage.capacity.threshold", "percentage (as a value between 0 and 1) of storage utilization above which alerts will be sent about low storage available"); s_configurationDescriptions.put("public.ip.capacity.threshold", "percentage (as a value between 0 and 1) of public IP address space utilization above which alerts will be sent"); s_configurationDescriptions.put("private.ip.capacity.threshold", "percentage (as a value between 0 and 1) of private IP address space utilization above which alerts will be sent"); - s_configurationDescriptions.put("max.account.user.vms", "the maximum number of user VMs that can be deployed for an account"); - s_configurationDescriptions.put("max.account.public.ips", "the maximum number of public IPs that can be reserved for an account"); s_configurationDescriptions.put("expunge.interval", "the interval to wait before running the expunge thread"); s_configurationDescriptions.put("network.throttling.rate", "default data transfer rate in megabits per second allowed per user"); s_configurationDescriptions.put("multicast.throttling.rate", "default multicast rate in megabits per second allowed"); @@ -234,8 +232,6 @@ public class DatabaseConfig { s_configurationComponents.put("public.ip.capacity.threshold", "management-server"); s_configurationComponents.put("private.ip.capacity.threshold", "management-server"); s_configurationComponents.put("capacity.check.period", "management-server"); - s_configurationComponents.put("max.account.user.vms", "management-server"); - s_configurationComponents.put("max.account.public.ips", "management-server"); s_configurationComponents.put("network.throttling.rate", "management-server"); s_configurationComponents.put("multicast.throttling.rate", "management-server"); s_configurationComponents.put("account.cleanup.interval", "management-server"); @@ -313,8 +309,6 @@ public class DatabaseConfig { s_defaultConfigurationValues.put("snapshot.test.months.per.year", "12"); s_defaultConfigurationValues.put("alert.wait", "1800"); s_defaultConfigurationValues.put("update.wait", "600"); - s_defaultConfigurationValues.put("max.account.user.vms", "20"); - s_defaultConfigurationValues.put("max.account.public.ips", "20"); s_defaultConfigurationValues.put("expunge.interval", "86400"); s_defaultConfigurationValues.put("extract.url.cleanup.interval", "120"); s_defaultConfigurationValues.put("instance.name", "VM"); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 0058207f04b..8051339bd7f 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -119,6 +119,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private String _name; @Inject private AccountDao _accountDao; + @Inject ConfigurationDao _configDao; @Inject private DomainDao _domainDao; @Inject private ResourceLimitDao _resourceLimitDao; @Inject private ResourceCountDao _resourceCountDao; @@ -250,22 +251,33 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag public long findCorrectResourceLimit(AccountVO account, ResourceType type) { long max = -1; - // Check account ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(account.getId(), type); - + + // Check if limit is configured for account if (limit != null) { max = limit.getMax().longValue(); } else { - // If the account has an infinite limit, check the ROOT domain - Long domainId = account.getDomainId(); - while ((domainId != null) && (limit == null)) { - limit = _resourceLimitDao.findByDomainIdAndType(domainId, type); - DomainVO domain = _domainDao.findById(domainId); - domainId = domain.getParent(); - } - - if (limit != null) { - max = limit.getMax().longValue(); + // If the account has an no limit set, then return global default account limits + try { + switch (type) { + case public_ip: + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())); + break; + case snapshot: + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())); + break; + case template: + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key())); + break; + case user_vm: + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())); + break; + case volume: + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())); + break; + } + } catch (NumberFormatException nfe) { + s_logger.error("Invalid value is set for the default account limit."); } } @@ -310,14 +322,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (m_resourceCountLock.lock(120)) { // 2 minutes try { - // Check account - ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(account.getId(), type); - - if (limit != null) { - long potentialCount = _resourceCountDao.getAccountCount(account.getId(), type) + numResources; - if (potentialCount > limit.getMax().longValue()) { - return true; - } + // Check account limits + AccountVO accountVo = _accountDao.findById(account.getAccountId()); + long accountLimit = findCorrectResourceLimit(accountVo, type); + long potentialCount = _resourceCountDao.getAccountCount(account.getId(), type) + numResources; + if (potentialCount > accountLimit) { + return true; } // check all domains in the account's domain hierarchy diff --git a/setup/db/db/schema-222to224.sql b/setup/db/db/schema-222to224.sql index 129c31511a9..6020d869631 100644 --- a/setup/db/db/schema-222to224.sql +++ b/setup/db/db/schema-222to224.sql @@ -114,7 +114,12 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced','DEFAULT','management-server','vmware.private.vswitch',NULL,'Specify the vSwitch on host for private network'), ('Advanced','DEFAULT','management-server','vmware.public.vswitch',NULL,'Specify the vSwitch on host for public network'), ('Advanced','DEFAULT','management-server','vmware.service.console','Service Console','Specify the service console network name (ESX host only)'), -('Advanced','DEFAULT','AgentManager','xapiwait','600','Time (in seconds) to wait for XAPI to return'); +('Advanced','DEFAULT','AgentManager','xapiwait','600','Time (in seconds) to wait for XAPI to return'), +('Account Defaults','DEFAULT','management-server','max.account.user.vms','20','The default maximum number of user VMs that can be deployed for an account'), +('Account Defaults','DEFAULT','management-server','max.account.public.ips','20','The default maximum number of public IPs that can be consumed by an account'), +('Account Defaults','DEFAULT','management-server','max.account.templates','20','The default maximum number of templates that can be deployed for an account'), +('Account Defaults','DEFAULT','management-server','max.account.snapshots','20','The default maximum number of snapshots that can be created for an account'), +('Account Defaults','DEFAULT','management-server','max.account.volumes','20','The default maximum number of volumes that can be created for an account'); ALTER TABLE `cloud`.`op_dc_ip_address_alloc` CHANGE COLUMN `instance_id` `nic_id` bigint unsigned DEFAULT NULL; ALTER TABLE `cloud`.`op_dc_ip_address_alloc` ADD CONSTRAINT `fk_op_dc_ip_address_alloc__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE; diff --git a/ui/custom/custom3/css/custom3.css b/ui/custom/custom3/css/custom3.css new file mode 100644 index 00000000000..da7b8b5ddbf --- /dev/null +++ b/ui/custom/custom3/css/custom3.css @@ -0,0 +1,356 @@ +@charset "UTF-8"; +/* CSS Document */ + +html,body{ + font-family:Arial, Helvetica, sans-serif; + font-size:11px; + color:#333; + height:auto; + font-weight:normal; + background:#68af23 url(../images/custom3_login_bg.gif) repeat-x top left; + margin:0; + padding:0; + +} + +.login_logobox { + width:217px; + height:58px; + float:left; + background:url(../images/custom3_login_logo.png) no-repeat top left; + margin:0 0 0 75px; + display:inline; + padding:0; +} + +.main_loginbox_bot { + width:660px; + height:109px; + float:left; + background:url(../images/custom3_loginbox_bot.png) no-repeat top left; + margin:0; + padding:0; +} + +#main_header { + min-width:980px; + width:100%; + height:73px; + float:left; + background:#b84634 url(../../custom3/images/custom3_header_bg.jpg) repeat-x top left; + margin:0; + padding:0; +} + +.header_left { + width:509px; + height:73px; + float:left; + margin:0; + padding:0; +} + +.logo { + width:212px; + height:54px; + float:left; + background:url(../../custom3/images/custom3_logo.jpg) no-repeat top left; + margin:8px 0 0 8px; + display:inline; + padding:0; +} + +.mgmtconsole_logo { + width:138px; + height:17px; + float:left; + background:url(../../custom3/images/custom3_mgmtconsole_logo.jpg) no-repeat top left; + margin:25px 0 0 15px; + display:inline; + padding:0; +} + + +.userlinks { + width:auto; + height:auto; + float:left; + margin:30px 15px 0 0; + padding:0; +} + + +.userlinks p { + width:auto; + height:auto; + float:left; + text-align:left; + font-size:12px; + font-weight:normal; + color:#FFF; +} + +.userlinks span { + font-weight:bold; + text-align:left; + font-size:11px; +} + +.logout_button { + width:63px; + height:24px; + float:left; + margin:28px 0 0 10px; + padding:0; +} + +.userlinks a { + width:auto; + height:auto; + color:#c4ff25; + text-decoration:none; + font-size:11px; + font-weight:normal; +} + +.userlinks a:link, userlinks a:visited { + text-decoration:none; +} + +.userlinks a:hover { + text-decoration:underline; +} + +.language_dropdownpanel { + width:103px; + height:19px; + float:left; + position:relative; + background:url(../../custom3/images/custom3_language_bg.gif) no-repeat top left; + margin:-3px 0 0 8px; + display:inline; + padding:0; + cursor:pointer; + cursor:hand; +} + +.language_dropdownpanel:hover { + background:url(../../custom3/images/custom3_language_bg_hover.gif) no-repeat top left; +} + +.language_icon { + width: 13px; + height:12px; + float:left; + background:url(../../custom3/images/custom3_language_icon.gif) no-repeat top left; + margin:3px 0 0 5px; + display:inline; + padding:0; +} + +.language_dropdownbox { + width:101px; + height:auto; + position:absolute; + background:#a44031 repeat top left; + border:1px solid #d87d58; + margin:0; + padding:0 0 15px 0; + top:17px; + z-index:1010; +} + +.leftmenu_panel { + width:221px; + height:100%; + min-height:1025px; + float:left; + background:#dbdbdb repeat top left; + border-right:1px dotted #183042; + border-top:1px dotted #183042; + margin:0 0 0 -100%; + padding:0; +} + +.leftmenu_arrows_firstlevel_open { + width:19px; + height:17px; + float:right; + margin:-2px 4px 0 0; + background:url(../images/custom3_leftmenu_maindownarrow.gif) no-repeat top left; + padding:0; +} + +.leftmenu_list{ + width:100%; + height:auto; + float:left; + margin:0; + padding:0; + background:#dbdbdb repeat-x bottom left; + border-bottom:1px dotted #333; +} + +.leftmenu_expandedbox{ + width:100%; + height:auto; + float:left; + position:relative; + background:#7ec558 url(../../custom3/images/custom3_leftmenu_expanded.gif) repeat-x top left; + border-bottom:1px solid #FFF; + margin:0; + padding:0; + overflow-x:scoll; + overflow-x:auto; + overflow-y:hidden; +} + +.leftmenu_content_flevel.selected{ + background:#dadada url(../../custom3/images/custom3_leftmenu_highlighted.gif) repeat-x top left; + border-bottom:1px dotted #333; + font-weight:bold; + color:#333; +} + +.leftmenu_content_flevel:hover{ + background:#f7f7f7 url(../../custom3/images/custom3_leftmenu_hover.gif) repeat-x top left; +} + +.leftmenu_content:hover{ + color:#FFF; + background:#508e24 repeat top left; +} + +.leftmenu_content.selected{ + color:#FFF; + background:#39750b repeat-x top left; +} + +.leftmenu_secondindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + +.leftmenu_thirdindent{ + min-width:160px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 50px; + display:inline; + padding:0; +} + +.leftmenu_fourthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 70px; + display:inline; + padding:0; +} + +.leftmenu_fifthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 100px; + display:inline; + padding:0; +} + +.leftmenu_sixthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 120px; + display:inline; + padding:0; +} + +.leftmenu_domainindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#FFF; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + + + + + + + +.midmenu_panel { + width:221px; + min-height:1000px; + height:auto; + float:left; + position:relative; + background:#f9f9f9 repeat top left; + border-right:1px dotted #183042; + margin:27px 0 0 -100%; + display:inline; + padding:0; +} + +.midmenu_list{ + width:220px; + height:auto; + float:left; + background:#f9f9f9 repeat-x bottom left; + border-bottom:1px dotted #183042; + margin:0; + padding:0; +} + +.midmenu_content:hover{ + background:#b6b6b6 url(../../custom3/images/custom3_midmenu_hover.gif) repeat-x top left; + color:#333; +} + +.midmenu_content.selected { + background:#167a1a url(../../custom3/images/custom3_midmenu_selected.gif) repeat-x top left; + color:#FFF; + +} + + + + +.content_tabs.off { + background:url(../images/custom3_contenttab_unselected.gif) no-repeat bottom left; + color:#FFF; + cursor:pointer; + cursor:hand; + +} + + + +.adv_searchpopup_bg { + width:100%; + height:auto; + float:left; + background:#cecece url(../../custom3/images/custom3_adv_searchbg.gif) repeat-x top left; + border-bottom:1px solid #2d2d2d; + margin:0; + padding:0 0 9px 0; +} diff --git a/ui/custom/custom3/images/custom3_contenttab_unselected.gif b/ui/custom/custom3/images/custom3_contenttab_unselected.gif new file mode 100644 index 00000000000..293601fd320 Binary files /dev/null and b/ui/custom/custom3/images/custom3_contenttab_unselected.gif differ diff --git a/ui/custom/custom3/images/custom3_header_bg.jpg b/ui/custom/custom3/images/custom3_header_bg.jpg new file mode 100644 index 00000000000..781f7b9bb32 Binary files /dev/null and b/ui/custom/custom3/images/custom3_header_bg.jpg differ diff --git a/ui/custom/custom3/images/custom3_leftmenu_expanded.gif b/ui/custom/custom3/images/custom3_leftmenu_expanded.gif new file mode 100644 index 00000000000..9ac2e03bd40 Binary files /dev/null and b/ui/custom/custom3/images/custom3_leftmenu_expanded.gif differ diff --git a/ui/custom/custom3/images/custom3_leftmenu_highlighted.gif b/ui/custom/custom3/images/custom3_leftmenu_highlighted.gif new file mode 100644 index 00000000000..df47fe01609 Binary files /dev/null and b/ui/custom/custom3/images/custom3_leftmenu_highlighted.gif differ diff --git a/ui/custom/custom3/images/custom3_leftmenu_maindownarrow.gif b/ui/custom/custom3/images/custom3_leftmenu_maindownarrow.gif new file mode 100644 index 00000000000..13da67e45c7 Binary files /dev/null and b/ui/custom/custom3/images/custom3_leftmenu_maindownarrow.gif differ diff --git a/ui/custom/custom3/images/custom3_login_bg.gif b/ui/custom/custom3/images/custom3_login_bg.gif new file mode 100644 index 00000000000..6cca86f1ccc Binary files /dev/null and b/ui/custom/custom3/images/custom3_login_bg.gif differ diff --git a/ui/custom/custom3/images/custom3_login_logo.png b/ui/custom/custom3/images/custom3_login_logo.png new file mode 100644 index 00000000000..1147413bca5 Binary files /dev/null and b/ui/custom/custom3/images/custom3_login_logo.png differ diff --git a/ui/custom/custom3/images/custom3_loginbox_bot.png b/ui/custom/custom3/images/custom3_loginbox_bot.png new file mode 100644 index 00000000000..db735b38c6b Binary files /dev/null and b/ui/custom/custom3/images/custom3_loginbox_bot.png differ diff --git a/ui/custom/custom3/images/custom3_logo.jpg b/ui/custom/custom3/images/custom3_logo.jpg new file mode 100644 index 00000000000..0092d2dde2d Binary files /dev/null and b/ui/custom/custom3/images/custom3_logo.jpg differ diff --git a/ui/custom/custom3/images/custom3_mgmtconsole_logo.jpg b/ui/custom/custom3/images/custom3_mgmtconsole_logo.jpg new file mode 100644 index 00000000000..9f8e30b76a7 Binary files /dev/null and b/ui/custom/custom3/images/custom3_mgmtconsole_logo.jpg differ diff --git a/ui/custom/custom3/images/custom3_midmenu_selected.gif b/ui/custom/custom3/images/custom3_midmenu_selected.gif new file mode 100644 index 00000000000..e3ba427c7db Binary files /dev/null and b/ui/custom/custom3/images/custom3_midmenu_selected.gif differ diff --git a/ui/custom/custom3/images/logout_button.jpg b/ui/custom/custom3/images/logout_button.jpg new file mode 100644 index 00000000000..b91a3970eda Binary files /dev/null and b/ui/custom/custom3/images/logout_button.jpg differ