diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 33aa1e8d370..b2bf18b12f8 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -260,5 +260,6 @@ public class ApiConstants { public static final String TEMPLATE_TAG = "templatetag"; public static final String HYPERVISOR_VERSION = "hypervisorversion"; public static final String MAX_GUESTS_LIMIT = "maxguestslimit"; + public static final String PROJECT_ID = "projectid"; } diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index 69bc4e577cd..a14341062d5 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -52,6 +52,8 @@ import com.cloud.storage.snapshot.SnapshotService; import com.cloud.template.TemplateService; import com.cloud.user.Account; import com.cloud.user.AccountService; +import com.cloud.user.DomainService; +import com.cloud.user.ResourceLimitService; import com.cloud.user.UserContext; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; @@ -68,7 +70,7 @@ public abstract class BaseCmd { public static final String RESPONSE_TYPE_JSON = "json"; public enum CommandType { - BOOLEAN, DATE, FLOAT, INTEGER, LIST, LONG, OBJECT, MAP, STRING, TZDATE + BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE } // FIXME: Extract these out into a separate file @@ -120,6 +122,8 @@ public abstract class BaseCmd { public static BareMetalVmService _bareMetalVmService; public static ProjectService _projectService; public static FirewallService _firewallService; + public static DomainService _domainService; + public static ResourceLimitService _resourceLimitService; static void setComponents(ResponseGenerator generator) { ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); @@ -143,6 +147,8 @@ public abstract class BaseCmd { _bareMetalVmService = locator.getManager(BareMetalVmService.class); _projectService = locator.getManager(ProjectService.class); _firewallService = locator.getManager(FirewallService.class); + _domainService = locator.getManager(DomainService.class); + _resourceLimitService = locator.getManager(ResourceLimitService.class); } public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException; diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java index 3352df62cf8..a9a53e5d72e 100644 --- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -98,7 +98,7 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { if (zone.getNetworkType() == NetworkType.Advanced) { List networks = _networkService.getVirtualNetworksOwnedByAccountInZone(getAccountName(), getDomainId(), getZoneId()); if (networks.size() == 0) { - String domain = _accountService.getDomain(getDomainId()).getName(); + String domain = _domainService.getDomain(getDomainId()).getName(); throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" + zone.getName()); } assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete"; diff --git a/api/src/com/cloud/api/commands/CreateAccountCmd.java b/api/src/com/cloud/api/commands/CreateAccountCmd.java index ec613d77c29..a3e84d3280f 100644 --- a/api/src/com/cloud/api/commands/CreateAccountCmd.java +++ b/api/src/com/cloud/api/commands/CreateAccountCmd.java @@ -44,8 +44,8 @@ public class CreateAccountCmd extends BaseCmd { @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="Creates the user under the specified account. If no account is specified, the username will be used as the account name.") private String accountName; - @Parameter(name=ApiConstants.ACCOUNT_TYPE, type=CommandType.LONG, required=true, description="Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") - private Long accountType; + @Parameter(name=ApiConstants.ACCOUNT_TYPE, type=CommandType.SHORT, required=true, description="Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") + private Short accountType; @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Creates the user under the specified domain.") private Long domainId; @@ -54,19 +54,19 @@ public class CreateAccountCmd extends BaseCmd { private String email; @Parameter(name=ApiConstants.FIRSTNAME, type=CommandType.STRING, required=true, description="firstname") - private String firstname; + private String firstName; @Parameter(name=ApiConstants.LASTNAME, type=CommandType.STRING, required=true, description="lastname") - private String lastname; + private String lastName; @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=true, description="Hashed password (Default is MD5). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter See Docs section.") private String password; @Parameter(name=ApiConstants.TIMEZONE, type=CommandType.STRING, description="Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") - private String timezone; + private String timeZone; @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required=true, description="Unique username.") - private String username; + private String userName; @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="Network domain for the account's networks") private String networkDomain; @@ -79,7 +79,7 @@ public class CreateAccountCmd extends BaseCmd { return accountName; } - public Long getAccountType() { + public Short getAccountType() { return accountType; } @@ -91,24 +91,24 @@ public class CreateAccountCmd extends BaseCmd { return email; } - public String getFirstname() { - return firstname; + public String getFirstName() { + return firstName; } - public String getLastname() { - return lastname; + public String getLastName() { + return lastName; } public String getPassword() { return password; } - public String getTimezone() { - return timezone; + public String getTimeZone() { + return timeZone; } public String getUsername() { - return username; + return userName; } public String getNetworkDomain() { @@ -133,9 +133,9 @@ public class CreateAccountCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); - UserAccount user = _accountService.createAccount(this); - if (user != null) { - AccountResponse response = _responseGenerator.createUserAccountResponse(user); + UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), getDomainId(), getNetworkDomain()); + if (userAccount != null) { + AccountResponse response = _responseGenerator.createUserAccountResponse(userAccount); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/com/cloud/api/commands/CreateDomainCmd.java b/api/src/com/cloud/api/commands/CreateDomainCmd.java index 5606b6070ca..2c4c8f6fad0 100644 --- a/api/src/com/cloud/api/commands/CreateDomainCmd.java +++ b/api/src/com/cloud/api/commands/CreateDomainCmd.java @@ -81,7 +81,7 @@ public class CreateDomainCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("Domain Name: "+getDomainName()+((getParentDomainId()!=null)?", Parent DomainId :"+getParentDomainId():"")); - Domain domain = _accountService.createDomain(this); + Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain()); if (domain != null) { DomainResponse response = _responseGenerator.createDomainResponse(domain); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateProjectCmd.java b/api/src/com/cloud/api/commands/CreateProjectCmd.java index 2fb817b189f..8c4948b914a 100644 --- a/api/src/com/cloud/api/commands/CreateProjectCmd.java +++ b/api/src/com/cloud/api/commands/CreateProjectCmd.java @@ -52,9 +52,6 @@ public class CreateProjectCmd extends BaseCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="display text of the project") private String displayText; - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the zone id of the project") - private Long zoneId; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -75,10 +72,6 @@ public class CreateProjectCmd extends BaseCmd { return displayText; } - public Long getZoneId() { - return zoneId; - } - @Override public String getCommandName() { return s_name; @@ -110,8 +103,8 @@ public class CreateProjectCmd extends BaseCmd { @Override public void execute(){ - UserContext.current().setEventDetails("Project Name: "+ getName() + ", zoneId " + zoneId); - Project project = _projectService.createProject(getName(), getDisplayText(), getZoneId(), getAccountName(), getDomainId()); + UserContext.current().setEventDetails("Project Name: "+ getName()); + Project project = _projectService.createProject(getName(), getDisplayText(), getAccountName(), getDomainId()); if (project != null) { ProjectResponse response = _responseGenerator.createProjectResponse(project); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateUserCmd.java b/api/src/com/cloud/api/commands/CreateUserCmd.java index b73decb6d20..6cd208baf72 100644 --- a/api/src/com/cloud/api/commands/CreateUserCmd.java +++ b/api/src/com/cloud/api/commands/CreateUserCmd.java @@ -80,11 +80,11 @@ public class CreateUserCmd extends BaseCmd { return email; } - public String getFirstname() { + public String getFirstName() { return firstname; } - public String getLastname() { + public String getLastName() { return lastname; } @@ -96,7 +96,7 @@ public class CreateUserCmd extends BaseCmd { return timezone; } - public String getUsername() { + public String getUserName() { return username; } @@ -130,8 +130,8 @@ public class CreateUserCmd extends BaseCmd { @Override public void execute(){ - UserContext.current().setEventDetails("UserName: "+getUsername()+", FirstName :"+getFirstname()+", LastName: "+getLastname()); - User user = _accountService.createUser(this); + UserContext.current().setEventDetails("UserName: "+getUserName()+", FirstName :"+getFirstName()+", LastName: "+getLastName()); + User user = _accountService.createUser(getUserName(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimezone(), getAccountName(), getDomainId()); if (user != null) { UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/DeleteAccountCmd.java b/api/src/com/cloud/api/commands/DeleteAccountCmd.java index 8bcb29839db..98fa690472b 100644 --- a/api/src/com/cloud/api/commands/DeleteAccountCmd.java +++ b/api/src/com/cloud/api/commands/DeleteAccountCmd.java @@ -91,7 +91,7 @@ public class DeleteAccountCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Account Id: "+getId()); - boolean result = _accountService.deleteUserAccount(this); + boolean result = _accountService.deleteUserAccount(getId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/DeleteDomainCmd.java b/api/src/com/cloud/api/commands/DeleteDomainCmd.java index 775039f15e1..d2e0d96f48d 100644 --- a/api/src/com/cloud/api/commands/DeleteDomainCmd.java +++ b/api/src/com/cloud/api/commands/DeleteDomainCmd.java @@ -91,7 +91,7 @@ public class DeleteDomainCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Domain Id: "+getId()); - boolean result = _mgr.deleteDomain(this); + boolean result = _domainService.deleteDomain(id, cleanup); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/DeleteProjectCmd.java b/api/src/com/cloud/api/commands/DeleteProjectCmd.java index 8719dea68d3..7d427436d38 100644 --- a/api/src/com/cloud/api/commands/DeleteProjectCmd.java +++ b/api/src/com/cloud/api/commands/DeleteProjectCmd.java @@ -23,15 +23,12 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; import com.cloud.api.BaseAsyncCmd; import com.cloud.api.BaseCmd; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; -import com.cloud.api.response.ProjectResponse; import com.cloud.api.response.SuccessResponse; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.Network; import com.cloud.projects.Project; import com.cloud.user.UserContext; @@ -45,7 +42,7 @@ public class DeleteProjectCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="id of the project to be deleted") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of the project to be deleted") private Long id; ///////////////////////////////////////////////////// @@ -94,7 +91,7 @@ public class DeleteProjectCmd extends BaseAsyncCmd { if (project == null) { throw new InvalidParameterValueException("Project id=" + id + " doesn't exist"); } else { - return _projectService.getProject(id).getAccountId(); + return _projectService.getProject(id).getProjectAccountId(); } } } \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index a9cb8e7c8b3..fa00dc065ef 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -346,7 +346,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { public void create() throws ResourceAllocationException{ try { //Verify that all objects exist before passing them to the service - Account owner = _accountService.getActiveAccount(getAccountName(), getDomainId()); + Account owner = _accountService.getActiveAccountByName(getAccountName(), getDomainId()); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } diff --git a/api/src/com/cloud/api/commands/DisableAccountCmd.java b/api/src/com/cloud/api/commands/DisableAccountCmd.java index 391aaee6c09..706795af532 100644 --- a/api/src/com/cloud/api/commands/DisableAccountCmd.java +++ b/api/src/com/cloud/api/commands/DisableAccountCmd.java @@ -78,7 +78,7 @@ public class DisableAccountCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - Account account = _accountService.getActiveAccount(getAccountName(), getDomainId()); + Account account = _accountService.getActiveAccountByName(getAccountName(), getDomainId()); if (account != null) { return account.getAccountId(); } @@ -96,9 +96,9 @@ public class DisableAccountCmd extends BaseAsyncCmd { UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); Account result = null; if(lockRequested) - result = _accountService.lockAccount(this); + result = _accountService.lockAccount(getAccountName(), getDomainId()); else - result = _accountService.disableAccount(this); + result = _accountService.disableAccount(getAccountName(), getDomainId()); if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/DisableUserCmd.java b/api/src/com/cloud/api/commands/DisableUserCmd.java index 23a3852f064..6f171501f6a 100644 --- a/api/src/com/cloud/api/commands/DisableUserCmd.java +++ b/api/src/com/cloud/api/commands/DisableUserCmd.java @@ -85,7 +85,7 @@ public class DisableUserCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("UserId: "+getId()); - UserAccount user = _accountService.disableUser(this); + UserAccount user = _accountService.disableUser(getId()); if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/EnableAccountCmd.java b/api/src/com/cloud/api/commands/EnableAccountCmd.java index 3dfdbebcf89..32b4fa27c6f 100644 --- a/api/src/com/cloud/api/commands/EnableAccountCmd.java +++ b/api/src/com/cloud/api/commands/EnableAccountCmd.java @@ -65,7 +65,7 @@ public class EnableAccountCmd extends BaseCmd { @Override public long getEntityOwnerId() { - Account account = _accountService.getActiveAccount(getAccountName(), getDomainId()); + Account account = _accountService.getActiveAccountByName(getAccountName(), getDomainId()); if (account != null) { return account.getAccountId(); } @@ -75,7 +75,7 @@ public class EnableAccountCmd extends BaseCmd { @Override public void execute(){ - Account result = _accountService.enableAccount(this); + Account result = _accountService.enableAccount(getAccountName(), getDomainId()); if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/EnableUserCmd.java b/api/src/com/cloud/api/commands/EnableUserCmd.java index 1d5f57969dc..7e867abbe3e 100644 --- a/api/src/com/cloud/api/commands/EnableUserCmd.java +++ b/api/src/com/cloud/api/commands/EnableUserCmd.java @@ -74,7 +74,7 @@ public class EnableUserCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("UserId: "+getId()); - UserAccount user = _accountService.enableUser(this); + UserAccount user = _accountService.enableUser(getId()); if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/ListProjectsCmd.java b/api/src/com/cloud/api/commands/ListProjectsCmd.java index 2ff4f1551d6..2fa9b7f1c1d 100644 --- a/api/src/com/cloud/api/commands/ListProjectsCmd.java +++ b/api/src/com/cloud/api/commands/ListProjectsCmd.java @@ -53,9 +53,6 @@ public class ListProjectsCmd extends BaseListCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list projects by display text") private String displayText; - - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="list projects for specific zone") - private Long zoneId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -80,10 +77,6 @@ public class ListProjectsCmd extends BaseListCmd { public String getDisplayText() { return displayText; } - - public Long getZoneId() { - return zoneId; - } @Override public String getCommandName() { @@ -96,7 +89,7 @@ public class ListProjectsCmd extends BaseListCmd { @Override public void execute(){ - List projects = _projectService.listProjects(id, name, displayText, zoneId, accountName, domainId, this.getKeyword(), this.getStartIndex(), this.getPageSizeVal()); + List projects = _projectService.listProjects(id, name, displayText, accountName, domainId, this.getKeyword(), this.getStartIndex(), this.getPageSizeVal()); ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); for (Project project : projects) { diff --git a/api/src/com/cloud/api/commands/ListResourceLimitsCmd.java b/api/src/com/cloud/api/commands/ListResourceLimitsCmd.java index d5d3a0ca2e6..4d7f671bf03 100644 --- a/api/src/com/cloud/api/commands/ListResourceLimitsCmd.java +++ b/api/src/com/cloud/api/commands/ListResourceLimitsCmd.java @@ -88,7 +88,7 @@ public class ListResourceLimitsCmd extends BaseListCmd { @Override public void execute(){ - List result = _accountService.searchForLimits(id, accountName, domainId, resourceType, this.getStartIndex(), this.getPageSizeVal()); + List result = _resourceLimitService.searchForLimits(id, accountName, domainId, resourceType, this.getStartIndex(), this.getPageSizeVal()); ListResponse response = new ListResponse(); List limitResponses = new ArrayList(); for (ResourceLimit limit : result) { diff --git a/api/src/com/cloud/api/commands/LockAccountCmd.java b/api/src/com/cloud/api/commands/LockAccountCmd.java index 278f9354fe3..3eed7cfaa61 100644 --- a/api/src/com/cloud/api/commands/LockAccountCmd.java +++ b/api/src/com/cloud/api/commands/LockAccountCmd.java @@ -65,7 +65,7 @@ public class LockAccountCmd extends BaseCmd { @Override public long getEntityOwnerId() { - Account account = _accountService.getActiveAccount(getAccountName(), getDomainId()); + Account account = _accountService.getActiveAccountByName(getAccountName(), getDomainId()); if (account != null) { return account.getAccountId(); } diff --git a/api/src/com/cloud/api/commands/LockUserCmd.java b/api/src/com/cloud/api/commands/LockUserCmd.java index 85eeab33be4..efcf072f71c 100644 --- a/api/src/com/cloud/api/commands/LockUserCmd.java +++ b/api/src/com/cloud/api/commands/LockUserCmd.java @@ -71,7 +71,7 @@ public class LockUserCmd extends BaseCmd { @Override public void execute(){ - UserAccount user = _accountService.lockUser(this); + UserAccount user = _accountService.lockUser(getId()); if (user != null){ UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/RegisterCmd.java b/api/src/com/cloud/api/commands/RegisterCmd.java index 8d44d7088c2..b548de82649 100644 --- a/api/src/com/cloud/api/commands/RegisterCmd.java +++ b/api/src/com/cloud/api/commands/RegisterCmd.java @@ -69,7 +69,7 @@ public class RegisterCmd extends BaseCmd { @Override public void execute(){ - String[] keys = _mgr.createApiKeyAndSecretKey(this); + String[] keys = _accountService.createApiKeyAndSecretKey(this); RegisterResponse response = new RegisterResponse(); response.setApiKey(keys[0]); response.setSecretKey(keys[1]); diff --git a/api/src/com/cloud/api/commands/StartSystemVMCmd.java b/api/src/com/cloud/api/commands/StartSystemVMCmd.java index 02e01ee4728..9661ca992fe 100644 --- a/api/src/com/cloud/api/commands/StartSystemVMCmd.java +++ b/api/src/com/cloud/api/commands/StartSystemVMCmd.java @@ -104,7 +104,7 @@ public class StartSystemVMCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Vm Id: "+getId()); - VirtualMachine instance = _mgr.startSystemVM(this); + VirtualMachine instance = _mgr.startSystemVM(getId()); if (instance != null) { SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/UpdateAccountCmd.java b/api/src/com/cloud/api/commands/UpdateAccountCmd.java index 05a77d60ab1..69b0e5164d5 100644 --- a/api/src/com/cloud/api/commands/UpdateAccountCmd.java +++ b/api/src/com/cloud/api/commands/UpdateAccountCmd.java @@ -79,7 +79,7 @@ public class UpdateAccountCmd extends BaseCmd{ @Override public long getEntityOwnerId() { - Account account = _accountService.getActiveAccount(getAccountName(), getDomainId()); + Account account = _accountService.getActiveAccountByName(getAccountName(), getDomainId()); if (account != null) { return account.getAccountId(); } diff --git a/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java b/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java index 556ed5c719e..8ac4ac139e6 100644 --- a/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java +++ b/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java @@ -104,7 +104,7 @@ public class UpdateResourceCountCmd extends BaseCmd { @Override public void execute(){ - List result = _accountService.updateResourceCount(this); + List result = _resourceLimitService.recalculateResourceCount(this); if ((result != null) && (result.size()>0)){ ListResponse response = new ListResponse(); diff --git a/api/src/com/cloud/api/commands/UpdateResourceLimitCmd.java b/api/src/com/cloud/api/commands/UpdateResourceLimitCmd.java index 88f6084011c..244f1564ab5 100644 --- a/api/src/com/cloud/api/commands/UpdateResourceLimitCmd.java +++ b/api/src/com/cloud/api/commands/UpdateResourceLimitCmd.java @@ -26,9 +26,11 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.ResourceLimitResponse; +import com.cloud.configuration.Resource.ResourceOwnerType; import com.cloud.configuration.ResourceLimit; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.user.Account; -import com.cloud.user.UserContext; +import com.cloud.utils.Pair; @Implementation(description="Updates resource limits for an account or domain.", responseObject=ResourceLimitResponse.class) public class UpdateResourceLimitCmd extends BaseCmd { @@ -46,6 +48,9 @@ public class UpdateResourceLimitCmd extends BaseCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Update resource limits for all accounts in specified domain. If used with the account parameter, updates resource limits for a specified account in specified domain.") private Long domainId; + + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Update resource limits for project") + private Long projectId; @Parameter(name=ApiConstants.MAX, type=CommandType.LONG, description=" Maximum resource limit.") private Long max; @@ -61,12 +66,44 @@ public class UpdateResourceLimitCmd extends BaseCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getAccountName() { - return accountName; - } - - public Long getDomainId() { - return domainId; + public Pair getOwner() { + + Long ownerId = null; + ResourceOwnerType resourceOwnerType = null; + if (domainId != null) { + + if (_domainService.getDomain(domainId) == null) { + throw new InvalidParameterValueException("Unable to find domain by id=" + domainId); + } + + if (accountName != null) { + Account account = _accountService.getActiveAccountByName(accountName, domainId); + if (account != null) { + ownerId = account.getId(); + resourceOwnerType = ResourceOwnerType.Account; + } else { + throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain id=" + domainId); + } + } else { + ownerId = domainId; + resourceOwnerType = ResourceOwnerType.Domain; + } + } else if (projectId != null){ + if (_projectService.getProject(projectId) == null) { + throw new InvalidParameterValueException("Unable to find project by id " + projectId); + } + + //TODO - get domainId associated with the project + ownerId = projectId; + resourceOwnerType = ResourceOwnerType.Domain; + + } + + if (ownerId == null) { + throw new InvalidParameterValueException("Please specify projectId or domainId or domainId/accountName"); + } + + return new Pair(ownerId, resourceOwnerType); } public Long getMax() { @@ -88,26 +125,12 @@ public class UpdateResourceLimitCmd extends BaseCmd { @Override public long getEntityOwnerId() { - Account account = UserContext.current().getCaller(); - if ((account == null) || isAdmin(account.getType())) { - if ((domainId != null) && (accountName != null)) { - Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId); - if (userAccount != null) { - return userAccount.getId(); - } - } - } - - if (account != null) { - return account.getId(); - } - - return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + return getOwner().first(); } @Override public void execute(){ - ResourceLimit result = _accountService.updateResourceLimit(accountName, domainId, resourceType, max); + ResourceLimit result = _resourceLimitService.updateResourceLimit(getOwner().first(), getOwner().second(), resourceType, max); if (result != null || (result == null && max != null && max.longValue() == -1L)){ ResourceLimitResponse response = _responseGenerator.createResourceLimitResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/response/BaseResponse.java b/api/src/com/cloud/api/response/BaseResponse.java index 65b5f71812d..b0e60b1a67f 100644 --- a/api/src/com/cloud/api/response/BaseResponse.java +++ b/api/src/com/cloud/api/response/BaseResponse.java @@ -23,7 +23,7 @@ import com.cloud.api.ResponseObject; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; -public class BaseResponse implements ResponseObject { +public abstract class BaseResponse implements ResponseObject { private transient String responseName; private transient String objectName; @@ -73,5 +73,4 @@ public class BaseResponse implements ResponseObject { public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } - } diff --git a/api/src/com/cloud/api/response/ProjectResponse.java b/api/src/com/cloud/api/response/ProjectResponse.java index 1d1f2d1ae76..727f9d2d684 100644 --- a/api/src/com/cloud/api/response/ProjectResponse.java +++ b/api/src/com/cloud/api/response/ProjectResponse.java @@ -22,6 +22,7 @@ import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; +@SuppressWarnings("unused") public class ProjectResponse extends BaseResponse{ @SerializedName("id") @Param(description="the id of the project") @@ -32,72 +33,38 @@ public class ProjectResponse extends BaseResponse{ @SerializedName("displaytext") @Param(description="the displaytext of the project") private String displaytext; - - @SerializedName("zoneid") @Param(description="zone id of the project") - private Long zoneId; - - @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the project") - private String accountName; - @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the project owner") + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id the project belongs to") private Long domainId; - @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the project owner") + @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name where the project belongs to") private String domain; - public Long getId() { - return id; - } + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account name of the project's owner") + private String ownerName; public void setId(Long id) { this.id = id; } - public String getName() { - return name; - } - public void setName(String name) { this.name = name; } - public Long getZoneId() { - return zoneId; - } - - public void setZoneId(Long zoneId) { - this.zoneId = zoneId; - } - - public String getAccountName() { - return accountName; - } - - public void setAccountName(String accountName) { - this.accountName = accountName; - } - - public Long getDomainId() { - return domainId; + public void setDisplaytext(String displaytext) { + this.displaytext = displaytext; } public void setDomainId(Long domainId) { this.domainId = domainId; } - public String getDisplaytext() { - return displaytext; - } - - public void setDisplaytext(String displaytext) { - this.displaytext = displaytext; - } - - public String getDomain() { - return domain; - } - public void setDomain(String domain) { this.domain = domain; } + + public void setOwner(String owner) { + this.ownerName = owner; + } + } diff --git a/api/src/com/cloud/configuration/Resource.java b/api/src/com/cloud/configuration/Resource.java new file mode 100644 index 00000000000..4c9cda41058 --- /dev/null +++ b/api/src/com/cloud/configuration/Resource.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.configuration; + +public interface Resource { + + public enum ResourceType{ + user_vm ("user_vm", 0, ResourceOwnerType.Account, ResourceOwnerType.Domain), + public_ip ("public_ip", 1, ResourceOwnerType.Account, ResourceOwnerType.Domain), + volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain), + snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain), + template ("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain), + project ("project", 5, ResourceOwnerType.Domain); + + private String name; + private ResourceOwnerType[] supportedOwners; + private int ordinal; + + ResourceType(String name, int ordinal, ResourceOwnerType... supportedOwners) { + this.name = name; + this.supportedOwners = supportedOwners; + this.ordinal = ordinal; + } + + public String getName() { + return name; + } + + public ResourceOwnerType[] getSupportedOwners() { + return supportedOwners; + } + + public boolean supportsOwner(ResourceOwnerType ownerType) { + boolean success = false; + if (supportedOwners != null) { + int length = supportedOwners.length; + for (int i = 0; i< length; i++) { + if (supportedOwners[i].getName().equalsIgnoreCase(ownerType.getName())) { + success = true; + break; + } + } + } + + return success; + } + + public int getOrdinal() { + return ordinal; + } + } + + public static class ResourceOwnerType { + + public static final ResourceOwnerType Account = new ResourceOwnerType("Account"); + public static final ResourceOwnerType Domain = new ResourceOwnerType("Domain"); + + private String name; + + public ResourceOwnerType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + ResourceType getType(); + + long getOwnerId(); + + ResourceOwnerType getResourceOwnerType(); + +} diff --git a/api/src/com/cloud/configuration/ResourceCount.java b/api/src/com/cloud/configuration/ResourceCount.java index b9efaf45859..e5cc19967bb 100644 --- a/api/src/com/cloud/configuration/ResourceCount.java +++ b/api/src/com/cloud/configuration/ResourceCount.java @@ -18,32 +18,10 @@ package com.cloud.configuration; -public interface ResourceCount { - - public enum ResourceType { - user_vm, - public_ip, - volume, - snapshot, - template - } - +public interface ResourceCount extends Resource{ + public Long getId(); - public void setId(Long id); - - public ResourceType getType(); - - public void setType(ResourceType type); - - public Long getAccountId(); - - public void setAccountId(Long accountId); - - public Long getDomainId(); - - public void setDomainId(Long domainId); - public long getCount(); public void setCount(long count); diff --git a/api/src/com/cloud/configuration/ResourceLimit.java b/api/src/com/cloud/configuration/ResourceLimit.java index 4bb3a7fe04d..8c8b59d91cc 100644 --- a/api/src/com/cloud/configuration/ResourceLimit.java +++ b/api/src/com/cloud/configuration/ResourceLimit.java @@ -18,26 +18,10 @@ package com.cloud.configuration; -public interface ResourceLimit { - - public static enum OwnerType {Account, Domain} +public interface ResourceLimit extends Resource{ public Long getId(); - public void setId(Long id); - - public ResourceCount.ResourceType getType(); - - public void setType(ResourceCount.ResourceType type); - - public Long getDomainId(); - - public void setDomainId(Long domainId); - - public Long getAccountId(); - - public void setAccountId(Long accountId); - public Long getMax(); public void setMax(Long max); diff --git a/api/src/com/cloud/domain/Domain.java b/api/src/com/cloud/domain/Domain.java index fc27974f374..7f891b6b405 100644 --- a/api/src/com/cloud/domain/Domain.java +++ b/api/src/com/cloud/domain/Domain.java @@ -30,6 +30,10 @@ import com.cloud.user.OwnedBy; */ public interface Domain extends OwnedBy { public static final long ROOT_DOMAIN = 1L; + public enum Type { + Normal, + Project, + } enum State {Active, Inactive}; @@ -60,4 +64,6 @@ public interface Domain extends OwnedBy { void setState(State state); String getNetworkDomain(); + + Type getType(); } diff --git a/api/src/com/cloud/projects/Project.java b/api/src/com/cloud/projects/Project.java index 5131428a995..2308f8e65eb 100644 --- a/api/src/com/cloud/projects/Project.java +++ b/api/src/com/cloud/projects/Project.java @@ -1,25 +1,47 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ package com.cloud.projects; import java.util.Date; -import com.cloud.acl.ControlledEntity; +import com.cloud.domain.PartOf; -public interface Project extends ControlledEntity{ +public interface Project extends PartOf{ + public enum State {Active, Inactive, Suspended} String getDisplayText(); long getDomainId(); - long getAccountId(); - long getId(); Date getCreated(); Date getRemoved(); - long getDataCenterId(); - String getName(); + + public long getProjectAccountId(); + + long getProjectDomainId(); + + State getState(); + + void setState(State state); } diff --git a/api/src/com/cloud/projects/ProjectAccount.java b/api/src/com/cloud/projects/ProjectAccount.java new file mode 100644 index 00000000000..abf77cba18d --- /dev/null +++ b/api/src/com/cloud/projects/ProjectAccount.java @@ -0,0 +1,14 @@ +package com.cloud.projects; + + +public interface ProjectAccount { + public enum Role {Owner, Regular}; + + long getAccountId(); + + long getProjectId(); + + Role getAccountRole(); + + long getId(); +} diff --git a/api/src/com/cloud/projects/ProjectService.java b/api/src/com/cloud/projects/ProjectService.java index cb2def11986..f564a4ada37 100644 --- a/api/src/com/cloud/projects/ProjectService.java +++ b/api/src/com/cloud/projects/ProjectService.java @@ -2,6 +2,9 @@ package com.cloud.projects; import java.util.List; +import com.cloud.projects.ProjectAccount.Role; +import com.cloud.user.Account; + public interface ProjectService { /** @@ -9,12 +12,11 @@ public interface ProjectService { * * @param name - project name * @param displayText - project display text - * @param zoneId - id of the zone the project belongs to * @param accountName - account name of the project owner * @param domainId - domainid of the project owner * @return the project if created successfully, null otherwise */ - Project createProject(String name, String displayText, long zoneId, String accountName, Long domainId); + Project createProject(String name, String displayText, String accountName, Long domainId); /** * Deletes a project @@ -32,5 +34,11 @@ public interface ProjectService { */ Project getProject(long id); - List listProjects(Long id, String name, String displayText, Long zoneId, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize); + List listProjects(Long id, String name, String displayText, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize); + + ProjectAccount assignAccountToProject(Project project, long accountId, Role accountRole); + + Account getProjectOwner(long projectId); + + boolean unassignAccountFromProject(long projectId, long accountId); } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index aa72d9e2b4c..98b12691c7e 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -25,9 +25,7 @@ import java.util.Set; import com.cloud.alert.Alert; import com.cloud.api.ServerApiException; -import com.cloud.api.commands.CreateDomainCmd; import com.cloud.api.commands.CreateSSHKeyPairCmd; -import com.cloud.api.commands.DeleteDomainCmd; import com.cloud.api.commands.DeleteSSHKeyPairCmd; import com.cloud.api.commands.DestroySystemVmCmd; import com.cloud.api.commands.ExtractVolumeCmd; @@ -64,9 +62,7 @@ import com.cloud.api.commands.ListVlanIpRangesCmd; import com.cloud.api.commands.ListVolumesCmd; import com.cloud.api.commands.ListZonesByCmd; import com.cloud.api.commands.RebootSystemVmCmd; -import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.RegisterSSHKeyPairCmd; -import com.cloud.api.commands.StartSystemVMCmd; import com.cloud.api.commands.StopSystemVmCmd; import com.cloud.api.commands.UpdateDomainCmd; import com.cloud.api.commands.UpdateHostPasswordCmd; @@ -111,7 +107,7 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; /** - * Hopefull this is temporary. + * Hopefully this is temporary. * */ public interface ManagementService { @@ -236,7 +232,7 @@ public interface ManagementService { VirtualMachine stopSystemVM(StopSystemVmCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; - VirtualMachine startSystemVM(StartSystemVMCmd cmd); + VirtualMachine startSystemVM(long vmId); VirtualMachine rebootSystemVM(RebootSystemVmCmd cmd); @@ -251,15 +247,6 @@ public interface ManagementService { List searchForDomainChildren(ListDomainChildrenCmd cmd); - /** - * delete a domain with the given domainId - * - * @param cmd - * the command wrapping the delete parameters - domainId - ownerId - cleanup: whether or not to delete all - * accounts/VMs/sub-domains when deleting the domain - */ - boolean deleteDomain(DeleteDomainCmd cmd); - /** * update an existing domain * @@ -371,8 +358,6 @@ public interface ManagementService { boolean updateTemplatePermissions(UpdateIsoPermissionsCmd cmd); - String[] createApiKeyAndSecretKey(RegisterCmd cmd); - boolean updateHostPassword(UpdateHostPasswordCmd cmd); InstanceGroup updateVmGroup(UpdateVMGroupCmd cmd); diff --git a/api/src/com/cloud/user/Account.java b/api/src/com/cloud/user/Account.java index 1a89cf05b3f..60273ed11b8 100755 --- a/api/src/com/cloud/user/Account.java +++ b/api/src/com/cloud/user/Account.java @@ -27,7 +27,8 @@ public interface Account extends ControlledEntity { Normal, Admin, DomainAdmin, - CustomerCare + CustomerCare, + Project } public enum State { @@ -41,6 +42,7 @@ public interface Account extends ControlledEntity { public static final short ACCOUNT_TYPE_DOMAIN_ADMIN = 2; public static final short ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN = 3; public static final short ACCOUNT_TYPE_READ_ONLY_ADMIN = 4; + public static final short ACCOUNT_TYPE_PROJECT = 5; public static final String ACCOUNT_STATE_DISABLED = "disabled"; public static final String ACCOUNT_STATE_ENABLED = "enabled"; diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index e1124592611..372d2fe86e1 100644 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -17,25 +17,10 @@ */ package com.cloud.user; -import java.util.List; -import java.util.Set; - -import com.cloud.api.commands.CreateAccountCmd; -import com.cloud.api.commands.CreateDomainCmd; -import com.cloud.api.commands.CreateUserCmd; -import com.cloud.api.commands.DeleteAccountCmd; import com.cloud.api.commands.DeleteUserCmd; -import com.cloud.api.commands.DisableAccountCmd; -import com.cloud.api.commands.DisableUserCmd; -import com.cloud.api.commands.EnableAccountCmd; -import com.cloud.api.commands.EnableUserCmd; -import com.cloud.api.commands.LockUserCmd; +import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.UpdateAccountCmd; -import com.cloud.api.commands.UpdateResourceCountCmd; import com.cloud.api.commands.UpdateUserCmd; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit; -import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.utils.Pair; @@ -43,41 +28,45 @@ import com.cloud.utils.Pair; public interface AccountService { /** - * Creates a new user, stores the password as is so encrypted passwords are recommended. + * Creates a new user and account, stores the password as is so encrypted passwords are recommended. + * @param userName TODO + * @param password TODO + * @param firstName TODO + * @param lastName TODO + * @param email TODO + * @param timezone TODO + * @param accountName TODO + * @param accountType TODO + * @param domainId TODO + * @param networkDomain TODO * - * @param cmd - * the create command that has the username, email, password, account name, domain, timezone, etc. for creating - * the user. * @return the user if created successfully, null otherwise */ - UserAccount createAccount(CreateAccountCmd cmd); + UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain); /** * Deletes a user by userId + * @param accountId - id of the account do delete * - * @param cmd - * - the delete command defining the id of the user to be deleted. * @return true if delete was successful, false otherwise */ - boolean deleteUserAccount(DeleteAccountCmd cmd); + boolean deleteUserAccount(long accountId); /** * Disables a user by userId * - * @param cmd - * the command wrapping the userId parameter + * @param userId - the userId * @return UserAccount object */ - UserAccount disableUser(DisableUserCmd cmd); + UserAccount disableUser(long userId); /** * Enables a user * - * @param cmd - * - the command containing userId + * @param userId - the userId * @return UserAccount object */ - UserAccount enableUser(EnableUserCmd cmd); + UserAccount enableUser(long userId); /** * Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses allocated/etc. @@ -85,7 +74,7 @@ public interface AccountService { * @param userId * @return UserAccount object */ - UserAccount lockUser(LockUserCmd cmd); + UserAccount lockUser(long userId); /** * Update a user by userId @@ -97,31 +86,34 @@ public interface AccountService { /** * Disables an account by accountName and domainId - * + * @param accountName TODO + * @param domainId TODO * @param disabled * account if success * @return true if disable was successful, false otherwise */ - Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException; + Account disableAccount(String accountName, Long domainId) throws ConcurrentOperationException, ResourceUnavailableException; /** * Enables an account by accountId * - * @param cmd + * @param accountName * - the enableAccount command defining the accountId to be deleted. + * @param domainId TODO * @return account object */ - Account enableAccount(EnableAccountCmd cmd); + Account enableAccount(String accountName, long domainId); /** * Locks an account by accountId. A locked account cannot access the API, but will still have running VMs/IP addresses * allocated/etc. * - * @param cmd + * @param accountName * - the LockAccount command defining the accountId to be locked. + * @param domainId TODO * @return account object */ - Account lockAccount(DisableAccountCmd cmd); + Account lockAccount(String accountName, Long domainId); /** * Updates an account name @@ -133,44 +125,11 @@ public interface AccountService { Account updateAccount(UpdateAccountCmd cmd); - /** - * Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one. - * @param accountName TODO - * @param domainId TODO - * @param typeId TODO - * @param max TODO - * - * @return the updated/created resource limit - */ - ResourceLimit updateResourceLimit(String accountName, Long domainId, int typeId, Long max); - - - /** - * Updates an existing resource count details for the account/domain - * - * @param cmd - * the command that wraps the domainId, accountId, resource type parameters - * @return the updated/created resource counts - */ - List updateResourceCount(UpdateResourceCountCmd cmd); - - /** - * Search for resource limits for the given id and/or account and/or type and/or domain. - * @param id TODO - * @param accountName TODO - * @param domainId TODO - * @param type TODO - * @param startIndex TODO - * @param pageSizeVal TODO - * @return a list of limits that match the criteria - */ - List searchForLimits(Long id, String accountName, Long domainId, Integer type, Long startIndex, Long pageSizeVal); - Account getSystemAccount(); User getSystemUser(); - User createUser(CreateUserCmd cmd); + User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId); boolean deleteUser(DeleteUserCmd deleteUserCmd); boolean isAdmin(short accountType); @@ -179,9 +138,9 @@ public interface AccountService { Pair finalizeAccountDomainForList(Account caller, String accountName, Long domainId); - Account getActiveAccount(String accountName, Long domainId); + Account getActiveAccountByName(String accountName, Long domainId); - Account getActiveAccount(Long accountId); + Account getActiveAccountById(Long accountId); Account getAccount(Long accountId); @@ -189,18 +148,12 @@ public interface AccountService { User getUser(long userId); - Domain getDomain(long id); - boolean isRootAdmin(short accountType); User getActiveUserByRegistrationToken(String registrationToken); void markUserRegistered(long userId); - Set getDomainParentIds(long domainId); - - Set getDomainChildrenIds(String parentDomainPath); - - Domain createDomain(CreateDomainCmd cmd); + public String[] createApiKeyAndSecretKey(RegisterCmd cmd); } diff --git a/api/src/com/cloud/user/DomainService.java b/api/src/com/cloud/user/DomainService.java new file mode 100644 index 00000000000..cbeae1b07f4 --- /dev/null +++ b/api/src/com/cloud/user/DomainService.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.user; + +import com.cloud.domain.Domain; + +public interface DomainService { + + Domain createDomain(String name, Long parentId, String networkDomain); + + Domain getDomain(long id); + + /** + * Return whether a domain is a child domain of a given domain. + * + * @param parentId + * @param childId + * @return True if the domainIds are equal, or if the second domain is a child of the first domain. False otherwise. + */ + boolean isChildDomain(Long parentId, Long childId); + + boolean deleteDomain(long domainId, Boolean cleanup); +} diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java new file mode 100644 index 00000000000..45d7e96addd --- /dev/null +++ b/api/src/com/cloud/user/ResourceLimitService.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.user; + +import java.util.List; + +import com.cloud.api.commands.UpdateResourceCountCmd; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; +import com.cloud.configuration.ResourceCount; +import com.cloud.configuration.ResourceLimit; +import com.cloud.domain.Domain; + +public interface ResourceLimitService { + + /** + * Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one. + * + * @param ownerId + * the command that wraps the domainId, accountId, type, and max parameters + * @param ownerType TODO + * @param resourceType TODO + * @param max TODO + * @return the updated/created resource limit + */ + ResourceLimit updateResourceLimit(Long ownerId, ResourceOwnerType ownerType, Integer resourceType, Long max); + + /** + * Updates an existing resource count details for the account/domain + * + * @param cmd + * the command that wraps the domainId, accountId, resource type parameters + * @return the updated/created resource counts + */ + List recalculateResourceCount(UpdateResourceCountCmd cmd); + + /** + * Search for resource limits for the given id and/or account and/or type and/or domain. + * @param id TODO + * @param accountName TODO + * @param domainId TODO + * @param type TODO + * @return a list of limits that match the criteria + */ + public List searchForLimits(Long id, String accountName, Long domainId, Integer type, Long startIndex, Long pageSizeVal); + + /** + * Finds the resource limit for a specified account and type. If the account has an infinite limit, will check + * the account's parent domain, and if that limit is also infinite, will return the ROOT domain's limit. + * @param accountId + * @param type + * @return resource limit + */ + public long findCorrectResourceLimitForAccount(long accountId, ResourceType type); + + /** + * Finds the resource limit for a specified domain and type. If the domain has an infinite limit, will check + * up the domain hierarchy + * @param account + * @param type + * @return resource limit + */ + public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type); + + /** + * Increments the resource count + * @param accountId + * @param type + * @param delta + */ + public void incrementResourceCount(long accountId, ResourceType type, Long...delta); + + /** + * Decrements the resource count + * @param accountId + * @param type + * @param delta + */ + public void decrementResourceCount(long accountId, ResourceType type, Long...delta); + + /** + * Checks if a limit has been exceeded for an account + * @param account + * @param type + * @param count the number of resources being allocated, count will be added to current allocation and compared against maximum allowed allocation + * @return true if the limit has been exceeded + */ + public boolean resourceLimitExceeded(Account account, ResourceCount.ResourceType type, long...count); + + /** + * Gets the count of resources for a resource type and account + * @param account + * @param type + * @return count of resources + */ + public long getResourceCount(Account account, ResourceType type); + + boolean resourceLimitExceededForDomain(Domain domain, ResourceType type, long... count); + +} diff --git a/core/src/com/cloud/configuration/ResourceCountVO.java b/core/src/com/cloud/configuration/ResourceCountVO.java index 449c5292bc2..5ff44976e3a 100644 --- a/core/src/com/cloud/configuration/ResourceCountVO.java +++ b/core/src/com/cloud/configuration/ResourceCountVO.java @@ -26,6 +26,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.Transient; @Entity @Table(name="resource_count") @@ -38,7 +39,7 @@ public class ResourceCountVO implements ResourceCount { @Column(name="type") @Enumerated(EnumType.STRING) - private ResourceCount.ResourceType type; + private ResourceType type; @Column(name="account_id") private Long accountId; @@ -49,15 +50,24 @@ public class ResourceCountVO implements ResourceCount { @Column(name="count") private long count; - public ResourceCountVO() {} + @Transient + private ResourceOwnerType ownerType; + + public ResourceCountVO(){} - public ResourceCountVO(Long accountId, Long domainId, ResourceCount.ResourceType type, long count) { - this.accountId = accountId; - this.domainId = domainId; + public ResourceCountVO(ResourceType type, long count, long ownerId, ResourceOwnerType ownerType) { this.type = type; this.count = count; + + if (ownerType == ResourceOwnerType.Account) { + this.accountId = ownerId; + } else if (ownerType == ResourceOwnerType.Domain) { + this.domainId = ownerId; + } + this.ownerType = ownerType; } + @Override public Long getId() { return id; } @@ -66,40 +76,56 @@ public class ResourceCountVO implements ResourceCount { this.id = id; } - public ResourceCount.ResourceType getType() { + @Override + public ResourceType getType() { return type; } - public void setType(ResourceCount.ResourceType type) { + public void setType(ResourceType type) { this.type = type; } - - public Long getAccountId() { - return accountId; - } - - public void setAccountId(Long accountId) { - this.accountId = accountId; - } - - public Long getDomainId() { - return domainId; - } - - public void setDomainId(Long domainId) { - this.domainId = domainId; - } + @Override public long getCount() { return count; } - + @Override public void setCount(long count) { this.count = count; } + public Long getDomainId() { + return domainId; + } + + public Long getAccountId() { + return accountId; + } + @Override public String toString() { return new StringBuilder("REsourceCount[").append("-").append(id).append("-").append(type).append("-").append(accountId).append("-").append(domainId).append("]").toString(); } + + @Override + public long getOwnerId() { + if (accountId != null) { + return accountId; + } + + return domainId; + } + + @Override + public ResourceOwnerType getResourceOwnerType() { + return ownerType; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } } diff --git a/core/src/com/cloud/configuration/ResourceLimitVO.java b/core/src/com/cloud/configuration/ResourceLimitVO.java index aaa57ddf80a..7b20ec3b8db 100644 --- a/core/src/com/cloud/configuration/ResourceLimitVO.java +++ b/core/src/com/cloud/configuration/ResourceLimitVO.java @@ -26,6 +26,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.Transient; @Entity @Table(name="resource_limit") @@ -49,15 +50,23 @@ public class ResourceLimitVO implements ResourceLimit { @Column(name="max") private Long max; - public ResourceLimitVO() {} + @Transient + private ResourceOwnerType ownerType; + + public ResourceLimitVO() {} - public ResourceLimitVO(Long domainId, Long accountId, ResourceCount.ResourceType type, Long max) { - this.domainId = domainId; - this.accountId = accountId; + public ResourceLimitVO(ResourceCount.ResourceType type, Long max, long ownerId, ResourceOwnerType ownerType) { this.type = type; this.max = max; + + if (ownerType == ResourceOwnerType.Account) { + this.accountId = ownerId; + } else if (ownerType == ResourceOwnerType.Domain) { + this.domainId = ownerId; + } } + @Override public Long getId() { return id; } @@ -66,7 +75,8 @@ public class ResourceLimitVO implements ResourceLimit { this.id = id; } - public ResourceCount.ResourceType getType() { + @Override + public ResourceType getType() { return type; } @@ -78,23 +88,40 @@ public class ResourceLimitVO implements ResourceLimit { return domainId; } - public void setDomainId(Long domainId) { - this.domainId = domainId; - } - public Long getAccountId() { return accountId; } - public void setAccountId(Long accountId) { - this.accountId = accountId; - } - + @Override public Long getMax() { return max; } + @Override public void setMax(Long max) { this.max = max; } + + @Override + public long getOwnerId() { + if (accountId != null) { + return accountId; + } + + return domainId; + } + + @Override + public ResourceOwnerType getResourceOwnerType() { + return ownerType; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + } diff --git a/core/src/com/cloud/user/AccountVO.java b/core/src/com/cloud/user/AccountVO.java index fdcdb214702..4fd2ecf78dc 100644 --- a/core/src/com/cloud/user/AccountVO.java +++ b/core/src/com/cloud/user/AccountVO.java @@ -62,9 +62,18 @@ public class AccountVO implements Account { private String networkDomain; - public AccountVO() {} + public AccountVO() {} + public AccountVO(long id) { this.id = id; + } + + public AccountVO(String accountName, long domainId, String networkDomain, short type) { + this.accountName = accountName; + this.domainId = domainId; + this.networkDomain = networkDomain; + this.type = type; + this.state = State.enabled; } public void setNeedsCleanup(boolean value) { diff --git a/core/src/com/cloud/user/UserVO.java b/core/src/com/cloud/user/UserVO.java index 16f514c29f8..c5fc3b70250 100644 --- a/core/src/com/cloud/user/UserVO.java +++ b/core/src/com/cloud/user/UserVO.java @@ -19,6 +19,7 @@ package com.cloud.user; import java.util.Date; +import java.util.TimeZone; import javax.persistence.Column; import javax.persistence.Entity; @@ -95,6 +96,17 @@ public class UserVO implements User { public UserVO(long id) { this.id = id; } + + public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone) { + this.accountId = accountId; + this.username = username; + this.password = password; + this.firstname = firstName; + this.lastname = lastName; + this.email = email; + this.timezone = timezone; + this.state = State.enabled; + } @Override public long getId() { diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 23b2cad2101..b62188f79ac 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -23,14 +23,13 @@ import java.util.List; import java.util.Map; import com.cloud.agent.AgentManager; -import com.cloud.api.response.UserVmResponse; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationService; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterVO; @@ -72,6 +71,7 @@ import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.projects.ProjectService; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; @@ -99,8 +99,8 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; -import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; @@ -123,10 +123,10 @@ import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmData; +import com.cloud.vm.dao.VMInstanceDao; public class ApiDBUtils { private static ManagementServer _ms; - private static AccountManager _accountMgr; private static AgentManager _agentMgr; public static AsyncJobManager _asyncMgr; private static SecurityGroupManager _securityGroupMgr; @@ -168,12 +168,13 @@ public class ApiDBUtils { private static ConfigurationDao _configDao; private static ConsoleProxyDao _consoleProxyDao; private static FirewallRulesCidrsDao _firewallCidrsDao; + private static VMInstanceDao _vmDao; + private static ResourceLimitService _resourceLimitMgr; + private static ProjectService _projectMgr; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); - - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - _accountMgr = locator.getManager(AccountManager.class); + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); _agentMgr = locator.getManager(AgentManager.class); _asyncMgr = locator.getManager(AsyncJobManager.class); _securityGroupMgr = locator.getManager(SecurityGroupManager.class); @@ -214,6 +215,9 @@ public class ApiDBUtils { _configDao = locator.getDao(ConfigurationDao.class); _consoleProxyDao = locator.getDao(ConsoleProxyDao.class); _firewallCidrsDao = locator.getDao(FirewallRulesCidrsDao.class); + _vmDao = locator.getDao(VMInstanceDao.class); + _resourceLimitMgr = locator.getManager(ResourceLimitService.class); + _projectMgr = locator.getManager(ProjectService.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -224,7 +228,7 @@ public class ApiDBUtils { // /////////////////////////////////////////////////////////// public static VMInstanceVO findVMInstanceById(long vmId) { - return _ms.findVMInstanceById(vmId); + return _vmDao.findById(vmId); } public static long getMemoryOrCpuCapacitybyHost(Long hostId, short capacityType) { @@ -253,7 +257,7 @@ public class ApiDBUtils { } public static Long getPodIdForVlan(long vlanDbId) { - return _ms.getPodIdForVlan(vlanDbId); + return _networkMgr.getPodIdForVlan(vlanDbId); } public static String getVersion() { @@ -279,7 +283,7 @@ public class ApiDBUtils { return -1; } - return _accountMgr.findCorrectResourceLimit(account.getAccountId(), type); + return _resourceLimitMgr.findCorrectResourceLimitForAccount(account.getAccountId(), type); } public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) { @@ -293,7 +297,7 @@ public class ApiDBUtils { return -1; } - return _accountMgr.getResourceCount(account, type); + return _resourceLimitMgr.getResourceCount(account, type); } public static String getSecurityGroupsNamesForVm(long vmId) { @@ -622,5 +626,9 @@ public class ApiDBUtils { public static Hashtable listVmDetails(Hashtable vmData){ return _userVmDao.listVmDetails(vmData); } + + public static Account getProjectOwner(long projectId) { + return _projectMgr.getProjectOwner(projectId); + } } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 98522024197..ceb1f3172f3 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -284,6 +284,8 @@ public class ApiDispatcher { case LONG: listParam.add(Long.valueOf(token)); break; + case SHORT: + listParam.add(Short.valueOf(token)); case STRING: listParam.add(token); break; @@ -294,6 +296,9 @@ public class ApiDispatcher { case LONG: field.set(cmdObj, Long.valueOf(paramObj.toString())); break; + case SHORT: + field.set(cmdObj, Short.valueOf(paramObj.toString())); + break; case STRING: field.set(cmdObj, paramObj.toString()); break; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index b1911ddb9fd..bab8589140f 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -86,8 +86,9 @@ import com.cloud.async.AsyncJobResult; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.configuration.Configuration; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.ResourceLimit; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter; @@ -160,7 +161,6 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.InstanceGroup; import com.cloud.vm.NicProfile; -import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -389,20 +389,18 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) { ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse(); - if (limit.getDomainId() != null) { - resourceLimitResponse.setDomainId(limit.getDomainId()); - resourceLimitResponse.setDomainName(ApiDBUtils.findDomainById(limit.getDomainId()).getName()); - } - - if (limit.getAccountId() != null) { - Account accountTemp = ApiDBUtils.findAccountById(limit.getAccountId()); + if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) { + resourceLimitResponse.setDomainId(limit.getOwnerId()); + resourceLimitResponse.setDomainName(ApiDBUtils.findDomainById(limit.getOwnerId()).getName()); + } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) { + Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId()); if (accountTemp != null) { resourceLimitResponse.setAccountName(accountTemp.getAccountName()); resourceLimitResponse.setDomainId(accountTemp.getDomainId()); resourceLimitResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName()); } } - resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().ordinal()).toString()); + resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); resourceLimitResponse.setMax(limit.getMax()); resourceLimitResponse.setObjectName("resourcelimit"); @@ -413,19 +411,19 @@ public class ApiResponseHelper implements ResponseGenerator { public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) { ResourceCountResponse resourceCountResponse = new ResourceCountResponse(); - if (resourceCount.getAccountId() != null) { - Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getAccountId()); + if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) { + Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId()); if (accountTemp != null) { resourceCountResponse.setAccountName(accountTemp.getAccountName()); resourceCountResponse.setDomainId(accountTemp.getDomainId()); resourceCountResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName()); } - } else if (resourceCount.getDomainId() != null) { - resourceCountResponse.setDomainId(resourceCount.getDomainId()); - resourceCountResponse.setDomainName(ApiDBUtils.findDomainById(resourceCount.getDomainId()).getName()); + } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) { + resourceCountResponse.setDomainId(resourceCount.getOwnerId()); + resourceCountResponse.setDomainName(ApiDBUtils.findDomainById(resourceCount.getOwnerId()).getName()); } - resourceCountResponse.setResourceType(Integer.valueOf(resourceCount.getType().ordinal()).toString()); + resourceCountResponse.setResourceType(Integer.valueOf(resourceCount.getType().getOrdinal()).toString()); resourceCountResponse.setResourceCount(resourceCount.getCount()); resourceCountResponse.setObjectName("resourcecount"); return resourceCountResponse; @@ -2254,14 +2252,12 @@ public class ApiResponseHelper implements ResponseGenerator { response.setId(project.getId()); response.setName(project.getName()); response.setDisplaytext(project.getDisplayText()); - response.setZoneId(project.getDataCenterId()); - Account owner = ApiDBUtils.findAccountById(project.getAccountId()); - response.setAccountName(owner.getAccountName()); - - Domain domain = ApiDBUtils.findDomainById(owner.getDomainId()); + Domain domain = ApiDBUtils.findDomainById(project.getDomainId()); response.setDomainId(domain.getId()); response.setDomain(domain.getName()); + + response.setOwner(ApiDBUtils.getProjectOwner(project.getId()).getAccountName()); response.setObjectName("project"); return response; diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index a10f9ed0b9f..ea2e7990497 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -99,7 +99,8 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.server.ManagementServer; import com.cloud.user.Account; -import com.cloud.user.AccountService; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.user.UserContext; @@ -123,8 +124,8 @@ public class ApiServer implements HttpRequestHandler { public static String jsonContentType = "text/javascript"; private Properties _apiCommands = null; private ApiDispatcher _dispatcher; - private ManagementServer _ms = null; - private AccountService _accountMgr = null; + private AccountManager _accountMgr = null; + private DomainManager _domainMgr = null; private AsyncJobManager _asyncMgr = null; private Account _systemAccount = null; private User _systemUser = null; @@ -215,13 +216,13 @@ public class ApiServer implements HttpRequestHandler { s_logger.error("Exception loading properties file", ioex); } - _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - _accountMgr = locator.getManager(AccountService.class); + _accountMgr = locator.getManager(AccountManager.class); _asyncMgr = locator.getManager(AsyncJobManager.class); _systemAccount = _accountMgr.getSystemAccount(); _systemUser = _accountMgr.getSystemUser(); _dispatcher = ApiDispatcher.getInstance(); + _domainMgr = locator.getManager(DomainManager.class); int apiPort = 8096; // default port ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); @@ -531,7 +532,7 @@ public class ApiServer implements HttpRequestHandler { // if userId not null, that mean that user is logged in if (userId != null) { Long accountId = ApiDBUtils.findUserById(userId).getAccountId(); - Account userAccount = _ms.findAccountById(accountId); + Account userAccount = _accountMgr.getAccount(accountId); short accountType = userAccount.getType(); if (!isCommandAvailable(accountType, commandName)) { @@ -618,7 +619,7 @@ public class ApiServer implements HttpRequestHandler { txn.close(); User user = null; // verify there is a user with this api key - Pair userAcctPair = _ms.findUserByApiKey(apiKey); + Pair userAcctPair = _accountMgr.findUserByApiKey(apiKey); if (userAcctPair == null) { s_logger.info("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey); return false; @@ -676,7 +677,7 @@ public class ApiServer implements HttpRequestHandler { if (domainPath == null || domainPath.trim().length() == 0) { domainId = DomainVO.ROOT_DOMAIN; } else { - Domain domainObj = _ms.findDomainByPath(domainPath); + Domain domainObj = _domainMgr.findDomainByPath(domainPath); if (domainObj != null) { domainId = domainObj.getId(); } else { // if an unknown path is passed in, fail the login call @@ -685,7 +686,7 @@ public class ApiServer implements HttpRequestHandler { } } - UserAccount userAcct = _ms.authenticateUser(username, password, domainId, requestParameters); + UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, requestParameters); if (userAcct != null) { String timezone = userAcct.getTimezone(); float offsetInHrs = 0f; @@ -700,7 +701,7 @@ public class ApiServer implements HttpRequestHandler { s_logger.info("Timezone offset from UTC is: " + offsetInHrs); } - Account account = _ms.findAccountById(userAcct.getAccountId()); + Account account = _accountMgr.getAccount(userAcct.getAccountId()); // set the userId and account object for everyone session.setAttribute("userid", userAcct.getId()); @@ -733,15 +734,15 @@ public class ApiServer implements HttpRequestHandler { } public void logoutUser(long userId) { - _ms.logoutUser(Long.valueOf(userId)); + _accountMgr.logoutUser(Long.valueOf(userId)); return; } public boolean verifyUser(Long userId) { - User user = _ms.findUserById(userId); + User user = _accountMgr.getUser(userId); Account account = null; if (user != null) { - account = _ms.findAccountById(user.getAccountId()); + account = _accountMgr.getAccount(user.getAccountId()); } if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) || !account.getState().equals(Account.State.enabled)) { diff --git a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java index 86b52908ccf..4d2d5c1ffb7 100644 --- a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java +++ b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java @@ -10,7 +10,7 @@ import org.apache.log4j.Logger; import com.cloud.api.commands.DeleteIsoCmd; import com.cloud.api.commands.RegisterIsoCmd; import com.cloud.api.commands.RegisterTemplateCmd; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; @@ -19,10 +19,9 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; -import com.cloud.template.HyervisorTemplateAdapter; +import com.cloud.storage.VMTemplateZoneVO; import com.cloud.template.TemplateAdapter; import com.cloud.template.TemplateAdapterBase; import com.cloud.template.TemplateProfile; @@ -105,7 +104,7 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem templateCreateUsage(template, pxe); } - _accountMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); + _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); return template; } @@ -179,7 +178,7 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem success = false; } else if (_tmpltDao.remove(templateId)) { // Decrement the number of templates - _accountMgr.decrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); } } finally { diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java index 7db4759726e..68e064a934c 100755 --- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java @@ -41,7 +41,7 @@ import com.cloud.api.commands.DeployVMCmd; import com.cloud.api.commands.DetachVolumeCmd; import com.cloud.api.commands.UpgradeVMCmd; import com.cloud.baremetal.PxeServerManager.PxeServerType; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; @@ -247,7 +247,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet } // check if account/domain is with in resource limits to create a new vm - if (_accountMgr.resourceLimitExceeded(owner, ResourceType.user_vm)) { + if (_resourceLimitMgr.resourceLimitExceeded(owner, ResourceType.user_vm)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of virtual machines for account: " + owner.getAccountName() + " has been exceeded."); rae.setResourceType("vm"); @@ -384,7 +384,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, cmd.getZoneId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString()); _usageEventDao.persist(usageEvent); - _accountMgr.incrementResourceCount(accountId, ResourceType.user_vm); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); // Assign instance to the group try { diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 0d51fde2e54..efcbeefce17 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -59,7 +59,7 @@ import com.cloud.api.commands.UpdateServiceOfferingCmd; import com.cloud.api.commands.UpdateZoneCmd; import com.cloud.capacity.Capacity; import com.cloud.capacity.dao.CapacityDao; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterVO; @@ -117,6 +117,7 @@ import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -199,6 +200,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Adapters _secChecker; @Inject CapacityDao _capacityDao; + @Inject + ResourceLimitService _resourceLimitMgr; // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao? protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); @@ -2049,7 +2052,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (forVirtualNetwork) { if (account != null) { // verify resource limits - long ipResourceLimit = _accountMgr.findCorrectResourceLimit(account.getId(), ResourceType.public_ip); + long ipResourceLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(account.getId(), ResourceType.public_ip); long accountIpRange = NetUtils.ip2Long(endIP) - NetUtils.ip2Long(startIP) + 1; if (s_logger.isDebugEnabled()) { s_logger.debug(" IPResourceLimit " + ipResourceLimit + " accountIpRange " + accountIpRange); diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index a2a31420aa7..c593b174145 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -97,7 +97,6 @@ import com.cloud.network.ovs.dao.VmFlowLogDaoImpl; import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; -import com.cloud.network.security.SecurityGroupManagerImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; import com.cloud.network.security.dao.IngressRuleDaoImpl; import com.cloud.network.security.dao.SecurityGroupDaoImpl; @@ -109,7 +108,9 @@ import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; import com.cloud.projects.ProjectManagerImpl; import com.cloud.projects.dao.ProjectDaoImpl; +import com.cloud.projects.dao.ProjectAccountDaoImpl; import com.cloud.resource.ResourceManagerImpl; +import com.cloud.resourcelimit.ResourceLimitManagerImpl; import com.cloud.service.dao.ServiceOfferingDaoImpl; import com.cloud.storage.OCFS2ManagerImpl; import com.cloud.storage.StorageManagerImpl; @@ -140,6 +141,7 @@ import com.cloud.template.TemplateAdapter; import com.cloud.template.TemplateAdapter.TemplateAdapterType; import com.cloud.template.TemplateManagerImpl; import com.cloud.user.AccountManagerImpl; +import com.cloud.user.DomainManagerImpl; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.SSHKeyPairDaoImpl; import com.cloud.user.dao.UserAccountDaoImpl; @@ -273,6 +275,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("ProjectDao", ProjectDaoImpl.class); addDao("InlineLoadBalancerNicMapDao", InlineLoadBalancerNicMapDaoImpl.class); addDao("ElasticLbVmMap", ElasticLbVmMapDaoImpl.class); + addDao("ProjectsAccountDao", ProjectAccountDaoImpl.class); info = addDao("HypervisorCapabilitiesDao",HypervisorCapabilitiesDaoImpl.class); info.addParameter("cache.size", "100"); info.addParameter("cache.time.to.live", "600"); @@ -289,6 +292,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com protected void populateManagers() { addManager("StackMaidManager", CheckPointManagerImpl.class); addManager("account manager", AccountManagerImpl.class); + addManager("domain manager", DomainManagerImpl.class); + addManager("resource limit manager", ResourceLimitManagerImpl.class); addManager("configuration manager", ConfigurationManagerImpl.class); addManager("network manager", NetworkManagerImpl.class); addManager("download manager", DownloadMonitorImpl.class); diff --git a/server/src/com/cloud/configuration/dao/ResourceCountDao.java b/server/src/com/cloud/configuration/dao/ResourceCountDao.java index 9a5c17fd971..0a4f6cbd2ff 100644 --- a/server/src/com/cloud/configuration/dao/ResourceCountDao.java +++ b/server/src/com/cloud/configuration/dao/ResourceCountDao.java @@ -21,71 +21,43 @@ package com.cloud.configuration.dao; import java.util.List; import java.util.Set; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCountVO; -import com.cloud.configuration.ResourceLimit.OwnerType; import com.cloud.utils.db.GenericDao; public interface ResourceCountDao extends GenericDao { - /** - * Get the count of in use resources for an account by type - * @param accountId the id of the account to get the resource count - * @param type the type of resource (e.g. user_vm, public_ip, volume) - * @return the count of resources in use for the given type and account - */ - public long getAccountCount(long accountId, ResourceType type); + * Get the count of in use resources for a owner by type + * @param domainId the id of the domain to get the resource count + * @param type the type of resource (e.g. user_vm, public_ip, volume) + * @return the count of resources in use for the given type and domain + * @param ownertype the type of the owner - can be Account and Domain + */ + long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type); - /** - * Get the count of in use resources for a domain by type - * @param domainId the id of the domain to get the resource count - * @param type the type of resource (e.g. user_vm, public_ip, volume) - * @return the count of resources in use for the given type and domain - */ - public long getDomainCount(long domainId, ResourceType type); - - /** - * Set the count of in use resources for an account by type - * @param accountId the id of the account to set the resource count - * @param type the type of resource (e.g. user_vm, public_ip, volume) - * @param the count of resources in use for the given type and account - */ - public void setAccountCount(long accountId, ResourceType type, long count); - - /** - * Get the count of in use resources for a domain by type - * @param domainId the id of the domain to set the resource count - * @param type the type of resource (e.g. user_vm, public_ip, volume) - * @param the count of resources in use for the given type and domain - */ - public void setDomainCount(long domainId, ResourceType type, long count); - - /** - * Update the count of resources in use for the given domain and given resource type - * @param domainId the id of the domain to update resource count - * @param type the type of resource (e.g. user_vm, public_ip, volume) - * @param increment whether the change is adding or subtracting from the current count - * @param delta the number of resources being added/released - */ - public void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta); + /** + * Get the count of in use resources for a resource by type + * @param domainId the id of the domain to set the resource count + * @param type the type of resource (e.g. user_vm, public_ip, volume) + * @param the count of resources in use for the given type and domain + * @param ownertype the type of the owner - can be Account and Domain + */ + void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count); + + //this api is deprecated as it's used by upgrade code only + @Deprecated + void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta); boolean updateById(long id, boolean increment, long delta); - ResourceCountVO findByDomainIdAndType(long domainId, ResourceType type); - - ResourceCountVO findByAccountIdAndType(long accountId, ResourceType type); + void createResourceCounts(long ownerId, ResourceOwnerType ownerType); - Set listAllRowsToUpdateForAccount(long accountId, long domainId, ResourceType type); + List listByOwnerId(long ownerId, ResourceOwnerType ownerType); - Set listRowsToUpdateForDomain(long domainId, ResourceType type); - - void createResourceCounts(long ownerId, OwnerType ownerType); + ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type); - List listByDomainId(long domainId); + List listResourceCountByOwnerType(ResourceOwnerType ownerType); - List listByAccountId(long accountId); - - List listDomainCounts(); - - List listAccountCounts(); + Set listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type); } diff --git a/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java index 1e50e3c023d..06989ebdd8d 100644 --- a/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java +++ b/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java @@ -18,17 +18,21 @@ package com.cloud.configuration.dao; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.ejb.Local; -import com.cloud.configuration.ResourceCount.ResourceType; -import com.cloud.configuration.ResourceCount; +import com.cloud.configuration.Resource; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCountVO; import com.cloud.configuration.ResourceLimit; import com.cloud.domain.dao.DomainDaoImpl; +import com.cloud.exception.UnsupportedServiceException; +import com.cloud.user.dao.AccountDaoImpl; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -38,24 +42,20 @@ import com.cloud.utils.db.Transaction; @Local(value={ResourceCountDao.class}) public class ResourceCountDaoImpl extends GenericDaoBase implements ResourceCountDao { - private SearchBuilder AccountTypeSearch; - private SearchBuilder DomainTypeSearch; + private SearchBuilder TypeSearch; private SearchBuilder AccountSearch; private SearchBuilder DomainSearch; protected final DomainDaoImpl _domainDao = ComponentLocator.inject(DomainDaoImpl.class); + protected final AccountDaoImpl _accountDao = ComponentLocator.inject(AccountDaoImpl.class); public ResourceCountDaoImpl() { - AccountTypeSearch = createSearchBuilder(); - AccountTypeSearch.and("type", AccountTypeSearch.entity().getType(), SearchCriteria.Op.EQ); - AccountTypeSearch.and("accountId", AccountTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountTypeSearch.done(); - - DomainTypeSearch = createSearchBuilder(); - DomainTypeSearch.and("type", DomainTypeSearch.entity().getType(), SearchCriteria.Op.EQ); - DomainTypeSearch.and("domainId", DomainTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ); - DomainTypeSearch.done(); + TypeSearch = createSearchBuilder(); + TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeSearch.and("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ); + TypeSearch.done(); AccountSearch = createSearchBuilder(); AccountSearch.and("accountId", AccountSearch.entity().getAccountId(), SearchCriteria.Op.NNULL); @@ -65,60 +65,47 @@ public class ResourceCountDaoImpl extends GenericDaoBase DomainSearch.and("domainId", DomainSearch.entity().getDomainId(), SearchCriteria.Op.NNULL); DomainSearch.done(); } - + + @Override + public ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type) { + SearchCriteria sc = TypeSearch.create(); + sc.setParameters("type", type); + + if (ownerType == ResourceOwnerType.Account) { + sc.setParameters("accountId", ownerId); + return findOneIncludingRemovedBy(sc); + } else if (ownerType == ResourceOwnerType.Domain) { + sc.setParameters("domainId", ownerId); + return findOneIncludingRemovedBy(sc); + } else { + return null; + } + } + @Override - public ResourceCountVO findByAccountIdAndType(long accountId, ResourceType type) { - SearchCriteria sc = AccountTypeSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("type", type); - - return findOneIncludingRemovedBy(sc); + public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type) { + ResourceCountVO vo = findByOwnerAndType(ownerId, ownerType, type); + if (vo != null) { + return vo.getCount(); + } else { + return 0; + } + } + + @Override + public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count) { + ResourceCountVO resourceCountVO = findByOwnerAndType(ownerId, ownerType, type); + if (count != resourceCountVO.getCount()) { + resourceCountVO.setCount(count); + update(resourceCountVO.getId(), resourceCountVO); + } } - @Override - public ResourceCountVO findByDomainIdAndType(long domainId, ResourceType type) { - SearchCriteria sc = DomainTypeSearch.create(); - sc.setParameters("domainId", domainId); - sc.setParameters("type", type); - - return findOneIncludingRemovedBy(sc); - } - - @Override - public long getAccountCount(long accountId, ResourceType type) { - ResourceCountVO resourceCountVO = findByAccountIdAndType(accountId, type); - return resourceCountVO.getCount(); - } - - @Override - public long getDomainCount(long domainId, ResourceType type) { - ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type); - return resourceCountVO.getCount(); - } - - @Override - public void setAccountCount(long accountId, ResourceType type, long count) { - ResourceCountVO resourceCountVO = findByAccountIdAndType(accountId, type); - if (count != resourceCountVO.getCount()) { - resourceCountVO.setCount(count); - update(resourceCountVO.getId(), resourceCountVO); - } - } - - @Override - public void setDomainCount(long domainId, ResourceType type, long count) { - ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type); - if (count != resourceCountVO.getCount()) { - resourceCountVO.setCount(count); - update(resourceCountVO.getId(), resourceCountVO); - } - } - - @Override + @Override @Deprecated public void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta) { delta = increment ? delta : delta * -1; - ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type); + ResourceCountVO resourceCountVO = findByOwnerAndType(domainId, ResourceOwnerType.Domain, type); resourceCountVO.setCount(resourceCountVO.getCount() + delta); update(resourceCountVO.getId(), resourceCountVO); } @@ -132,80 +119,95 @@ public class ResourceCountDaoImpl extends GenericDaoBase return update(resourceCountVO.getId(), resourceCountVO); } - @Override - public Set listAllRowsToUpdateForAccount(long accountId, long domainId, ResourceType type) { - Set rowIds = new HashSet(); - //Create resource count records if not exist - //1) for account - ResourceCountVO accountCountRecord = findByAccountIdAndType(accountId, type); - rowIds.add(accountCountRecord.getId()); - - //2) for domain(s) - rowIds.addAll(listRowsToUpdateForDomain(domainId, type)); - - return rowIds; - } - - @Override - public Set listRowsToUpdateForDomain(long domainId, ResourceType type) { + private Set listRowsToUpdateForDomain(long domainId, ResourceType type) { Set rowIds = new HashSet(); Set domainIdsToUpdate = _domainDao.getDomainParentIds(domainId); for (Long domainIdToUpdate : domainIdsToUpdate) { - ResourceCountVO domainCountRecord = findByDomainIdAndType(domainIdToUpdate, type); + ResourceCountVO domainCountRecord = findByOwnerAndType(domainIdToUpdate, ResourceOwnerType.Domain, type); rowIds.add(domainCountRecord.getId()); } return rowIds; } + @Override + public Set listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type) { + Set rowIds = new HashSet(); + + if (ownerType == ResourceOwnerType.Account) { + //get records for account + ResourceCountVO accountCountRecord = findByOwnerAndType(ownerId, ResourceOwnerType.Account, type); + rowIds.add(accountCountRecord.getId()); + //get records for account's domain and all its parent domains + rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(),type)); + } else if (ownerType == ResourceOwnerType.Domain) { + return listRowsToUpdateForDomain(ownerId, type); + } + + return rowIds; + } + @Override @DB - public void createResourceCounts(long ownerId, ResourceLimit.OwnerType ownerType){ - Long accountId = null; - Long domainId = null; - if (ownerType == ResourceLimit.OwnerType.Account) { - accountId = ownerId; - } else if (ownerType == ResourceLimit.OwnerType.Domain) { - domainId = ownerId; - } + public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType){ Transaction txn = Transaction.currentTxn(); txn.start(); - ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); + ResourceType[] resourceTypes = Resource.ResourceType.values(); for (ResourceType resourceType : resourceTypes) { - ResourceCountVO resourceCountVO = new ResourceCountVO(accountId, domainId, resourceType, 0); + if (!resourceType.supportsOwner(ownerType)) { + continue; + } + ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType); persist(resourceCountVO); } txn.commit(); } - @Override - public List listByDomainId(long domainId) { - SearchCriteria sc = DomainTypeSearch.create(); + private List listByDomainId(long domainId) { + SearchCriteria sc = TypeSearch.create(); sc.setParameters("domainId", domainId); return listBy(sc); } - @Override - public List listByAccountId(long accountId) { - SearchCriteria sc = AccountTypeSearch.create(); + private List listByAccountId(long accountId) { + SearchCriteria sc = TypeSearch.create(); sc.setParameters("accountId", accountId); return listBy(sc); } + + @Override + public List listByOwnerId(long ownerId, ResourceOwnerType ownerType) { + if (ownerType == ResourceOwnerType.Account) { + return listByAccountId(ownerId); + } else if (ownerType == ResourceOwnerType.Domain) { + return listByDomainId(ownerId); + } else { + return new ArrayList(); + } + } @Override - public List listDomainCounts() { - SearchCriteria sc = DomainSearch.create(); - - return listBy(sc); + public List listResourceCountByOwnerType(ResourceOwnerType ownerType) { + if (ownerType == ResourceOwnerType.Account) { + return listBy(AccountSearch.create()); + } else if (ownerType == ResourceOwnerType.Domain) { + return listBy(DomainSearch.create()); + } else { + return new ArrayList(); + } } - + @Override - public List listAccountCounts() { - SearchCriteria sc = AccountSearch.create(); - - return listBy(sc); - } + public ResourceCountVO persist(ResourceCountVO resourceCountVO){ + ResourceOwnerType ownerType = resourceCountVO.getResourceOwnerType(); + ResourceType resourceType = resourceCountVO.getType(); + if (!resourceType.supportsOwner(ownerType)) { + throw new UnsupportedServiceException("Resource type " + resourceType + " is not supported for owner of type " + ownerType.getName()); + } + + return super.persist(resourceCountVO); + } } \ No newline at end of file diff --git a/server/src/com/cloud/configuration/dao/ResourceLimitDao.java b/server/src/com/cloud/configuration/dao/ResourceLimitDao.java index 2addacd6b95..90ac4ffbcd8 100644 --- a/server/src/com/cloud/configuration/dao/ResourceLimitDao.java +++ b/server/src/com/cloud/configuration/dao/ResourceLimitDao.java @@ -20,18 +20,15 @@ package com.cloud.configuration.dao; import java.util.List; +import com.cloud.configuration.Resource.ResourceOwnerType; import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit.OwnerType; import com.cloud.configuration.ResourceLimitVO; import com.cloud.utils.db.GenericDao; public interface ResourceLimitDao extends GenericDao { - public ResourceLimitVO findByDomainIdAndType(Long domainId, ResourceCount.ResourceType type); - public ResourceLimitVO findByAccountIdAndType(Long accountId, ResourceCount.ResourceType type); - public List listByAccountId(Long accountId); - public List listByDomainId(Long domainId); - public boolean update(Long id, Long max); - public ResourceCount.ResourceType getLimitType(String type); - public ResourceLimitVO findByOwnerIdAndType(long ownerId, OwnerType ownerType, ResourceCount.ResourceType type); + List listByOwner(Long ownerId, ResourceOwnerType ownerType); + boolean update(Long id, Long max); + ResourceCount.ResourceType getLimitType(String type); + ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type); } diff --git a/server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java b/server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java index 3cabd5f6acb..504068e808b 100644 --- a/server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java +++ b/server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java @@ -18,12 +18,15 @@ package com.cloud.configuration.dao; +import java.util.ArrayList; import java.util.List; import javax.ejb.Local; +import com.cloud.configuration.Resource; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit.OwnerType; import com.cloud.configuration.ResourceLimitVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -40,49 +43,24 @@ public class ResourceLimitDaoImpl extends GenericDaoBase IdTypeSearch.and("accountId", IdTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ); IdTypeSearch.done(); } - - public ResourceLimitVO findByDomainIdAndType(Long domainId, ResourceCount.ResourceType type) { - if (domainId == null || type == null) - return null; - - SearchCriteria sc = IdTypeSearch.create(); - sc.setParameters("domainId", domainId); - sc.setParameters("type", type); - - return findOneIncludingRemovedBy(sc); + + @Override + public List listByOwner(Long ownerId, ResourceOwnerType ownerType) { + SearchCriteria sc = IdTypeSearch.create(); + + if (ownerType == ResourceOwnerType.Account) { + sc.setParameters("accountId", ownerId); + return listBy(sc); + } else if (ownerType == ResourceOwnerType.Domain) { + sc.setParameters("domainId", ownerId); + return listBy(sc); + } else { + return new ArrayList(); + } } - public List listByDomainId(Long domainId) { - if (domainId == null) - return null; - - SearchCriteria sc = IdTypeSearch.create(); - sc.setParameters("domainId", domainId); - - return listIncludingRemovedBy(sc); - } - - public ResourceLimitVO findByAccountIdAndType(Long accountId, ResourceCount.ResourceType type) { - if (accountId == null || type == null) - return null; - - SearchCriteria sc = IdTypeSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("type", type); - - return findOneIncludingRemovedBy(sc); - } - - public List listByAccountId(Long accountId) { - if (accountId == null) - return null; - - SearchCriteria sc = IdTypeSearch.create(); - sc.setParameters("accountId", accountId); - - return listIncludingRemovedBy(sc); - } + @Override public boolean update(Long id, Long max) { ResourceLimitVO limit = findById(id); if (max != null) @@ -92,11 +70,12 @@ public class ResourceLimitDaoImpl extends GenericDaoBase return update(id, limit); } + @Override public ResourceCount.ResourceType getLimitType(String type) { - ResourceCount.ResourceType[] validTypes = ResourceCount.ResourceType.values(); + ResourceType[] validTypes = Resource.ResourceType.values(); - for (ResourceCount.ResourceType validType : validTypes) { - if (validType.toString().equals(type)) { + for (ResourceType validType : validTypes) { + if (validType.getName().equals(type)) { return validType; } } @@ -104,11 +83,16 @@ public class ResourceLimitDaoImpl extends GenericDaoBase } @Override - public ResourceLimitVO findByOwnerIdAndType(long ownerId, OwnerType ownerType, ResourceCount.ResourceType type) { - if (ownerType == OwnerType.Account) { - return findByAccountIdAndType(ownerId, type); - } else if (ownerType == OwnerType.Domain) { - return findByDomainIdAndType(ownerId, type); + public ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type) { + SearchCriteria sc = IdTypeSearch.create(); + sc.setParameters("type", type); + + if (ownerType == ResourceOwnerType.Account) { + sc.setParameters("accountId", ownerId); + return findOneBy(sc); + } else if (ownerType == ResourceOwnerType.Domain) { + sc.setParameters("domainId", ownerId); + return findOneBy(sc); } else { return null; } diff --git a/server/src/com/cloud/dc/dao/PodVlanMapDao.java b/server/src/com/cloud/dc/dao/PodVlanMapDao.java index bf18b401050..d06b7be4412 100644 --- a/server/src/com/cloud/dc/dao/PodVlanMapDao.java +++ b/server/src/com/cloud/dc/dao/PodVlanMapDao.java @@ -26,7 +26,7 @@ import com.cloud.utils.db.GenericDao; public interface PodVlanMapDao extends GenericDao { public List listPodVlanMapsByPod(long podId); - public List listPodVlanMapsByVlan(long vlanDbId); + public PodVlanMapVO listPodVlanMapsByVlan(long vlanDbId); public PodVlanMapVO findPodVlanMap(long podId, long vlanDbId); } diff --git a/server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java b/server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java index 00410a4002b..88d4886134f 100644 --- a/server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java +++ b/server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java @@ -42,10 +42,10 @@ public class PodVlanMapDaoImpl extends GenericDaoBase implem } @Override - public List listPodVlanMapsByVlan(long vlanDbId) { + public PodVlanMapVO listPodVlanMapsByVlan(long vlanDbId) { SearchCriteria sc = VlanSearch.create(); sc.setParameters("vlanDbId", vlanDbId); - return listIncludingRemovedBy(sc); + return findOneBy(sc); } @Override diff --git a/server/src/com/cloud/domain/DomainVO.java b/server/src/com/cloud/domain/DomainVO.java index 76e9cbf53ee..07194d27a7e 100644 --- a/server/src/com/cloud/domain/DomainVO.java +++ b/server/src/com/cloud/domain/DomainVO.java @@ -66,6 +66,9 @@ public class DomainVO implements Domain { @Column(name="network_domain") private String networkDomain; + + @Column(name="type") + private Domain.Type type = Domain.Type.Normal; public DomainVO() {} @@ -81,7 +84,16 @@ public class DomainVO implements Domain { this.path =""; this.level = 0; this.state = Domain.State.Active; - this.networkDomain = networkDomain; + this.networkDomain = networkDomain; + + } + + public DomainVO(String name, long owner, Long parentId, String networkDomain, Domain.Type type) { + this(name, owner, parentId, networkDomain); + + if (type != null) { + this.type = type; + } } @Override @@ -185,6 +197,11 @@ public class DomainVO implements Domain { public void setNetworkDomain(String domainSuffix) { this.networkDomain = domainSuffix; + } + + @Override + public Domain.Type getType() { + return type; } } diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index e6b7d7c5770..8bd840d579b 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -367,7 +367,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu long vmId = work.getInstanceId(); - VMInstanceVO vm = _itMgr.findById(work.getType(), work.getInstanceId()); + VMInstanceVO vm = _itMgr.findByIdAndType(work.getType(), work.getInstanceId()); if (vm == null) { s_logger.info("Unable to find vm: " + vmId); return null; @@ -484,7 +484,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu } } - vm = _itMgr.findById(vm.getType(), vm.getId()); + vm = _itMgr.findByIdAndType(vm.getType(), vm.getId()); if (!_forceHA && !vm.isHaEnabled()) { if (s_logger.isDebugEnabled()) { @@ -532,7 +532,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu _alertMgr.sendAlert(alertType, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc); } - vm = _itMgr.findById(vm.getType(), vm.getId()); + vm = _itMgr.findByIdAndType(vm.getType(), vm.getId()); work.setUpdateTime(vm.getUpdated()); work.setPreviousState(vm.getState()); return (System.currentTimeMillis() >> 10) + _restartRetryInterval; @@ -578,7 +578,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu } protected Long destroyVM(HaWorkVO work) { - final VMInstanceVO vm = _itMgr.findById(work.getType(), work.getInstanceId()); + final VMInstanceVO vm = _itMgr.findByIdAndType(work.getType(), work.getInstanceId()); s_logger.info("Destroying " + vm.toString()); try { if (vm.getState() != State.Destroyed) { @@ -611,7 +611,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager, Clu } protected Long stopVM(final HaWorkVO work) throws ConcurrentOperationException { - VMInstanceVO vm = _itMgr.findById(work.getType(), work.getInstanceId()); + VMInstanceVO vm = _itMgr.findByIdAndType(work.getType(), work.getInstanceId()); if (vm == null) { s_logger.info("No longer can find VM " + work.getInstanceId() + ". Throwing away " + work); work.setStep(Step.Done); diff --git a/server/src/com/cloud/migration/Db21to22MigrationUtil.java b/server/src/com/cloud/migration/Db21to22MigrationUtil.java index 8a964ca2536..906ecaa58a3 100644 --- a/server/src/com/cloud/migration/Db21to22MigrationUtil.java +++ b/server/src/com/cloud/migration/Db21to22MigrationUtil.java @@ -27,7 +27,8 @@ import java.util.Queue; import org.apache.log4j.xml.DOMConfigurator; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCountVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceCountDao; @@ -148,7 +149,7 @@ public class Db21to22MigrationUtil { SearchBuilder sb = _resourceCountDao.createSearchBuilder(); sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); - for (ResourceType type : ResourceType.values()) { + for (ResourceType type : Resource.ResourceType.values()) { SearchCriteria sc = sb.create(); sc.setParameters("type", type); diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index d64f21ff861..1fe3c6371f8 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -217,5 +217,7 @@ public interface NetworkManager extends NetworkService { String getIpInNetwork(long vmId, long networkId); String getIpInNetworkIncludingRemoved(long vmId, long networkId); + + Long getPodIdForVlan(long vlanDbId); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index ba68dc7bab6..9cb798abc3d 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -50,7 +50,7 @@ import com.cloud.api.commands.RestartNetworkCmd; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.AccountVlanMapVO; @@ -118,6 +118,8 @@ import com.cloud.org.Grouping; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.DomainManager; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -223,8 +225,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag FirewallManager _firewallMgr; @Inject FirewallRulesDao _firewallDao; - + @Inject + ResourceLimitService _resourceLimitMgr; @Inject DomainRouterDao _routerDao; + @Inject DomainManager _domainMgr; + private final HashMap _systemNetworks = new HashMap(5); @@ -353,7 +358,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _usageEventDao.persist(usageEvent); // don't increment resource count for direct ip addresses if (addr.getAssociatedWithNetworkId() != null) { - _accountMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); + _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); } } @@ -386,7 +391,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, dcId, null, network.getId()); if (addrs.size() == 0) { // Check that the maximum number of public IPs for the given accountId will not be exceeded - if (_accountMgr.resourceLimitExceeded(owner, ResourceType.public_ip)) { + if (_resourceLimitMgr.resourceLimitExceeded(owner, ResourceType.public_ip)) { throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); } @@ -455,7 +460,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, , permission denied"); } if (accountName != null) { - Account userAccount = _accountMgr.getActiveAccount(accountName, domainId); + Account userAccount = _accountMgr.getActiveAccountByName(accountName, domainId); if (userAccount != null) { account = userAccount; } else { @@ -521,7 +526,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public List getVirtualNetworksOwnedByAccountInZone(String accountName, long domainId, long zoneId) { - Account owner = _accountMgr.getActiveAccount(accountName, domainId); + Account owner = _accountMgr.getActiveAccountByName(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } @@ -539,7 +544,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account caller = UserContext.current().getCaller(); long userId = UserContext.current().getCallerUserId(); - Account ipOwner = _accountMgr.getActiveAccount(accountName, domainId); + Account ipOwner = _accountMgr.getActiveAccountByName(accountName, domainId); if (ipOwner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } @@ -603,7 +608,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Check that the maximum number of public IPs for the given // accountId will not be exceeded - if (_accountMgr.resourceLimitExceeded(accountToLock, ResourceType.public_ip)) { + if (_resourceLimitMgr.resourceLimitExceeded(accountToLock, ResourceType.public_ip)) { UserContext.current().setEventDetails("Maximum number of public IP addresses for account: " + accountToLock.getAccountName() + " has been exceeded."); ResourceAllocationException rae = new ResourceAllocationException("Maximum number of public IP addresses for account: " + accountToLock.getAccountName() + " has been exceeded."); rae.setResourceType("ip"); @@ -1851,7 +1856,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountMgr.checkAccess(caller, domain); if (accountName != null) { - Account owner = _accountMgr.getActiveAccount(accountName, domainId); + Account owner = _accountMgr.getActiveAccountByName(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } @@ -1970,7 +1975,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Set allowedDomains = new HashSet(); if (_allowSubdomainNetworkAccess) { - allowedDomains = _accountMgr.getDomainParentIds(domainId); + allowedDomains = _domainMgr.getDomainParentIds(domainId); } else { allowedDomains.add(domainId); } @@ -1991,7 +1996,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag accountSC.addAnd("isShared", SearchCriteria.Op.EQ, false); if (path != null) { - Set allowedDomains = _accountMgr.getDomainChildrenIds(path); + Set allowedDomains = _domainMgr.getDomainChildrenIds(path); accountSC.addAnd("domainId", SearchCriteria.Op.IN, allowedDomains.toArray()); } @@ -2365,7 +2370,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Long networkId = cmd.getNetworkId(); User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - Account callerAccount = _accountMgr.getActiveAccount(caller.getAccountId()); + Account callerAccount = _accountMgr.getActiveAccountById(caller.getAccountId()); // Check if network exists NetworkVO network = _networksDao.findById(networkId); @@ -2677,7 +2682,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @DB public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - Account owner = _accountMgr.getActiveAccount(accountId); + Account owner = _accountMgr.getActiveAccountById(accountId); boolean createNetwork = false; Transaction txn = Transaction.currentTxn(); @@ -2952,7 +2957,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // don't decrement resource count for direct ips if (ip.getAssociatedWithNetworkId() != null) { - _accountMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAccountId(), ResourceType.public_ip); + _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAccountId(), ResourceType.public_ip); } long isSourceNat = (ip.isSourceNat()) ? 1 : 0; @@ -3001,7 +3006,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (_allowSubdomainNetworkAccess) { - Set parentDomains = _accountMgr.getDomainParentIds(domainId); + Set parentDomains = _domainMgr.getDomainParentIds(domainId); if (parentDomains.contains(domainId)) { return true; @@ -3269,4 +3274,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } + + @Override + public Long getPodIdForVlan(long vlanDbId) { + PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId); + if (podVlanMaps == null) { + return null; + } else { + return podVlanMaps.getPodId(); + } + } } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index a987417fdd5..16897e8f172 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -59,6 +59,7 @@ import com.cloud.network.rules.FirewallRule.State; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; @@ -96,6 +97,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma UsageEventDao _usageEventDao; @Inject ConfigurationDao _configDao; + @Inject + DomainManager _domainMgr; private boolean _elbEnabled=false; @@ -192,7 +195,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -224,7 +227,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } diff --git a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java index 72799591c3b..fa39f7a3a0b 100644 --- a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java @@ -135,8 +135,8 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru { // we need to get a new ip address if we try to deploy a vm in a different pod IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp); if (ipVO != null) { - List mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId()); - if (mapVO.get(0).getPodId() != dest.getPod().getId()) { + PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId()); + if (mapVO.getPodId() != dest.getPod().getId()) { //release the old ip here _networkMgr.markIpAsUnavailable(ipVO.getId()); _ipAddressDao.unassignIpAddress(ipVO.getId()); diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index e98d2908d90..6f60a310959 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -203,11 +203,11 @@ public class ElasticLoadBalancerManagerImpl implements int _elasticLbvmNumCpu; private Long getPodIdForDirectIp(IPAddressVO ipAddr) { - List podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(ipAddr.getVlanId()); - if (podVlanMaps.isEmpty()) { + PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(ipAddr.getVlanId()); + if (podVlanMaps == null) { return null; } else { - return podVlanMaps.get(0).getPodId(); + return podVlanMaps.getPodId(); } } @@ -220,7 +220,7 @@ public class ElasticLoadBalancerManagerImpl implements Map params = new HashMap( 1); params.put(VirtualMachineProfile.Param.RestartNetwork, true); - Account owner = _accountService.getActiveAccount("system", new Long(1)); + Account owner = _accountService.getActiveAccountByName("system", new Long(1)); DeployDestination dest = new DeployDestination(dc, pod, null, null); s_logger.debug("About to deploy ELB vm "); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index abf9c174242..a68d40c9fcd 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -69,6 +69,7 @@ import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.RulesManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.DomainService; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.uservm.UserVm; @@ -131,6 +132,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, NetworkDao _networkDao; @Inject FirewallRulesDao _firewallDao; + @Inject + DomainService _domainMgr; @Override @DB @@ -699,7 +702,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, Long domainId = accountDomainPair.second(); if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -764,7 +767,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 7f0ea4e4175..dc50c9fd812 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -52,6 +52,7 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; @@ -98,8 +99,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { DomainDao _domainDao; @Inject FirewallManager _firewallMgr; - - + @Inject + DomainManager _domainMgr; @Override public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) { @@ -543,7 +544,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -575,7 +576,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } @@ -773,7 +774,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -811,7 +812,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index 2887774a976..507813158e0 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -74,7 +74,7 @@ import com.cloud.network.security.dao.VmRulesetLogDao; import com.cloud.server.ManagementServer; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; +import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.uservm.UserVm; @@ -144,6 +144,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG NetworkManager _networkMgr; @Inject AccountManager _accountMgr; + @Inject + DomainManager _domainMgr; ScheduledExecutorService _executorPool; ScheduledExecutorService _cleanupExecutor; @@ -1031,13 +1033,13 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG if (_accountMgr.isAdmin(caller.getType())) { if (domainId != null) { - Domain domain = _accountMgr.getDomain(domainId); + Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new InvalidParameterValueException("Unable to find domain by id " + domainId); } _accountMgr.checkAccess(caller, domain); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); if (account == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 98a3e9bef49..3ecdb1a224c 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -58,6 +58,7 @@ import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.RulesManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; @@ -86,6 +87,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag @Inject IPAddressDao _ipAddressDao; @Inject VirtualNetworkApplianceManager _routerMgr; @Inject AccountManager _accountMgr; + @Inject DomainManager _domainMgr; @Inject NetworkManager _networkMgr; @Inject RulesManager _rulesMgr; @Inject DomainDao _domainDao; @@ -458,7 +460,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -496,7 +498,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } @@ -519,7 +521,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag Long domainId = accountDomainPair.second(); if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - Domain domain = _accountMgr.getDomain(caller.getDomainId()); + Domain domain = _domainMgr.getDomain(caller.getDomainId()); path = domain.getPath(); } @@ -564,7 +566,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag if (domainId != null) { sc.setParameters("domainId", domainId); if (accountName != null) { - Account account = _accountMgr.getActiveAccount(accountName, domainId); + Account account = _accountMgr.getActiveAccountByName(accountName, domainId); sc.setParameters("accountId", account.getId()); } } diff --git a/server/src/com/cloud/projects/ProjectAccountVO.java b/server/src/com/cloud/projects/ProjectAccountVO.java new file mode 100644 index 00000000000..4c06391f697 --- /dev/null +++ b/server/src/com/cloud/projects/ProjectAccountVO.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.projects; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="project_account") +public class ProjectAccountVO implements ProjectAccount{ + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="project_id") + private long projectId; + + @Column(name="account_id") + private long accountId; + + @Column(name="account_role") + @Enumerated(value=EnumType.STRING) + private Role accountRole = Role.Regular; + + + protected ProjectAccountVO(){ + } + + public ProjectAccountVO(Project project, long accountId, Role accountRole) { + this.accountId = accountId; + this.accountRole = accountRole; + this.projectId = project.getId(); + } + + @Override + public long getId() { + return id; + } + + @Override + public long getProjectId() { + return projectId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public Role getAccountRole() { + return accountRole; + } + + + +} diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 15ea79fd7da..359abe8b706 100644 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -10,28 +10,34 @@ import org.apache.log4j.Logger; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.projects.Project.State; +import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; +import com.cloud.user.ResourceLimitService; import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; @Local(value = { ProjectService.class }) public class ProjectManagerImpl implements ProjectManager, Manager{ @@ -39,8 +45,6 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ private String _name; private long _maxProjects; - @Inject - private AccountDao _accountDao; @Inject private DomainDao _domainDao; @Inject @@ -48,7 +52,13 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ @Inject AccountManager _accountMgr; @Inject + DomainManager _domainMgr; + @Inject ConfigurationManager _configMgr; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + private ProjectAccountDao _projectAccountDao; @Override @@ -81,7 +91,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project") - public Project createProject(String name, String displayText, long zoneId, String accountName, Long domainId) { + @DB + public Project createProject(String name, String displayText, String accountName, Long domainId) { Account caller = UserContext.current().getCaller(); Account owner = caller; @@ -94,20 +105,42 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ owner = _accountMgr.finalizeOwner(caller, accountName, domainId); } - DataCenter zone = _configMgr.getZone(zoneId); - - if (zone == null) { - throw new InvalidParameterValueException("Unable to find zone by id " + zoneId); + //don't allow 2 projects with the same name inside the same domain + if (_projectDao.findByNameAndDomain(name, owner.getDomainId()) != null) { + throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId()); } - //TODO - do resource limit check here + Domain ownerDomain = _domainDao.findById(owner.getDomainId()); - Project project = _projectDao.persist(new ProjectVO(name, displayText, zoneId, owner.getAccountId(), owner.getDomainId())); + //do resource limit check + _resourceLimitMgr.resourceLimitExceededForDomain(ownerDomain, ResourceType.project); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + //Create a domain associated with the project + StringBuilder dmnNm = new StringBuilder("PrjDmn-"); + dmnNm.append(name).append("-").append(owner.getDomainId()); + + Domain projectDomain = _domainMgr.createDomain(dmnNm.toString(), Domain.ROOT_DOMAIN, Account.ACCOUNT_ID_SYSTEM, null, Domain.Type.Project); + + //Create an account associated with the project + StringBuilder acctNm = new StringBuilder("PrjAcct-"); + acctNm.append(name).append("-").append(owner.getDomainId()); + + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, projectDomain.getId(), null); + + Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId(), projectDomain.getId())); + + //TODO - assign owner to the project + assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Owner); if (project != null) { UserContext.current().setEventDetails("Project id=" + project.getId()); } + txn.commit(); + return project; } @@ -116,27 +149,74 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ public boolean deleteProject (long projectId) { Account caller = UserContext.current().getCaller(); - Project project= getProject(projectId); + ProjectVO project= getProject(projectId); //verify input parameters if (project == null) { throw new InvalidParameterValueException("Unable to find project by id " + projectId); } - _accountMgr.checkAccess(caller, null, project); + _accountMgr.checkAccess(caller, _domainDao.findById(project.getDomainId())); - //TODO - delete all project resources here + //mark project as inactive first, so you can't add resources to it + s_logger.debug("Marking project id=" + projectId + " with state " + State.Inactive + " as a part of project delete..."); + project.setState(State.Inactive); + if (_projectDao.update(projectId, project)) { + if (!cleanupProject(project)) { + s_logger.warn("Failed to cleanup project's id=" + projectId + " resources, not removing the project yet"); + return false; + } else { + return _projectDao.remove(projectId); + } + } else { + s_logger.warn("Failed to mark the project id=" + projectId + " with state " + State.Inactive); + return false; + } + } + + private boolean cleanupProject(Project project) { + boolean result=true; - return _projectDao.remove(projectId); - + //Unassign all users from the project + s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup..."); + List projectAccounts = _projectAccountDao.listByProjectId(project.getId()); + for (ProjectAccount projectAccount : projectAccounts) { + result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId()); + } + + if (result) { + s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup..."); + } + + //Delete project's domain + s_logger.debug("Deleting projects " + project + " internal domain id=" + project.getProjectDomainId() + " as a part of project cleanup..."); + result = result && _domainMgr.deleteDomain(project.getProjectDomainId(), true); + + return result; } @Override - public Project getProject (long projectId) { + public boolean unassignAccountFromProject(long projectId, long accountId) { + ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); + if (projectAccount == null) { + s_logger.debug("Account id=" + accountId + " is not assigned to project id=" + projectId + " so no need to unassign"); + return true; + } + + if ( _projectAccountDao.remove(projectAccount.getId())) { + return true; + } else { + s_logger.warn("Failed to unassign account id=" + accountId + " from the project id=" + projectId); + return false; + } + } + + @Override + public ProjectVO getProject (long projectId) { return _projectDao.findById(projectId); } @Override - public List listProjects(Long id, String name, String displayText, Long zoneId, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize) { + public List listProjects(Long id, String name, String displayText, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize) { Account caller = UserContext.current().getCaller(); Long accountId = null; String path = null; @@ -154,7 +234,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ _accountMgr.checkAccess(caller, domain); if (accountName != null) { - Account owner = _accountMgr.getActiveAccount(accountName, domainId); + Account owner = _accountMgr.getActiveAccountByName(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } @@ -198,10 +278,6 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ sc.addAnd("displayText", Op.EQ, displayText); } - if (zoneId != null) { - sc.addAnd("dataCenterId", Op.EQ, zoneId); - } - if (accountId != null) { sc.addAnd("accountId", Op.EQ, accountId); } @@ -218,7 +294,17 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } return _projectDao.search(sc, searchFilter); - + } + + @Override + public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole) { + return _projectAccountDao.persist(new ProjectAccountVO(project, accountId, accountRole)); + } + + @Override + public Account getProjectOwner(long projectId) { + long accountId = _projectAccountDao.getProjectOwner(projectId).getAccountId(); + return _accountMgr.getAccount(accountId); } } diff --git a/server/src/com/cloud/projects/ProjectVO.java b/server/src/com/cloud/projects/ProjectVO.java index 68cad0b2e09..29f27120454 100644 --- a/server/src/com/cloud/projects/ProjectVO.java +++ b/server/src/com/cloud/projects/ProjectVO.java @@ -1,9 +1,28 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ package com.cloud.projects; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -28,11 +47,11 @@ public class ProjectVO implements Project{ @Column(name="domain_id") long domainId; - @Column(name="account_id") - long accountId; + @Column(name="project_account_id") + long projectAccountId; - @Column(name="data_center_id") - long dataCenterId; + @Column(name="project_domain_id") + long projectDomainId; @Column(name=GenericDao.CREATED_COLUMN) private Date created; @@ -40,18 +59,20 @@ public class ProjectVO implements Project{ @Column(name=GenericDao.REMOVED_COLUMN) private Date removed; - @Column(name="cleanup_needed") - private boolean needsCleanup = false; + @Column(name="state") + @Enumerated(value=EnumType.STRING) + private State state; protected ProjectVO(){ } - public ProjectVO(String name, String displayText, long dataCenterId, long accountId, long domainId) { + public ProjectVO(String name, String displayText, long domainId, long projectAccountId, long projectDomainId) { this.name = name; this.displayText = displayText; - this.accountId = accountId; + this.projectAccountId = projectAccountId; this.domainId = domainId; - this.dataCenterId = dataCenterId; + this.projectDomainId = projectDomainId; + this.state = State.Inactive; } @Override @@ -59,10 +80,6 @@ public class ProjectVO implements Project{ return name; } - public void setName(String name) { - this.name = name; - } - @Override public String getDisplayText() { return displayText; @@ -77,18 +94,6 @@ public class ProjectVO implements Project{ return domainId; } - public void setDomainId(long domainId) { - this.domainId = domainId; - } - - @Override - public long getAccountId() { - return accountId; - } - - public void setAccountId(long accountId) { - this.accountId = accountId; - } @Override public long getId() { @@ -104,19 +109,6 @@ public class ProjectVO implements Project{ public Date getRemoved() { return removed; } - - @Override - public long getDataCenterId() { - return dataCenterId; - } - - public void setNeedsCleanup(boolean value) { - needsCleanup = value; - } - - public boolean getNeedsCleanup() { - return needsCleanup; - } @Override public String toString() { @@ -137,4 +129,29 @@ public class ProjectVO implements Project{ return true; } + + @Override + public long getProjectAccountId() { + return projectAccountId; + } + + @Override + public long getProjectDomainId() { + return projectDomainId; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public State getState() { + return state; + } + + @Override + public void setState(State state) { + this.state = state; + } + } diff --git a/server/src/com/cloud/projects/dao/ProjectAccountDao.java b/server/src/com/cloud/projects/dao/ProjectAccountDao.java new file mode 100644 index 00000000000..0686511c4f5 --- /dev/null +++ b/server/src/com/cloud/projects/dao/ProjectAccountDao.java @@ -0,0 +1,13 @@ +package com.cloud.projects.dao; + +import java.util.List; + +import com.cloud.projects.ProjectAccountVO; +import com.cloud.utils.db.GenericDao; + +public interface ProjectAccountDao extends GenericDao{ + ProjectAccountVO getProjectOwner(long projectId); + List listByProjectId(long projectId); + ProjectAccountVO findByProjectIdAccountId(long projectId, long accountId); + +} diff --git a/server/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java new file mode 100644 index 00000000000..3188cb7e952 --- /dev/null +++ b/server/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java @@ -0,0 +1,56 @@ +package com.cloud.projects.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.projects.ProjectAccount; +import com.cloud.projects.ProjectAccountVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={ProjectAccountDao.class}) +public class ProjectAccountDaoImpl extends GenericDaoBase implements ProjectAccountDao { + private static final Logger s_logger = Logger.getLogger(ProjectAccountDaoImpl.class); + + protected final SearchBuilder AllFieldsSearch; + + + protected ProjectAccountDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("role", AllFieldsSearch.entity().getAccountRole(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("projectId", AllFieldsSearch.entity().getProjectId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public ProjectAccountVO getProjectOwner(long projectId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("role", ProjectAccount.Role.Owner); + sc.setParameters("projectId", projectId); + + return findOneBy(sc); + } + + @Override + public List listByProjectId(long projectId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("projectId", projectId); + + return listBy(sc); + } + + @Override + public ProjectAccountVO findByProjectIdAccountId(long projectId, long accountId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("projectId", projectId); + sc.setParameters("accountId", accountId); + + return findOneBy(sc); + } + +} diff --git a/server/src/com/cloud/projects/dao/ProjectDao.java b/server/src/com/cloud/projects/dao/ProjectDao.java index 666e151cf72..beab8f5053e 100644 --- a/server/src/com/cloud/projects/dao/ProjectDao.java +++ b/server/src/com/cloud/projects/dao/ProjectDao.java @@ -5,4 +5,5 @@ import com.cloud.utils.db.GenericDao; public interface ProjectDao extends GenericDao{ + ProjectVO findByNameAndDomain(String name, long domainId); } diff --git a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java index b9efa1c55a2..87440f2169c 100644 --- a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -2,10 +2,53 @@ package com.cloud.projects.dao; import javax.ejb.Local; +import org.apache.log4j.Logger; + import com.cloud.projects.ProjectVO; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; @Local(value={ProjectDao.class}) public class ProjectDaoImpl extends GenericDaoBase implements ProjectDao { - + private static final Logger s_logger = Logger.getLogger(ProjectDaoImpl.class); + protected final SearchBuilder NameDomainSearch; + + protected ProjectDaoImpl() { + NameDomainSearch = createSearchBuilder(); + NameDomainSearch.and("name", NameDomainSearch.entity().getName(), SearchCriteria.Op.EQ); + NameDomainSearch.and("domainId", NameDomainSearch.entity().getDomainId(), SearchCriteria.Op.EQ); + NameDomainSearch.done(); + } + + @Override + public ProjectVO findByNameAndDomain(String name, long domainId) { + SearchCriteria sc = NameDomainSearch.create(); + sc.setParameters("name", name); + sc.setParameters("domainId", domainId); + + return findOneBy(sc); + } + + @Override @DB + public boolean remove(Long projectId) { + boolean result = false; + Transaction txn = Transaction.currentTxn(); + txn.start(); + ProjectVO projectToRemove = findById(projectId); + projectToRemove.setName(null); + if (!update(projectId, projectToRemove)) { + s_logger.warn("Failed to reset name for the project id=" + projectId + " as a part of project remove"); + return false; + } else { + + } + result = super.remove(projectId); + txn.commit(); + + return result; + + } } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java new file mode 100644 index 00000000000..b2a9ae43498 --- /dev/null +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -0,0 +1,683 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.resourcelimit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.alert.AlertManager; +import com.cloud.api.commands.UpdateResourceCountCmd; +import com.cloud.configuration.Config; +import com.cloud.configuration.Resource; +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.ResourceLimitVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.configuration.dao.ResourceCountDao; +import com.cloud.configuration.dao.ResourceLimitDao; +import com.cloud.dao.EntityManager; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.UserContext; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.VMInstanceDao; + +import edu.emory.mathcs.backport.java.util.Arrays; + +@Local(value = { ResourceLimitService.class}) +public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{ + public static final Logger s_logger = Logger.getLogger(ResourceLimitManagerImpl.class); + + private String _name; + @Inject + private DomainDao _domainDao; + @Inject + private AccountManager _accountMgr; + @Inject + private AlertManager _alertMgr; + @Inject + private ResourceCountDao _resourceCountDao; + @Inject + private ResourceLimitDao _resourceLimitDao; + @Inject + private UserVmDao _userVmDao; + @Inject + private AccountDao _accountDao; + @Inject + protected SnapshotDao _snapshotDao; + @Inject + protected VMTemplateDao _vmTemplateDao; + @Inject + private VolumeDao _volumeDao; + @Inject + private IPAddressDao _ipAddressDao; + @Inject + private VMInstanceDao _vmDao; + @Inject + ConfigurationDao _configDao; + @Inject + EntityManager _entityMgr; + + protected SearchBuilder ResourceCountSearch; + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _name = name; + + ResourceCountSearch = _resourceCountDao.createSearchBuilder(); + ResourceCountSearch.and("id", ResourceCountSearch.entity().getId(), SearchCriteria.Op.IN); + ResourceCountSearch.and("accountId", ResourceCountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ); + ResourceCountSearch.done(); + + return true; + } + + @Override + public void incrementResourceCount(long accountId, ResourceType type, Long... delta) { + //don't upgrade resource count for system account + if (accountId == Account.ACCOUNT_ID_SYSTEM) { + s_logger.trace("Not incrementing resource count for system accounts, returning"); + return; + } + long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue(); + + if (!updateResourceCountForAccount(accountId, type, true, numToIncrement)) { + //we should fail the operation (resource creation) when failed to update the resource count + throw new CloudRuntimeException("Failed to increment resource count of type " + type + " for account id=" + accountId); + } + } + + @Override + public void decrementResourceCount(long accountId, ResourceType type, Long... delta) { + //don't upgrade resource count for system account + if (accountId == Account.ACCOUNT_ID_SYSTEM) { + s_logger.trace("Not decrementing resource count for system accounts, returning"); + return; + } + long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue(); + + if (!updateResourceCountForAccount(accountId, type, false, numToDecrement)) { + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId, + "Failed to decrement resource count of type " + type + " for account id=" + accountId + "; use updateResourceCount API to recalculate/fix the problem"); + } + } + + @Override + public long findCorrectResourceLimitForAccount(long accountId, ResourceType type) { + long max = -1; + + ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(accountId, ResourceOwnerType.Account, type); + + // Check if limit is configured for account + if (limit != null) { + max = limit.getMax().longValue(); + } else { + // If the account has an no limit set, then return global default account limits + try { + if (type == Resource.ResourceType.public_ip) { + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())); + } else if (type == ResourceType.snapshot) { + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())); + } else if (type == ResourceType.template) { + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key())); + } else if (type == ResourceType.user_vm) { + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())); + } else if (type == ResourceType.volume) { + max = Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())); + } else { + throw new InvalidParameterValueException("Unsupported resource type " + type); + } + } catch (NumberFormatException nfe) { + s_logger.error("Invalid value is set for the default account limit."); + } + } + + return max; + } + + @Override + public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type) { + long max = -1; + + // Check account + ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(domain.getId(), ResourceOwnerType.Domain, type); + + if (limit != null) { + max = limit.getMax().longValue(); + } else { + // check domain hierarchy + Long domainId = domain.getParent(); + while ((domainId != null) && (limit == null)) { + limit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); + DomainVO tmpDomain = _domainDao.findById(domainId); + domainId = tmpDomain.getParent(); + } + + if (limit != null) { + max = limit.getMax().longValue(); + } + } + + return max; + } + + @Override @DB + public boolean resourceLimitExceeded(Account account, ResourceType type, long... count) { + long numResources = ((count.length == 0) ? 1 : count[0]); + + // Don't place any limits on system or admin accounts + if (_accountMgr.isAdmin(account.getType())) { + return false; + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + try { + //Lock all rows first so nobody else can read it + Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type); + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowIdsToLock.toArray()); + _resourceCountDao.lockRows(sc, null, true); + + // Check account limits + long accountLimit = findCorrectResourceLimitForAccount(account.getId(), type); + long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources; + if (accountLimit != -1 && potentialCount > accountLimit) { + return true; + } + + // check all domains in the account's domain hierarchy + Long domainId = account.getDomainId(); + while (domainId != null) { + ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); + if (domainLimit != null) { + long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type); + if ((domainCount + numResources) > domainLimit.getMax().longValue()) { + return true; + } + } + DomainVO domain = _domainDao.findById(domainId); + domainId = domain.getParent(); + } + + return false; + } finally { + txn.commit(); + } + } + + @DB @Override + public boolean resourceLimitExceededForDomain(Domain domain, ResourceType type, long... count) { + long numResources = ((count.length == 0) ? 1 : count[0]); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + try { + //Lock all rows first so nobody else can read it + Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domain.getId(), ResourceOwnerType.Domain, type); + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowIdsToLock.toArray()); + _resourceCountDao.lockRows(sc, null, true); + + Long domainId = domain.getId(); + // check all domains in the domain hierarchy + while (domainId != null) { + ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); + if (domainLimit != null) { + long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type); + if ((domainCount + numResources) > domainLimit.getMax().longValue()) { + return true; + } + } + domain = _domainDao.findById(domainId); + domainId = domain.getParent(); + } + + return false; + } finally { + txn.commit(); + } + } + + + @Override + public List searchForLimits(Long id, String accountName, Long domainId, Integer type, Long startIndex, Long pageSizeVal) { + Account caller = UserContext.current().getCaller(); + List limits = new ArrayList(); + boolean isAccount = true; + + Long accountId = null; + + if (!_accountMgr.isAdmin(caller.getType())) { + accountId = caller.getId(); + domainId = null; + } else { + if (domainId != null) { + //verify domain information and permissions + Domain domain = _domainDao.findById(domainId); + if (domain == null) { + //return empty set + return limits; + } + + _accountMgr.checkAccess(caller, domain); + + if (accountName != null) { + //Verify account information and permissions + Account account = _accountDao.findAccount(accountName, domainId); + if (account == null) { + //return empty set + return limits; + } + + _accountMgr.checkAccess(caller, null, account); + + accountId = account.getId(); + domainId = null; + } + } + } + + // Map resource type + ResourceType resourceType = null; + if (type != null) { + try { + resourceType = ResourceType.values()[type]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new InvalidParameterValueException("Please specify a valid resource type."); + } + } + + //If id is passed in, get the record and return it if permission check has passed + if (id != null) { + ResourceLimitVO vo = _resourceLimitDao.findById(id); + if (vo.getAccountId() != null) { + _accountMgr.checkAccess(caller, null, _accountDao.findById(vo.getAccountId())); + limits.add(vo); + } else if (vo.getDomainId() != null) { + _accountMgr.checkAccess(caller, _domainDao.findById(vo.getDomainId())); + limits.add(vo); + } + + return limits; + } + + + //If account is not specified, default it to caller account + if (accountId == null) { + if (domainId == null) { + accountId = caller.getId(); + isAccount = true; + } else { + isAccount = false; + } + } else { + isAccount = true; + } + + SearchBuilder sb = _resourceLimitDao.createSearchBuilder(); + sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + Filter filter = new Filter(ResourceLimitVO.class, "id", true, startIndex, pageSizeVal); + + if (accountId != null) { + sc.setParameters("accountId", accountId); + } + + if (domainId != null) { + sc.setParameters("domainId", domainId); + sc.setParameters("accountId", null); + } + + if (resourceType != null) { + sc.setParameters("type", resourceType); + } + + List foundLimits = _resourceLimitDao.search(sc, filter); + + if (resourceType != null) { + if (foundLimits.isEmpty()) { + if (isAccount) { + limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForAccount(accountId, resourceType), accountId, ResourceOwnerType.Account)); + } else { + limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), resourceType), domainId, ResourceOwnerType.Domain)); + } + } else { + limits.addAll(foundLimits); + } + } else { + limits.addAll(foundLimits); + + //see if any limits are missing from the table, and if yes - get it from the config table and add + ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); + if (foundLimits.size() != resourceTypes.length) { + List accountLimitStr = new ArrayList(); + List domainLimitStr = new ArrayList(); + for (ResourceLimitVO foundLimit : foundLimits) { + if (foundLimit.getAccountId() != null) { + accountLimitStr.add(foundLimit.getType().toString()); + } else { + domainLimitStr.add(foundLimit.getType().toString()); + } + } + + //get default from config values + if (isAccount) { + if (accountLimitStr.size() < resourceTypes.length) { + for (ResourceType rt : resourceTypes) { + if (!accountLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Account)) { + limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForAccount(accountId, rt), accountId, ResourceOwnerType.Account)); + } + } + } + + } else { + if (domainLimitStr.size() < resourceTypes.length) { + for (ResourceType rt : resourceTypes) { + if (!domainLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Domain)) { + limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), rt), domainId, ResourceOwnerType.Domain)); + } + } + } + } + } + } + + return limits; + } + + @Override + public ResourceLimitVO updateResourceLimit(Long ownerId, ResourceOwnerType ownerType, Integer typeId, Long max) { + Account caller = UserContext.current().getCaller(); + + if (max == null) { + max = new Long(-1); + } else if (max < -1) { + throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'."); + } + + // Map resource type + ResourceType resourceType = null; + if (typeId != null) { + for (ResourceType type : Resource.ResourceType.values()) { + if (type.getOrdinal() == typeId.intValue()) { + resourceType = type; + } + } + if (resourceType == null) { + throw new InvalidParameterValueException("Please specify valid resource type"); + } + } + + if (ownerType == ResourceOwnerType.Domain) { + Domain domain = _entityMgr.findById(Domain.class, ownerId); + _accountMgr.checkAccess(caller, domain); + if ((caller.getDomainId() == ownerId.longValue()) && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + // if the admin is trying to update their own domain, disallow... + throw new PermissionDeniedException("Unable to update resource limit for domain " + ownerId + ", permission denied"); + } + Long parentDomainId = domain.getParent(); + if (parentDomainId != null) { + DomainVO parentDomain = _domainDao.findById(parentDomainId); + long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType); + if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) { + throw new InvalidParameterValueException("Domain " + domain.getName() + "(id: " + ownerId + ") has maximum allowed resource limit " + parentMaximum + " for " + resourceType + + ", please specify a value less that or equal to " + parentMaximum); + } + } + } else if (ownerType == ResourceOwnerType.Account) { + Account account = _entityMgr.findById(Account.class, ownerId); + if (account.getType() == Account.ACCOUNT_ID_SYSTEM) { + throw new InvalidParameterValueException("Can't update system account"); + } + + _accountMgr.checkAccess(caller, null, account); + } + + ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(ownerId, ownerType, resourceType); + if (limit != null) { + // Update the existing limit + _resourceLimitDao.update(limit.getId(), max); + return _resourceLimitDao.findById(limit.getId()); + } else { + return _resourceLimitDao.persist(new ResourceLimitVO(resourceType, max, ownerId, ownerType)); + } + } + + @Override + public List recalculateResourceCount(UpdateResourceCountCmd cmd) throws InvalidParameterValueException, CloudRuntimeException, PermissionDeniedException{ + Account callerAccount = UserContext.current().getCaller(); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Long accountId = null; + long count=0; + List counts = new ArrayList(); + List resourceTypes = new ArrayList(); + + ResourceType resourceType = null; + Integer typeId = cmd.getResourceType(); + + if (typeId != null) { + for (ResourceType type : resourceTypes) { + if (type.getOrdinal() == typeId.intValue()) { + resourceType = type; + } + } + if (resourceType == null) { + throw new InvalidParameterValueException("Please specify valid resource type"); + } + } + + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Please specify a valid domain ID."); + } + _accountMgr.checkAccess(callerAccount, domain); + + if (accountName != null) { + Account userAccount = _accountMgr.getActiveAccountByName(accountName, domainId); + if (userAccount == null) { + throw new InvalidParameterValueException("unable to find account by name " + accountName + " in domain with id " + domainId); + } + accountId = userAccount.getId(); + } + + + if (resourceType != null) { + resourceTypes.add(resourceType); + } else { + resourceTypes = Arrays.asList(Resource.ResourceType.values()); + } + + for (ResourceType type : resourceTypes) { + if (accountId != null) { + if (type.supportsOwner(ResourceOwnerType.Account)) { + count = recalculateAccountResourceCount(accountId, type); + counts.add(new ResourceCountVO(type, count, accountId, ResourceOwnerType.Account)); + } + + } else { + if (type.supportsOwner(ResourceOwnerType.Domain)) { + count = recalculateDomainResourceCount(domainId, type); + counts.add(new ResourceCountVO(type, count, domainId, ResourceOwnerType.Domain)); + } + } + } + + return counts; + } + + @DB + protected boolean updateResourceCountForAccount(long accountId, ResourceType type, boolean increment, long delta) { + boolean result = true; + try { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + Set rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type); + + //Lock rows first + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowsToLock.toArray()); + List rowsToUpdate = _resourceCountDao.lockRows(sc, null, true); + + for (ResourceCountVO rowToUpdate : rowsToUpdate) { + if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) { + s_logger.trace("Unable to update resource count for the row " + rowToUpdate); + result = false; + } + } + + txn.commit(); + } catch (Exception ex) { + s_logger.error("Failed to update resource count for account id=" + accountId); + result = false; + } + return result; + } + + @DB + protected long recalculateDomainResourceCount(long domainId, ResourceType type) { + long count=0; + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + try { + //Lock all rows first so nobody else can read it + Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type); + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowIdsToLock.toArray()); + _resourceCountDao.lockRows(sc, null, true); + + List domainChildren = _domainDao.findImmediateChildrenForParent(domainId); + // for each child domain update the resource count + if (type.supportsOwner(ResourceOwnerType.Domain)) { + for (DomainVO domainChild : domainChildren) { + long domainCount = recalculateDomainResourceCount(domainChild.getId(), type); + count = count + domainCount; // add the child domain count to parent domain count + } + } + + if (type.supportsOwner(ResourceOwnerType.Account)) { + List accounts = _accountDao.findActiveAccountsForDomain(domainId); + for (AccountVO account : accounts) { + long accountCount = recalculateAccountResourceCount(account.getId(), type); + count = count + accountCount; // add account's resource count to parent domain count + } + } + _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, count); + } catch (Exception e) { + throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId); + } finally { + txn.commit(); + } + + return count; + } + + @DB + protected long recalculateAccountResourceCount(long accountId, ResourceType type) { + Long count=null; + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table + // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("accountId", accountId); + _resourceCountDao.lockRows(sc, null, true); + + if (type == Resource.ResourceType.user_vm) { + count = _userVmDao.countAllocatedVMsForAccount(accountId); + } else if (type == Resource.ResourceType.volume) { + count = _volumeDao.countAllocatedVolumesForAccount(accountId); + long virtualRouterCount = _vmDao.countAllocatedVirtualRoutersForAccount(accountId); + count = count - virtualRouterCount; // don't count the volumes of virtual router + } else if (type == Resource.ResourceType.snapshot) { + count = _snapshotDao.countSnapshotsForAccount(accountId); + } else if (type == Resource.ResourceType.public_ip) { + count = _ipAddressDao.countAllocatedIPsForAccount(accountId); + } else if (type == Resource.ResourceType.template) { + count = _vmTemplateDao.countTemplatesForAccount(accountId); + } else { + throw new InvalidParameterValueException("Unsupported resource type " + type); + } + + _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (count == null) ? 0 : count.longValue()); + + txn.commit(); + + return (count == null) ? 0 : count.longValue(); + } + + @Override + public long getResourceCount(Account account, ResourceType type) { + return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type); + } + +} diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 529fbc2376a..ed98ba3893c 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -48,10 +48,10 @@ import org.apache.log4j.Logger; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationVO; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.ResourceCountVO; -import com.cloud.configuration.ResourceLimit.OwnerType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.dc.DataCenter.NetworkType; @@ -358,8 +358,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { //create resource counts try { - _resourceCountDao.createResourceCounts(1, OwnerType.Account); - _resourceCountDao.createResourceCounts(2, OwnerType.Account); + _resourceCountDao.createResourceCounts(1, ResourceOwnerType.Account); + _resourceCountDao.createResourceCounts(2, ResourceOwnerType.Account); } catch (Exception ex) { // if exception happens, it might mean that resource counts are already created by another management server being started in the cluster s_logger.warn("Failed to create initial resource counts for system/admin accounts"); @@ -981,33 +981,48 @@ public class ConfigurationServerImpl implements ConfigurationServer { domain.setPath("/"); domain.setLevel(0); _domainDao.persist(domain); - _resourceCountDao.createResourceCounts(1, OwnerType.Domain); + _resourceCountDao.createResourceCounts(1, ResourceOwnerType.Domain); txn.commit(); } private void updateResourceCount() { - ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); + ResourceType[] resourceTypes = Resource.ResourceType.values(); + List accounts = _accountDao.listAllIncludingRemoved(); List domains = _domainDao.listAllIncludingRemoved(); - List domainResourceCount = _resourceCountDao.listDomainCounts(); - List accountResourceCount = _resourceCountDao.listAccountCounts(); + List domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain); + List accountResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Account); - int resourceCount = resourceTypes.length; + List accountSupportedResourceTypes = new ArrayList(); + List domainSupportedResourceTypes = new ArrayList(); - if ((domainResourceCount.size() < resourceCount * domains.size())) { + for (ResourceType resourceType : resourceTypes) { + if (resourceType.supportsOwner(ResourceOwnerType.Account)) { + accountSupportedResourceTypes.add(resourceType); + } + if (resourceType.supportsOwner(ResourceOwnerType.Domain)) { + domainSupportedResourceTypes.add(resourceType); + } + } + + + int accountExpectedCount = accountSupportedResourceTypes.size(); + int domainExpectedCount = domainSupportedResourceTypes.size(); + + if ((domainResourceCount.size() < domainExpectedCount * domains.size())) { s_logger.debug("resource_count table has records missing for some domains...going to insert them"); for (DomainVO domain : domains) { - List domainCounts = _resourceCountDao.listByDomainId(domain.getId()); + List domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain); List domainCountStr = new ArrayList(); for (ResourceCountVO domainCount : domainCounts) { domainCountStr.add(domainCount.getType().toString()); } - if (domainCountStr.size() < resourceCount) { - for (ResourceType resourceType : resourceTypes) { + if (domainCountStr.size() < domainExpectedCount) { + for (ResourceType resourceType : domainSupportedResourceTypes) { if (!domainCountStr.contains(resourceType.toString())) { - ResourceCountVO resourceCountVO = new ResourceCountVO(null, domain.getId(), resourceType, 0); + ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain); s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId()); _resourceCountDao.persist(resourceCountVO); } @@ -1016,19 +1031,19 @@ public class ConfigurationServerImpl implements ConfigurationServer { } } - if ((accountResourceCount.size() < resourceTypes.length * accounts.size())) { + if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) { s_logger.debug("resource_count table has records missing for some accounts...going to insert them"); for (AccountVO account : accounts) { - List accountCounts = _resourceCountDao.listByAccountId(account.getId()); + List accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account); List accountCountStr = new ArrayList(); for (ResourceCountVO accountCount : accountCounts) { accountCountStr.add(accountCount.getType().toString()); } - if (accountCountStr.size() < resourceCount) { - for (ResourceType resourceType : resourceTypes) { + if (accountCountStr.size() < accountExpectedCount) { + for (ResourceType resourceType : accountSupportedResourceTypes) { if (!accountCountStr.contains(resourceType.toString())) { - ResourceCountVO resourceCountVO = new ResourceCountVO(account.getId(), null, resourceType, 0); + ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account); s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId()); _resourceCountDao.persist(resourceCountVO); } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 200ca69374d..e8b2026bf11 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -19,40 +19,13 @@ package com.cloud.server; import java.util.Date; import java.util.List; -import java.util.Map; -import com.cloud.async.AsyncJobResult; -import com.cloud.async.AsyncJobVO; -import com.cloud.configuration.ResourceLimitVO; -import com.cloud.dc.DataCenterIpAddressVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.VlanVO; -import com.cloud.domain.DomainVO; import com.cloud.event.EventVO; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.HostVO; import com.cloud.info.ConsoleProxyInfo; -import com.cloud.network.IPAddressVO; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeStats; -import com.cloud.storage.VolumeVO; -import com.cloud.user.Account; -import com.cloud.user.AccountVO; -import com.cloud.user.User; -import com.cloud.user.UserAccount; import com.cloud.utils.Pair; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; /** @@ -60,109 +33,21 @@ import com.cloud.vm.VirtualMachine; * need to build a wire protocol, it will be built on top of this java interface. */ public interface ManagementServer extends ManagementService { - + /** - * Gets a user by userId + * returns the instance id of this management server. * - * @param userId - * @return a user object + * @return id of the management server */ - User getUser(long userId); - + long getId(); + /** - * Gets a user and account by username and domain - * - * @param username - * @param domainId - * @return a user object - */ - UserAccount getUserAccount(String username, Long domainId); - - /** - * Authenticates a user when s/he logs in. - * - * @param username - * required username for authentication - * @param password - * password to use for authentication, can be null for single sign-on case - * @param domainId - * id of domain where user with username resides - * @param requestParameters - * the request parameters of the login request, which should contain timestamp of when the request signature is - * made, and the signature itself in the single sign-on case - * @return a user object, null if the user failed to authenticate - */ - UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters); - - String updateAdminPassword(long userId, String oldPassword, String newPassword); - - /** - * Locate a user by their apiKey - * - * @param apiKey - * that was created for a particular user - * @return the user/account pair if one exact match was found, null otherwise - */ - Pair findUserByApiKey(String apiKey); - - /** - * Get an account by the accountId - * - * @param accountId - * @return the account, or null if not found - */ - Account getAccount(long accountId); - - /** - * Gets Volume statistics. The array returned will contain VolumeStats in the same order as the array of volumes requested. - * - * @param volId - * @return array of VolumeStats - */ - VolumeStats[] getVolumeStatistics(long[] volId); - - /** - * If the specified VLAN is associated with the pod, returns the pod ID. Else, returns null. - * - * @param vlanDbId - * @return pod ID, or null - */ - Long getPodIdForVlan(long vlanDbId); - - /** - * Return a list of IP addresses - * - * @param accountId - * @param allocatedOnly - * - if true, will only list IPs that are allocated to the specified account - * @param zoneId - * - if specified, will list IPs in this zone - * @param vlanDbId - * - if specified, will list IPs in this VLAN - * @return list of IP addresses - */ - List listPublicIpAddressesBy(Long accountId, boolean allocatedOnly, Long zoneId, Long vlanDbId); - - /** - * Return a list of private IP addresses that have been allocated to the given pod and zone - * - * @param podId - * @param zoneId - * @return list of private IP addresses - */ - List listPrivateIpAddressesBy(Long podId, Long zoneId); - - /** - * Attaches an ISO to the virtual CDROM device of the specified VM. Will fail if the VM already has an ISO mounted. - * - * @param vmId - * @param userId - * @param isoId - * @param attach - * whether to attach or detach the iso from the instance - * @return - */ - boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach); + * Fetches the version of cloud stack + */ + @Override + String getVersion(); + + String[] getApiConfig(); /** * Retrieves a host by id @@ -193,380 +78,26 @@ public interface ManagementServer extends ManagementService { */ List getEvents(long userId, long accountId, Long domainId, String type, String level, Date startDate, Date endDate); - /** - * returns the instance id of this management server. - * - * @return id of the management server - */ - long getId(); - - /** - * Searches for Zones by the specified search criteria Can search by: zone name - * - * @param c - * @return List of Zones - */ - List searchForZones(Criteria c); - - /** - * Searches for servers that are either Down or in Alert state - * - * @param c - * @return List of Hosts - */ - List searchForAlertServers(Criteria c); - - /** - * Search for templates by the specified search criteria Can search by: "name", "ready", "isPublic" - * - * @param c - * @return List of VMTemplates - */ - List searchForTemplates(Criteria c); - - /** - * Obtains pods that match the data center ID - * - * @param dataCenterId - * @return List of Pods - */ - List listPods(long dataCenterId); - - /** - * Change a pod's private IP range - * - * @param op - * @param podId - * @param startIP - * @param endIP - * @return Message to display to user - */ - String changePrivateIPRange(boolean add, Long podId, String startIP, String endIP); - - /** - * Finds a user by their user ID. - * - * @param ownerId - * @return User - */ - User findUserById(Long userId); - - /** - * Gets user by id. - * - * @param userId - * @param active - * @return - */ - User getUser(long userId, boolean active); - - /** - * Obtains a list of virtual machines that are similar to the VM with the specified name. - * - * @param vmInstanceName - * @return List of VMInstances - */ - List findVMInstancesLike(String vmInstanceName); - - /** - * Finds a virtual machine instance with the specified Volume ID. - * - * @param volumeId - * @return VMInstance - */ - VMInstanceVO findVMInstanceById(long vmId); - - /** - * Finds a guest virtual machine instance with the specified ID. - * - * @param userVmId - * @return UserVmVO - */ - UserVmVO findUserVMInstanceById(long userVmId); - - /** - * Finds a service offering with the specified ID. - * - * @param offeringId - * @return ServiceOffering - */ - ServiceOfferingVO findServiceOfferingById(long offeringId); - - /** - * Obtains a list of all service offerings. - * - * @return List of ServiceOfferings - */ - List listAllServiceOfferings(); - - /** - * Obtains a list of all active hosts. - * - * @return List of Hosts. - */ - List listAllActiveHosts(); - - /** - * Finds a data center with the specified ID. - * - * @param dataCenterId - * @return DataCenter - */ - DataCenterVO findDataCenterById(long dataCenterId); - - /** - * Finds a template by the specified ID. - * - * @param templateId - * @return A VMTemplate - */ - VMTemplateVO findTemplateById(long templateId); - List listPendingEvents(int entryTime, int duration); - /** - * Obtains a list of routers by the specified host ID. - * - * @param hostId - * @return List of DomainRouters. - */ - List listRoutersByHostId(long hostId); - - /** - * Obtains a list of all active routers. - * - * @return List of DomainRouters - */ - List listAllActiveRouters(); - - /** - * Finds a pod by the specified ID. - * - * @param podId - * @return HostPod - */ - HostPodVO findHostPodById(long podId); - - /** - * Finds a secondary storage host in the specified zone - * - * @param zoneId - * @return Host - */ - HostVO findSecondaryStorageHosT(long zoneId); - - /** - * Obtains a list of billing records by the specified search criteria. Can search by: "userId", "startDate", "endDate" - * - * @param c - * @return List of Billings. List searchForUsage(Criteria c); - */ - - /** - * Obtains a list of all templates. - * - * @return list of VMTemplates - */ - List listAllTemplates(); - - /** - * Logs out a user - * - * @param userId - */ - void logoutUser(Long userId); - - ConsoleProxyInfo getConsoleProxy(long dataCenterId, long userVmId); - - ConsoleProxyVO startConsoleProxy(long instanceId); - - ConsoleProxyVO stopConsoleProxy(VMInstanceVO systemVm, boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; - - ConsoleProxyVO rebootConsoleProxy(long instanceId); + //FIXME - move all console proxy related commands to corresponding managers + ConsoleProxyInfo getConsoleProxyForUserVm(long dataCenterId, long userVmId); String getConsoleAccessUrlRoot(long vmId); - - ConsoleProxyVO findConsoleProxyById(long instanceId); - - VMInstanceVO findSystemVMById(long instanceId); - - VirtualMachine startSystemVm(long vmId); - - /** - * Returns a configuration value with the specified name - * - * @param name - * @return configuration value - */ - String getConfigurationValue(String name); + + GuestOSVO getGuestOs(Long guestOsId); /** * Returns the vnc port of the vm. * - * @param VirtualMachine - * vm + * @param VirtualMachine vm * @return the vnc port if found; -1 if unable to find. */ Pair getVncPort(VirtualMachine vm); - /** - * find the domain Id associated with the given account - * - * @param accountId - * the id of the account to use to look up the domain - */ - Long findDomainIdByAccountId(Long accountId); - - /** - * find the domain by its path - * - * @param domainPath - * the path to use to lookup a domain - * @return domainVO the domain with the matching path, or null if no domain with the given path exists - */ - DomainVO findDomainByPath(String domainPath); - - /** - * Finds accounts with account identifiers similar to the parameter - * - * @param accountName - * @return list of Accounts - */ - List findAccountsLike(String accountName); - - /** - * Finds accounts with account identifier - * - * @param accountName - * @return an account that is active (not deleted) - */ - Account findActiveAccountByName(String accountName); - - /** - * Finds accounts with account identifier - * - * @param accountName - * , domainId - * @return an account that is active (not deleted) - */ - - Account findActiveAccount(String accountName, Long domainId); - - /** - * Finds accounts with account identifier - * - * @param accountName - * @param domainId - * @return an account that may or may not have been deleted - */ - Account findAccountByName(String accountName, Long domainId); - - /** - * Finds an account by the ID. - * - * @param accountId - * @return Account - */ - Account findAccountById(Long accountId); - - /** - * Deletes a Limit - * - * @param limitId - * - the database ID of the Limit - * @return true if successful, false if not - */ - boolean deleteLimit(Long limitId); - - /** - * Finds limit by id - * - * @param limitId - * - the database ID of the Limit - * @return LimitVO object - */ - ResourceLimitVO findLimitById(long limitId); - - /** - * Lists ISOs that are available for the specified account ID. - * - * @param accountId - * @param accountType - * @return a list of ISOs (VMTemplateVO objects) - */ - List listIsos(Criteria c); - public long getMemoryOrCpuCapacityByHost(Long hostId, short capacityType); - /** - * List private templates for which the given account/domain has been granted permission to launch instances - * - * @param accountId - * @return - */ - List listPermittedTemplates(long accountId); - - /** - * - * @param jobId - * async-call job id - * @return async-call result object - */ - AsyncJobResult queryAsyncJobResult(long jobId); - - AsyncJobVO findAsyncJobById(long jobId); - - String[] getApiConfig(); - - StoragePoolVO findPoolById(Long id); - List searchForStoragePools(Criteria c); - /** - * Return whether a domain is a child domain of a given domain. - * - * @param parentId - * @param childId - * @return True if the domainIds are equal, or if the second domain is a child of the first domain. False otherwise. - */ - boolean isChildDomain(Long parentId, Long childId); - - SecurityGroupVO findNetworkGroupByName(Long accountId, String groupName); - - /** - * Find a network group by id - * - * @param networkGroupId - * id of group to lookup - * @return the network group if found, null otherwise - */ - SecurityGroupVO findNetworkGroupById(long networkGroupId); - - List searchForStoragePoolDetails(long poolId, String value); - - boolean checkLocalStorageConfigVal(); - - VolumeVO findVolumeByInstanceAndDeviceId(long instanceId, long deviceId); - - InstanceGroupVO getGroupForVm(long vmId); - - List searchForZoneWideVlans(long dcId, String vlanType, String vlanId); - - /* - * Fetches the version of cloud stack - */ - @Override - String getVersion(); - - GuestOSVO getGuestOs(Long guestOsId); - - VolumeVO getRootVolume(Long instanceId); - - long getPsMaintenanceCount(long podId); - - boolean isPoolUp(long instanceId); - - boolean checkIfMaintenable(long hostId); - String getHashKey(); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 9fb174deef2..a8ef10ce2cc 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -18,18 +18,13 @@ package com.cloud.server; import java.lang.reflect.Field; -import java.math.BigInteger; import java.net.Inet6Address; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLEncoder; import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; @@ -45,9 +40,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import javax.crypto.KeyGenerator; import javax.crypto.Mac; -import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; @@ -66,7 +59,6 @@ import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiConstants; import com.cloud.api.ApiDBUtils; import com.cloud.api.commands.CreateSSHKeyPairCmd; -import com.cloud.api.commands.DeleteDomainCmd; import com.cloud.api.commands.DeleteSSHKeyPairCmd; import com.cloud.api.commands.DestroySystemVmCmd; import com.cloud.api.commands.ExtractVolumeCmd; @@ -103,9 +95,7 @@ import com.cloud.api.commands.ListVlanIpRangesCmd; import com.cloud.api.commands.ListVolumesCmd; import com.cloud.api.commands.ListZonesByCmd; import com.cloud.api.commands.RebootSystemVmCmd; -import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.RegisterSSHKeyPairCmd; -import com.cloud.api.commands.StartSystemVMCmd; import com.cloud.api.commands.StopSystemVmCmd; import com.cloud.api.commands.UpdateDomainCmd; import com.cloud.api.commands.UpdateHostPasswordCmd; @@ -129,16 +119,12 @@ import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ConfigurationVO; -import com.cloud.configuration.ResourceLimitVO; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.consoleproxy.ConsoleProxyManagementState; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.PodVlanMapVO; @@ -147,7 +133,6 @@ import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.PodVlanMapDao; import com.cloud.dc.dao.VlanDao; @@ -172,7 +157,6 @@ import com.cloud.host.DetailVO; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; -import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -187,9 +171,6 @@ import com.cloud.network.NetworkVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.server.auth.UserAuthenticator; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -199,22 +180,18 @@ import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; -import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; @@ -229,10 +206,8 @@ import com.cloud.user.AccountVO; import com.cloud.user.SSHKeyPair; import com.cloud.user.SSHKeyPairVO; import com.cloud.user.User; -import com.cloud.user.UserAccount; import com.cloud.user.UserAccountVO; import com.cloud.user.UserContext; -import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserAccountDao; @@ -285,10 +260,7 @@ public class ManagementServerImpl implements ManagementServer { private final AccountManager _accountMgr; private final AgentManager _agentMgr; - private final ConfigurationManager _configMgr; - private final SecurityGroupDao _networkSecurityGroupDao; private final IPAddressDao _publicIpAddressDao; - private final DataCenterIpAddressDao _privateIpAddressDao; private final DomainRouterDao _routerDao; private final ConsoleProxyDao _consoleProxyDao; private final ClusterDao _clusterDao; @@ -312,21 +284,17 @@ public class ManagementServerImpl implements ManagementServer { private final LaunchPermissionDao _launchPermissionDao; private final DomainDao _domainDao; private final AccountDao _accountDao; - private final ResourceLimitDao _resourceLimitDao; private final UserAccountDao _userAccountDao; private final AlertDao _alertDao; private final CapacityDao _capacityDao; private final GuestOSDao _guestOSDao; private final GuestOSCategoryDao _guestOSCategoryDao; private final StoragePoolDao _poolDao; - private final StoragePoolHostDao _poolHostDao; private final NicDao _nicDao; private final NetworkDao _networkDao; private final StorageManager _storageMgr; private final VirtualMachineManager _itMgr; private final TemplateManager _templateMgr; - - private final Adapters _userAuthenticators; private final HostPodDao _hostPodDao; private final VMInstanceDao _vmInstanceDao; private final VolumeDao _volumeDao; @@ -345,9 +313,9 @@ public class ManagementServerImpl implements ManagementServer { private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); - private final StatsCollector _statsCollector; - private final Map _configs; + + private final StatsCollector _statsCollector; private final Map _availableIdsMap; @@ -373,14 +341,11 @@ public class ManagementServerImpl implements ManagementServer { _accountMgr = locator.getManager(AccountManager.class); _agentMgr = locator.getManager(AgentManager.class); - _configMgr = locator.getManager(ConfigurationManager.class); _vmMgr = locator.getManager(UserVmManager.class); _consoleProxyMgr = locator.getManager(ConsoleProxyManager.class); _secStorageVmMgr = locator.getManager(SecondaryStorageVmManager.class); _storageMgr = locator.getManager(StorageManager.class); - _networkSecurityGroupDao = locator.getDao(SecurityGroupDao.class); _publicIpAddressDao = locator.getDao(IPAddressDao.class); - _privateIpAddressDao = locator.getDao(DataCenterIpAddressDao.class); _consoleProxyDao = locator.getDao(ConsoleProxyDao.class); _secStorageVmDao = locator.getDao(SecondaryStorageVmDao.class); _userDao = locator.getDao(UserDao.class); @@ -391,14 +356,12 @@ public class ManagementServerImpl implements ManagementServer { _launchPermissionDao = locator.getDao(LaunchPermissionDao.class); _domainDao = locator.getDao(DomainDao.class); _accountDao = locator.getDao(AccountDao.class); - _resourceLimitDao = locator.getDao(ResourceLimitDao.class); _userAccountDao = locator.getDao(UserAccountDao.class); _alertDao = locator.getDao(AlertDao.class); _capacityDao = locator.getDao(CapacityDao.class); _guestOSDao = locator.getDao(GuestOSDao.class); _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); _poolDao = locator.getDao(StoragePoolDao.class); - _poolHostDao = locator.getDao(StoragePoolHostDao.class); _vmGroupDao = locator.getDao(InstanceGroupDao.class); _uploadDao = locator.getDao(UploadDao.class); _configs = _configDao.getConfiguration(); @@ -409,11 +372,9 @@ public class ManagementServerImpl implements ManagementServer { _sshKeyPairDao = locator.getDao(SSHKeyPairDao.class); _itMgr = locator.getManager(VirtualMachineManager.class); _ksMgr = locator.getManager(KeystoreManager.class); - _userAuthenticators = locator.getAdapters(UserAuthenticator.class); + _hypervisorCapabilitiesDao = locator.getDao(HypervisorCapabilitiesDao.class); - if (_userAuthenticators == null || !_userAuthenticators.isSet()) { - s_logger.error("Unable to find an user authenticator."); - } + _hostAllocators = locator.getAdapters(HostAllocator.class); if (_hostAllocators == null || !_hostAllocators.isSet()) { @@ -424,7 +385,7 @@ public class ManagementServerImpl implements ManagementServer { String value = _configs.get("account.cleanup.interval"); int cleanup = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day. - + _statsCollector = StatsCollector.getInstance(_configs); _purgeDelay = NumbersUtil.parseInt(_configs.get("event.purge.delay"), 0); @@ -443,289 +404,11 @@ public class ManagementServerImpl implements ManagementServer { return _configs; } - @Override - public VolumeStats[] getVolumeStatistics(long[] volIds) { - return _statsCollector.getVolumeStats(volIds); - } - - @Override - public String updateAdminPassword(long userId, String oldPassword, String newPassword) { - // String old = StringToMD5(oldPassword); - // User user = getUser(userId); - // if (old.equals(user.getPassword())) { - UserVO userVO = _userDao.createForUpdate(userId); - userVO.setPassword(StringToMD5(newPassword)); - _userDao.update(userId, userVO); - return newPassword; - // } else { - // return null; - // } - } - - private String StringToMD5(String string) { - MessageDigest md5; - - try { - md5 = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new CloudRuntimeException("Error", e); - } - - md5.reset(); - BigInteger pwInt = new BigInteger(1, md5.digest(string.getBytes())); - - // make sure our MD5 hash value is 32 digits long... - StringBuffer sb = new StringBuffer(); - String pwStr = pwInt.toString(16); - int padding = 32 - pwStr.length(); - for (int i = 0; i < padding; i++) { - sb.append('0'); - } - sb.append(pwStr); - return sb.toString(); - } - - @Override - public User getUser(long userId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Retrieiving user with id: " + userId); - } - - UserVO user = _userDao.getUser(userId); - if (user == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find user with id " + userId); - } - return null; - } - - return user; - } - - @Override - public User getUser(long userId, boolean active) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Retrieiving user with id: " + userId + " and active = " + active); - } - - if (active) { - return _userDao.getUser(userId); - } else { - return _userDao.findById(userId); - } - } - - @Override - public UserAccount getUserAccount(String username, Long domainId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Retrieiving user: " + username + " in domain " + domainId); - } - - UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); - if (userAccount == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find user with name " + username + " in domain " + domainId); - } - return null; - } - - if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { - if (s_logger.isInfoEnabled()) { - s_logger.info("User " + username + " in domain id=" + domainId + " is disabled/locked (or account is disabled/locked)"); - } - throw new CloudAuthenticationException("User " + username + " in domain id=" + domainId + " is disabled/locked (or account is disabled/locked)"); - } - - return userAccount; - } - - private UserAccount getUserAccount(String username, String password, Long domainId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Attempting to log in user: " + username + " in domain " + domainId); - } - - // We only use the first adapter even if multiple have been configured - Enumeration en = _userAuthenticators.enumeration(); - UserAuthenticator authenticator = en.nextElement(); - boolean authenticated = authenticator.authenticate(username, password, domainId); - - if (authenticated) { - UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); - if (userAccount == null) { - s_logger.warn("Unable to find an authenticated user with username " + username + " in domain " + domainId); - return null; - } - - DomainVO domain = _domainDao.findById(domainId); - String domainName = null; - if (domain != null) { - domainName = domain.getName(); - } - - if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { - if (s_logger.isInfoEnabled()) { - s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)"); - } - throw new CloudAuthenticationException("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)"); - // return null; - } - return userAccount; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to authenticate user with username " + username + " in domain " + domainId); - } - return null; - } - } - - @Override - public Pair findUserByApiKey(String apiKey) { - return _accountDao.findUserAccountByApiKey(apiKey); - } - - @Override - public Account getAccount(long accountId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Retrieiving account with id: " + accountId); - } - - AccountVO account = _accountDao.findById(Long.valueOf(accountId)); - if (account == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find account with id " + accountId); - } - return null; - } - - return account; - } - - @Override - public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { - Long userId = cmd.getId(); - User user = _userDao.findById(userId); - - if (user == null) { - throw new InvalidParameterValueException("unable to find user for id : " + userId); - } - - // generate both an api key and a secret key, update the user table with the keys, return the keys to the user - String[] keys = new String[2]; - keys[0] = createApiKey(userId); - keys[1] = createSecretKey(userId); - - return keys; - } - - private String createApiKey(Long userId) { - User user = findUserById(userId); - try { - UserVO updatedUser = _userDao.createForUpdate(); - - String encodedKey = null; - Pair userAcct = null; - int retryLimit = 10; - do { - // FIXME: what algorithm should we use for API keys? - KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1"); - SecretKey key = generator.generateKey(); - encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded()); - userAcct = _accountDao.findUserAccountByApiKey(encodedKey); - retryLimit--; - } while ((userAcct != null) && (retryLimit >= 0)); - - if (userAcct != null) { - return null; - } - updatedUser.setApiKey(encodedKey); - _userDao.update(user.getId(), updatedUser); - return encodedKey; - } catch (NoSuchAlgorithmException ex) { - s_logger.error("error generating secret key for user: " + user.getUsername(), ex); - } - return null; - } - - private String createSecretKey(Long userId) { - User user = findUserById(userId); - try { - UserVO updatedUser = _userDao.createForUpdate(); - - String encodedKey = null; - int retryLimit = 10; - UserVO userBySecretKey = null; - do { - KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1"); - SecretKey key = generator.generateKey(); - encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded()); - userBySecretKey = _userDao.findUserBySecretKey(encodedKey); - retryLimit--; - } while ((userBySecretKey != null) && (retryLimit >= 0)); - - if (userBySecretKey != null) { - return null; - } - - updatedUser.setSecretKey(encodedKey); - _userDao.update(user.getId(), updatedUser); - return encodedKey; - } catch (NoSuchAlgorithmException ex) { - s_logger.error("error generating secret key for user: " + user.getUsername(), ex); - } - return null; - } - - @Override - public List listPublicIpAddressesBy(Long accountId, boolean allocatedOnly, Long zoneId, Long vlanDbId) { - SearchCriteria sc = _publicIpAddressDao.createSearchCriteria(); - - if (accountId != null) { - sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); - } - if (zoneId != null) { - sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); - } - if (vlanDbId != null) { - sc.addAnd("vlanDbId", SearchCriteria.Op.EQ, vlanDbId); - } - if (allocatedOnly) { - sc.addAnd("allocated", SearchCriteria.Op.NNULL); - } - - return _publicIpAddressDao.search(sc, null); - } - - @Override - public List listPrivateIpAddressesBy(Long podId, Long zoneId) { - if (podId != null && zoneId != null) { - return _privateIpAddressDao.listByPodIdDcId(podId.longValue(), zoneId.longValue()); - } else { - return new ArrayList(); - } - } - @Override public String generateRandomPassword() { return PasswordGenerator.generateRandomPassword(6); } - @Override - public boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) { - UserVmVO vm = _userVmDao.findById(vmId); - VMTemplateVO iso = _templateDao.findById(isoId); - boolean success = _vmMgr.attachISOToVM(vmId, isoId, attach); - - if (success) { - if (attach) { - vm.setIsoId(iso.getId()); - } else { - vm.setIsoId(null); - } - _userVmDao.update(vmId, vm); - } - return success; - } - @Override public List listDataCenters(ListZonesByCmd cmd) { Account account = UserContext.current().getCaller(); @@ -1435,29 +1118,6 @@ public class ManagementServerImpl implements ManagementServer { return _hostPodDao.search(sc, searchFilter); } - @Override - public List searchForZones(Criteria c) { - Long dataCenterId = (Long) c.getCriteria(Criteria.DATACENTERID); - - if (dataCenterId != null) { - DataCenterVO dc = _dcDao.findById(dataCenterId); - List datacenters = new ArrayList(); - datacenters.add(dc); - return datacenters; - } - - Filter searchFilter = new Filter(DataCenterVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); - SearchCriteria sc = _dcDao.createSearchCriteria(); - - String zoneName = (String) c.getCriteria(Criteria.ZONENAME); - - if (zoneName != null) { - sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + zoneName + "%"); - } - - return _dcDao.search(sc, searchFilter); - } - @Override public List searchForVlans(ListVlanIpRangesCmd cmd) { // If an account name and domain ID are specified, look up the account @@ -1551,16 +1211,6 @@ public class ManagementServerImpl implements ManagementServer { return _vlanDao.search(sc, searchFilter); } - @Override - public Long getPodIdForVlan(long vlanDbId) { - List podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId); - if (podVlanMaps.isEmpty()) { - return null; - } else { - return podVlanMaps.get(0).getPodId(); - } - } - @Override public List searchForConfigurations(ListCfgsByCmd cmd) { Filter searchFilter = new Filter(ConfigurationVO.class, "name", true, cmd.getStartIndex(), cmd.getPageSizeVal()); @@ -1596,69 +1246,6 @@ public class ManagementServerImpl implements ManagementServer { return _configDao.search(sc, searchFilter); } - @Override - public List searchForAlertServers(Criteria c) { - Filter searchFilter = new Filter(HostVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); - SearchCriteria sc = _hostDao.createSearchCriteria(); - - Object[] states = (Object[]) c.getCriteria(Criteria.STATE); - - if (states != null) { - sc.addAnd("status", SearchCriteria.Op.IN, states); - } - - return _hostDao.search(sc, searchFilter); - } - - @Override - public List searchForTemplates(Criteria c) { - Filter searchFilter = new Filter(VMTemplateVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); - - Object name = c.getCriteria(Criteria.NAME); - Object isPublic = c.getCriteria(Criteria.ISPUBLIC); - Object id = c.getCriteria(Criteria.ID); - Object keyword = c.getCriteria(Criteria.KEYWORD); - Long creator = (Long) c.getCriteria(Criteria.CREATED_BY); - - SearchBuilder sb = _templateDao.createSearchBuilder(); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("publicTemplate", sb.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - sb.and("format", sb.entity().getFormat(), SearchCriteria.Op.NEQ); - sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); - - SearchCriteria sc = sb.create(); - - if (keyword != null) { - SearchCriteria ssc = _templateDao.createSearchCriteria(); - ssc.addOr("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("group", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (id != null) { - sc.setParameters("id", id); - } - if (name != null) { - sc.setParameters("name", "%" + name + "%"); - } - - if (isPublic != null) { - sc.setParameters("publicTemplate", isPublic); - } - if (creator != null) { - sc.setParameters("accountId", creator); - } - - sc.setParameters("format", ImageFormat.ISO); - - return _templateDao.search(sc, searchFilter); - } - @Override public Set> listIsos(ListIsosCmd cmd) throws IllegalArgumentException, InvalidParameterValueException { TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); @@ -1752,57 +1339,6 @@ public class ManagementServerImpl implements ManagementServer { return templateZonePairSet; } - @Override - public List listPermittedTemplates(long accountId) { - return _launchPermissionDao.listPermittedTemplates(accountId); - } - - @Override - public List listPods(long dataCenterId) { - return _hostPodDao.listByDataCenterId(dataCenterId); - } - - @Override - public String changePrivateIPRange(boolean add, Long podId, String startIP, String endIP) { - return _configMgr.changePrivateIPRange(add, podId, startIP, endIP); - } - - @Override - public User findUserById(Long userId) { - return _userDao.findById(userId); - } - - @Override - public List findAccountsLike(String accountName) { - return _accountDao.findAccountsLike(accountName); - } - - @Override - public Account findActiveAccountByName(String accountName) { - return _accountDao.findActiveAccountByName(accountName); - } - - @Override - public Account findActiveAccount(String accountName, Long domainId) { - if (domainId == null) { - domainId = DomainVO.ROOT_DOMAIN; - } - return _accountDao.findActiveAccount(accountName, domainId); - } - - @Override - public Account findAccountByName(String accountName, Long domainId) { - if (domainId == null) { - domainId = DomainVO.ROOT_DOMAIN; - } - return _accountDao.findAccount(accountName, domainId); - } - - @Override - public Account findAccountById(Long accountId) { - return _accountDao.findById(accountId); - } - @Override public List searchForAccounts(ListAccountsCmd cmd) { Account caller = UserContext.current().getCaller(); @@ -1930,89 +1466,6 @@ public class ManagementServerImpl implements ManagementServer { return _accountDao.search(sc, searchFilter); } - @Override - public boolean deleteLimit(Long limitId) { - // A limit ID must be passed in - if (limitId == null) { - return false; - } - - return _resourceLimitDao.expunge(limitId); - } - - @Override - public ResourceLimitVO findLimitById(long limitId) { - return _resourceLimitDao.findById(limitId); - } - - @Override - public List listIsos(Criteria c) { - Filter searchFilter = new Filter(VMTemplateVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); - Boolean ready = (Boolean) c.getCriteria(Criteria.READY); - Boolean isPublic = (Boolean) c.getCriteria(Criteria.ISPUBLIC); - Long creator = (Long) c.getCriteria(Criteria.CREATED_BY); - Object keyword = c.getCriteria(Criteria.KEYWORD); - - SearchCriteria sc = _templateDao.createSearchCriteria(); - - if (keyword != null) { - SearchCriteria ssc = _templateDao.createSearchCriteria(); - ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (creator != null) { - sc.addAnd("accountId", SearchCriteria.Op.EQ, creator); - } - if (ready != null) { - sc.addAnd("ready", SearchCriteria.Op.EQ, ready); - } - if (isPublic != null) { - sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, isPublic); - } - - sc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO); - - return _templateDao.search(sc, searchFilter); - } - - @Override - public List findVMInstancesLike(String vmInstanceName) { - return _vmInstanceDao.findVMInstancesLike(vmInstanceName); - } - - @Override - public VMInstanceVO findVMInstanceById(long vmId) { - return _vmInstanceDao.findById(vmId); - } - - @Override - public UserVmVO findUserVMInstanceById(long userVmId) { - return _userVmDao.findById(userVmId); - } - - @Override - public ServiceOfferingVO findServiceOfferingById(long offeringId) { - return _offeringsDao.findById(offeringId); - } - - @Override - public List listAllServiceOfferings() { - return _offeringsDao.listAllIncludingRemoved(); - } - - @Override - public List listAllActiveHosts() { - return _hostDao.listAll(); - } - - @Override - public DataCenterVO findDataCenterById(long dataCenterId) { - return _dcDao.findById(dataCenterId); - } - @Override public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) { return updateTemplateOrIso(cmd); @@ -2096,10 +1549,6 @@ public class ManagementServerImpl implements ManagementServer { return _templateDao.findById(id); } - @Override - public VMTemplateVO findTemplateById(long templateId) { - return _templateDao.findById(templateId); - } @Override public List searchForEvents(ListEventsCmd cmd) { @@ -2213,15 +1662,6 @@ public class ManagementServerImpl implements ManagementServer { return _eventDao.searchAllEvents(sc, searchFilter); } - @Override - public List listRoutersByHostId(long hostId) { - return _routerDao.listByHostId(hostId); - } - - @Override - public List listAllActiveRouters() { - return _routerDao.listAll(); - } @Override public List searchForRouters(ListRoutersCmd cmd) { @@ -2471,25 +1911,6 @@ public class ManagementServerImpl implements ManagementServer { return _volumeDao.search(sc, searchFilter); } - @Override - public VolumeVO findVolumeByInstanceAndDeviceId(long instanceId, long deviceId) { - VolumeVO volume = _volumeDao.findByInstanceAndDeviceId(instanceId, deviceId).get(0); - if (volume != null && volume.getState() != Volume.State.Destroy && volume.getRemoved() == null) { - return volume; - } else { - return null; - } - } - - @Override - public HostPodVO findHostPodById(long podId) { - return _hostPodDao.findById(podId); - } - - @Override - public HostVO findSecondaryStorageHosT(long zoneId) { - return _storageMgr.getSecondaryStorageHost(zoneId); - } @Override public List searchForIPAddresses(ListPublicIpAddressesCmd cmd) { @@ -2616,131 +2037,6 @@ public class ManagementServerImpl implements ManagementServer { return _publicIpAddressDao.search(sc, searchFilter); } - @Override - public UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters) { - UserAccount user = null; - if (password != null) { - user = getUserAccount(username, password, domainId); - } else { - String key = getConfigurationValue("security.singlesignon.key"); - if (key == null) { - // the SSO key is gone, don't authenticate - return null; - } - - String singleSignOnTolerance = getConfigurationValue("security.singlesignon.tolerance.millis"); - if (singleSignOnTolerance == null) { - // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be valid), - // don't authenticate - return null; - } - - long tolerance = Long.parseLong(singleSignOnTolerance); - String signature = null; - long timestamp = 0L; - String unsignedRequest = null; - - // - build a request string with sorted params, make sure it's all lowercase - // - sign the request, verify the signature is the same - List parameterNames = new ArrayList(); - - for (Object paramNameObj : requestParameters.keySet()) { - parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later - } - - Collections.sort(parameterNames); - - try { - for (String paramName : parameterNames) { - // parameters come as name/value pairs in the form String/String[] - String paramValue = ((String[]) requestParameters.get(paramName))[0]; - - if ("signature".equalsIgnoreCase(paramName)) { - signature = paramValue; - } else { - if ("timestamp".equalsIgnoreCase(paramName)) { - String timestampStr = paramValue; - try { - // If the timestamp is in a valid range according to our tolerance, verify the request - // signature, otherwise return null to indicate authentication failure - timestamp = Long.parseLong(timestampStr); - long currentTime = System.currentTimeMillis(); - if (Math.abs(currentTime - timestamp) > tolerance) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expired timestamp passed in to login, current time = " + currentTime + ", timestamp = " + timestamp); - } - return null; - } - } catch (NumberFormatException nfe) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Invalid timestamp passed in to login: " + timestampStr); - } - return null; - } - } - - if (unsignedRequest == null) { - unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); - } else { - unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); - } - } - } - - if ((signature == null) || (timestamp == 0L)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Missing parameters in login request, signature = " + signature + ", timestamp = " + timestamp); - } - return null; - } - - unsignedRequest = unsignedRequest.toLowerCase(); - - Mac mac = Mac.getInstance("HmacSHA1"); - SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1"); - mac.init(keySpec); - mac.update(unsignedRequest.getBytes()); - byte[] encryptedBytes = mac.doFinal(); - String computedSignature = new String(Base64.encodeBase64(encryptedBytes)); - boolean equalSig = signature.equals(computedSignature); - if (!equalSig) { - s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature); - } else { - user = getUserAccount(username, domainId); - } - } catch (Exception ex) { - s_logger.error("Exception authenticating user", ex); - return null; - } - } - - if (user != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); - } - EventUtils.saveEvent(user.getId(), user.getAccountId(), EventTypes.EVENT_USER_LOGIN, "user has logged in"); - return user; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("User: " + username + " in domain " + domainId + " has failed to log in"); - } - return null; - } - } - - @Override - public void logoutUser(Long userId) { - UserAccount userAcct = _userAccountDao.findById(userId); - if (userAcct != null) { - EventUtils.saveEvent(userId, userAcct.getAccountId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out"); - } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted... - } - - @Override - public List listAllTemplates() { - return _templateDao.listAllIncludingRemoved(); - } - @Override public List listGuestOSByCriteria(ListGuestOsCmd cmd) { Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, cmd.getStartIndex(), cmd.getPageSizeVal()); @@ -2782,24 +2078,17 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public String getConfigurationValue(String name) { - return _configDao.getValue(name); - } - - @Override - public ConsoleProxyInfo getConsoleProxy(long dataCenterId, long userVmId) { + public ConsoleProxyInfo getConsoleProxyForUserVm(long dataCenterId, long userVmId) { return _consoleProxyMgr.assignProxy(dataCenterId, userVmId); } - @Override @ActionEvent(eventType = EventTypes.EVENT_PROXY_START, eventDescription = "starting console proxy Vm", async = true) - public ConsoleProxyVO startConsoleProxy(long instanceId) { + private ConsoleProxyVO startConsoleProxy(long instanceId) { return _consoleProxyMgr.startProxy(instanceId); } - @Override @ActionEvent(eventType = EventTypes.EVENT_PROXY_STOP, eventDescription = "stopping console proxy Vm", async = true) - public ConsoleProxyVO stopConsoleProxy(VMInstanceVO systemVm, boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { + private ConsoleProxyVO stopConsoleProxy(VMInstanceVO systemVm, boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { User caller = _userDao.findById(UserContext.current().getCallerUserId()); @@ -2809,9 +2098,8 @@ public class ManagementServerImpl implements ManagementServer { return null; } - @Override @ActionEvent(eventType = EventTypes.EVENT_PROXY_REBOOT, eventDescription = "rebooting console proxy Vm", async = true) - public ConsoleProxyVO rebootConsoleProxy(long instanceId) { + private ConsoleProxyVO rebootConsoleProxy(long instanceId) { _consoleProxyMgr.rebootProxy(instanceId); return _consoleProxyDao.findById(instanceId); } @@ -2828,9 +2116,9 @@ public class ManagementServerImpl implements ManagementServer { @Override public String getConsoleAccessUrlRoot(long vmId) { - VMInstanceVO vm = this.findVMInstanceById(vmId); + VMInstanceVO vm = _vmMgr.findById(vmId); if (vm != null) { - ConsoleProxyInfo proxy = getConsoleProxy(vm.getDataCenterIdToDeployIn(), vmId); + ConsoleProxyInfo proxy = getConsoleProxyForUserVm(vm.getDataCenterIdToDeployIn(), vmId); if (proxy != null) { return proxy.getProxyImageUrl(); } @@ -2857,11 +2145,6 @@ public class ManagementServerImpl implements ManagementServer { return new Pair(null, -1); } - @Override - public ConsoleProxyVO findConsoleProxyById(long instanceId) { - return _consoleProxyDao.findById(instanceId); - } - @Override public List searchForDomains(ListDomainsCmd cmd) throws PermissionDeniedException { Long domainId = cmd.getId(); @@ -2974,123 +2257,6 @@ public class ManagementServerImpl implements ManagementServer { return _domainDao.search(sc, searchFilter); } - @Override - @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_DELETE, eventDescription = "deleting Domain", async = true) - public boolean deleteDomain(DeleteDomainCmd cmd) { - Account caller = UserContext.current().getCaller(); - Long domainId = cmd.getId(); - Boolean cleanup = cmd.getCleanup(); - - DomainVO domain = _domainDao.findById(domainId); - - if (domain == null) { - throw new InvalidParameterValueException("Failed to delete domain " + domainId + ", domain not found"); - } else if (domainId == DomainVO.ROOT_DOMAIN) { - throw new PermissionDeniedException("Can't delete ROOT domain"); - } - - _accountMgr.checkAccess(caller, domain); - - //mark domain as inactive - s_logger.debug("Marking domain id=" + domainId + " as " + Domain.State.Inactive + " before actually deleting it"); - domain.setState(Domain.State.Inactive); - _domainDao.update(domainId, domain); - - try { - long ownerId = domain.getAccountId(); - if ((cleanup != null) && cleanup.booleanValue()) { - if (!cleanupDomain(domainId, ownerId)) { - s_logger.error("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domainId + ")."); - return false; - } - } else { - List accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId); - if (accountsForCleanup.isEmpty()) { - if (!_domainDao.remove(domainId)) { - s_logger.error("Delete failed on domain " + domain.getName() + " (id: " + domainId - + "); please make sure all users and sub domains have been removed from the domain before deleting"); - return false; - } - } else { - s_logger.warn("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); - return false; - } - } - - cleanupDomainOfferings(domainId); - return true; - } catch (Exception ex) { - s_logger.error("Exception deleting domain with id " + domainId, ex); - return false; - } - } - - private void cleanupDomainOfferings(Long domainId) { - // delete the service and disk offerings associated with this domain - List diskOfferingsForThisDomain = _diskOfferingDao.listByDomainId(domainId); - for (DiskOfferingVO diskOffering : diskOfferingsForThisDomain) { - _diskOfferingDao.remove(diskOffering.getId()); - } - - List serviceOfferingsForThisDomain = _offeringsDao.findServiceOfferingByDomainId(domainId); - for (ServiceOfferingVO serviceOffering : serviceOfferingsForThisDomain) { - _offeringsDao.remove(serviceOffering.getId()); - } - } - - private boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException { - boolean success = true; - { - DomainVO domainHandle = _domainDao.findById(domainId); - domainHandle.setState(Domain.State.Inactive); - _domainDao.update(domainId, domainHandle); - - SearchCriteria sc = _domainDao.createSearchCriteria(); - sc.addAnd("parent", SearchCriteria.Op.EQ, domainId); - List domains = _domainDao.search(sc, null); - - SearchCriteria sc1 = _domainDao.createSearchCriteria(); - sc1.addAnd("path", SearchCriteria.Op.LIKE, "%" + domainHandle.getPath() + "%"); - List domainsToBeInactivated = _domainDao.search(sc1, null); - - // update all subdomains to inactive so no accounts/users can be created - for (DomainVO domain : domainsToBeInactivated) { - domain.setState(Domain.State.Inactive); - _domainDao.update(domain.getId(), domain); - } - - // cleanup sub-domains first - for (DomainVO domain : domains) { - success = (success && cleanupDomain(domain.getId(), domain.getAccountId())); - if (!success) { - s_logger.warn("Failed to cleanup domain id=" + domain.getId()); - } - } - } - - // delete users which will also delete accounts and release resources for those accounts - SearchCriteria sc = _accountDao.createSearchCriteria(); - sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId); - List accounts = _accountDao.search(sc, null); - for (AccountVO account : accounts) { - success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller())); - if (!success) { - s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup"); - } - } - - //don't remove the domain if there are accounts required cleanup - boolean deleteDomainSuccess = true; - List accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId); - if (accountsForCleanup.isEmpty()) { - deleteDomainSuccess = _domainDao.remove(domainId); - } else { - s_logger.debug("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); - } - - return success && deleteDomainSuccess; - } - @Override @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_UPDATE, eventDescription = "updating Domain") @DB @@ -3174,25 +2340,6 @@ public class ManagementServerImpl implements ManagementServer { } } - @Override - public Long findDomainIdByAccountId(Long accountId) { - if (accountId == null) { - return null; - } - - AccountVO account = _accountDao.findById(accountId); - if (account != null) { - return account.getDomainId(); - } - - return null; - } - - @Override - public DomainVO findDomainByPath(String domainPath) { - return _domainDao.findDomainByPath(domainPath); - } - @Override public List searchForAlerts(ListAlertsCmd cmd) { Filter searchFilter = new Filter(AlertVO.class, "lastSent", false, cmd.getStartIndex(), cmd.getPageSizeVal()); @@ -3357,7 +2504,7 @@ public class ManagementServerImpl implements ManagementServer { } boolean isAdmin = isAdmin(caller.getType()); - boolean allowPublicUserTemplates = Boolean.parseBoolean(getConfigurationValue("allow.public.user.templates")); + boolean allowPublicUserTemplates = Boolean.valueOf(_configDao.getValue("allow.public.user.templates")); if (!isAdmin && !allowPublicUserTemplates && isPublic != null && isPublic) { throw new InvalidParameterValueException("Only private " + mediaType + "s can be created."); } @@ -3636,65 +2783,6 @@ public class ManagementServerImpl implements ManagementServer { return _diskOfferingDao.search(sc, searchFilter); } - // @Override - // public AsyncJobResult queryAsyncJobResult(QueryAsyncJobResultCmd cmd) throws PermissionDeniedException { - // return queryAsyncJobResult(cmd.getId()); - // } - - @Override - public AsyncJobResult queryAsyncJobResult(long jobId) throws PermissionDeniedException { - AsyncJobVO job = _asyncMgr.getAsyncJob(jobId); - if (job == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("queryAsyncJobResult error: Permission denied, invalid job id " + jobId); - } - - throw new PermissionDeniedException("Permission denied, invalid job id " + jobId); - } - - // treat any requests from API server as trusted requests - if (!UserContext.current().isApiServer() && job.getAccountId() != UserContext.current().getCaller().getId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Mismatched account id in job and user context, perform further securty check. job id: " + jobId + ", job owner account: " + job.getAccountId() - + ", accound id in current context: " + UserContext.current().getCaller().getId()); - } - - Account account = UserContext.current().getCaller(); - if (account != null) { - if (isAdmin(account.getType())) { - Account jobAccount = _accountDao.findById(job.getAccountId()); - if (jobAccount == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("queryAsyncJobResult error: Permission denied, account no long exist for account id in context, job id: " + jobId + ", accountId " + job.getAccountId()); - } - throw new PermissionDeniedException("Permission denied, invalid job ownership, job id: " + jobId); - } - - if (!_domainDao.isChildDomain(account.getDomainId(), jobAccount.getDomainId())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("queryAsyncJobResult error: Permission denied, invalid ownership for job " + jobId + ", job account owner: " + job.getAccountId() + " in domain: " - + jobAccount.getDomainId() + ", account id in context: " + account.getId() + " in domain: " + account.getDomainId()); - } - throw new PermissionDeniedException("Permission denied, invalid job ownership, job id: " + jobId); - } - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("queryAsyncJobResult error: Permission denied, invalid ownership for job " + jobId + ", job account owner: " + job.getAccountId() + ", account id in context: " - + account.getId()); - } - throw new PermissionDeniedException("Permission denied, invalid job ownership, job id: " + jobId); - } - } - } - - return _asyncMgr.queryAsyncJobResult(jobId); - } - - @Override - public AsyncJobVO findAsyncJobById(long jobId) { - return _asyncMgr.getAsyncJob(jobId); - } - @Override public String[] getApiConfig() { return new String[] { "commands.properties" }; @@ -3734,11 +2822,6 @@ public class ManagementServerImpl implements ManagementServer { } } - @Override - public StoragePoolVO findPoolById(Long id) { - return _poolDao.findById(id); - } - @Override public List searchForStoragePools(ListStoragePoolsCmd cmd) { @@ -3808,10 +2891,6 @@ public class ManagementServerImpl implements ManagementServer { return _poolDao.search(sc, searchFilter); } - @Override - public List searchForStoragePoolDetails(long poolId, String value) { - return _poolDao.searchForStoragePoolDetails(poolId, value); - } @Override public List searchForAsyncJobs(ListAsyncJobsCmd cmd) { @@ -3895,18 +2974,13 @@ public class ManagementServerImpl implements ManagementServer { return _jobDao.search(sc, searchFilter); } - @Override - public boolean isChildDomain(Long parentId, Long childId) { - return _domainDao.isChildDomain(parentId, childId); - } - @ActionEvent(eventType = EventTypes.EVENT_SSVM_START, eventDescription = "starting secondary storage Vm", async = true) public SecondaryStorageVmVO startSecondaryStorageVm(long instanceId) { return _secStorageVmMgr.startSecStorageVm(instanceId); } @ActionEvent(eventType = EventTypes.EVENT_SSVM_STOP, eventDescription = "stopping secondary storage Vm", async = true) - public SecondaryStorageVmVO stopSecondaryStorageVm(VMInstanceVO systemVm, boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { + private SecondaryStorageVmVO stopSecondaryStorageVm(VMInstanceVO systemVm, boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { User caller = _userDao.findById(UserContext.current().getCallerUserId()); @@ -3993,19 +3067,6 @@ public class ManagementServerImpl implements ManagementServer { return _vmInstanceDao.search(sc, searchFilter); } - @Override - public VMInstanceVO findSystemVMById(long instanceId) { - VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(instanceId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); - if (systemVm == null) { - return null; - } - - if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) { - return _consoleProxyDao.findById(instanceId); - } - return _secStorageVmDao.findById(instanceId); - } - @Override public VirtualMachine.Type findSystemVMTypeById(long instanceId) { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(instanceId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); @@ -4016,12 +3077,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public VirtualMachine startSystemVM(StartSystemVMCmd cmd) { - return startSystemVm(cmd.getId()); - } - - @Override - public VirtualMachine startSystemVm(long vmId) { + public VirtualMachine startSystemVM(long vmId) { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { @@ -4114,7 +3170,7 @@ public class ManagementServerImpl implements ManagementServer { Account caller = UserContext.current().getCaller(); // verify that user exists - User user = findUserById(userId); + User user = _accountMgr.getUser(userId); if ((user == null) || (user.getRemoved() != null)) { throw new InvalidParameterValueException("Unable to find active user by id " + userId); } @@ -4130,7 +3186,7 @@ public class ManagementServerImpl implements ManagementServer { String signature = ""; try { // get the user obj to get his secret key - user = getUser(userId); + user = _accountMgr.getActiveUser(userId); String secretKey = user.getSecretKey(); String input = cloudIdentifier; signature = signRequest(input, secretKey); @@ -4145,18 +3201,6 @@ public class ManagementServerImpl implements ManagementServer { return cloudParams; } - @Override - public SecurityGroupVO findNetworkGroupByName(Long accountId, String groupName) { - SecurityGroupVO groupVO = _networkSecurityGroupDao.findByAccountAndName(accountId, groupName); - return groupVO; - } - - @Override - public SecurityGroupVO findNetworkGroupById(long networkGroupId) { - SecurityGroupVO groupVO = _networkSecurityGroupDao.findById(networkGroupId); - return groupVO; - } - @Override public List listPendingEvents(int entryTime, int duration) { Calendar calMin = Calendar.getInstance(); @@ -4176,37 +3220,6 @@ public class ManagementServerImpl implements ManagementServer { return pendingEvents; } - @Override - public boolean checkLocalStorageConfigVal() { - String value = _configs.get("use.local.storage"); - - if (value != null && value.equalsIgnoreCase("true")) { - return true; - } else { - return false; - } - } - - @Override - public boolean checkIfMaintenable(long hostId) { - - // get the poolhostref record - List poolHostRecordSet = _poolHostDao.listByHostIdIncludingRemoved(hostId); - - if (poolHostRecordSet != null) { - // the above list has only 1 record - StoragePoolHostVO poolHostRecord = poolHostRecordSet.get(0); - - // get the poolId and get hosts associated in that pool - List hostsInPool = _poolHostDao.listByPoolId(poolHostRecord.getPoolId()); - - if (hostsInPool != null && hostsInPool.size() > 1) { - return true; // since there are other hosts to take over as master in this pool - } - } - return false; - } - @Override public Map listCapabilities(ListCapabilitiesCmd cmd) { Map capabilities = new HashMap(); @@ -4242,38 +3255,6 @@ public class ManagementServerImpl implements ManagementServer { return _guestOSDao.findById(guestOsId); } - @Override - public VolumeVO getRootVolume(Long instanceId) { - return _volumeDao.findByInstanceAndType(instanceId, Volume.Type.ROOT).get(0); - } - - @Override - public long getPsMaintenanceCount(long podId) { - List poolsInTransition = new ArrayList(); - poolsInTransition.addAll(_poolDao.listByStatus(StoragePoolStatus.Maintenance)); - poolsInTransition.addAll(_poolDao.listByStatus(StoragePoolStatus.PrepareForMaintenance)); - poolsInTransition.addAll(_poolDao.listByStatus(StoragePoolStatus.ErrorInMaintenance)); - - return poolsInTransition.size(); - } - - @Override - public boolean isPoolUp(long instanceId) { - VolumeVO rootVolume = _volumeDao.findByInstance(instanceId).get(0); - - if (rootVolume != null) { - StoragePoolStatus poolStatus = _poolDao.findById(rootVolume.getPoolId()).getStatus(); - - if (!poolStatus.equals(Status.Up)) { - return false; - } else { - return true; - } - } - - return false; - } - @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) public Long extractVolume(ExtractVolumeCmd cmd) throws URISyntaxException { @@ -4540,16 +3521,6 @@ public class ManagementServerImpl implements ManagementServer { return _vmGroupDao.search(sc, searchFilter); } - @Override - public InstanceGroupVO getGroupForVm(long vmId) { - return _vmMgr.getGroupForVm(vmId); - } - - @Override - public List searchForZoneWideVlans(long dcId, String vlanType, String vlanId) { - return _vlanDao.searchForZoneWideVlans(dcId, vlanType, vlanId); - } - @Override public String getVersion() { final Class c = ManagementServer.class; diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index 4b2f6391ca2..9a75d112a00 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -41,13 +41,16 @@ import com.cloud.host.HostVO; import com.cloud.server.ManagementServer; import com.cloud.storage.GuestOSVO; import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.User; +import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.Transaction; -import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineManager; /** * Thumbnail access : /console?cmd=thumbnail&vm=xxx&w=xxx&h=xxx @@ -60,6 +63,9 @@ public class ConsoleProxyServlet extends HttpServlet { private static final int DEFAULT_THUMBNAIL_WIDTH = 144; private static final int DEFAULT_THUMBNAIL_HEIGHT = 110; + private final static AccountManager _accountMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(AccountManager.class); + private final static VirtualMachineManager _vmMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(VirtualMachineManager.class); + private final static DomainManager _domainMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(DomainManager.class); private final static ManagementServer _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name); @Override @@ -71,7 +77,7 @@ public class ConsoleProxyServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { try { - if(_ms == null) { + if(_accountMgr == null || _vmMgr == null || _ms == null) { sendResponse(resp, "Service is not ready"); return; } @@ -156,7 +162,7 @@ public class ConsoleProxyServlet extends HttpServlet { } private void handleThumbnailRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) { - VMInstanceVO vm = _ms.findVMInstanceById(vmId); + VMInstanceVO vm = _vmMgr.findById(vmId); if(vm == null) { s_logger.warn("VM " + vmId + " does not exist, sending blank response for thumbnail request"); sendResponse(resp, ""); @@ -207,7 +213,7 @@ public class ConsoleProxyServlet extends HttpServlet { } private void handleAccessRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) { - VMInstanceVO vm = _ms.findVMInstanceById(vmId); + VMInstanceVO vm = _vmMgr.findById(vmId); if(vm == null) { s_logger.warn("VM " + vmId + " does not exist, sending blank response for console access request"); sendResponse(resp, ""); @@ -235,7 +241,7 @@ public class ConsoleProxyServlet extends HttpServlet { String vmName = vm.getInstanceName(); if(vm.getType() == VirtualMachine.Type.User) { - UserVmVO userVm = _ms.findUserVMInstanceById(vmId); + UserVm userVm = (UserVm)_vmMgr.findByIdAndType(VirtualMachine.Type.User, vmId); String displayName = userVm.getDisplayName(); if(displayName != null && !displayName.isEmpty() && !displayName.equals(vmName)) { vmName += "(" + displayName + ")"; @@ -252,7 +258,7 @@ public class ConsoleProxyServlet extends HttpServlet { // TODO authentication channel between console proxy VM and management server needs to be secured, // the data is now being sent through private network, but this is apparently not enough - VMInstanceVO vm = _ms.findVMInstanceById(vmId); + VMInstanceVO vm = _vmMgr.findById(vmId); if(vm == null) { s_logger.warn("VM " + vmId + " does not exist, sending failed response for authentication request from console proxy"); sendResponse(resp, "failed"); @@ -378,7 +384,7 @@ public class ConsoleProxyServlet extends HttpServlet { private boolean checkSessionPermision(HttpServletRequest req, long vmId, Account accountObj) { - VMInstanceVO vm = _ms.findVMInstanceById(vmId); + VMInstanceVO vm = _vmMgr.findById(vmId); if(vm == null) { s_logger.debug("Console/thumbnail access denied. VM " + vmId + " does not exist in system any more"); return false; @@ -403,7 +409,7 @@ public class ConsoleProxyServlet extends HttpServlet { } if(accountObj.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || accountObj.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) { - if(!_ms.isChildDomain(accountObj.getDomainId(), vm.getDomainId())) { + if(!_domainMgr.isChildDomain(accountObj.getDomainId(), vm.getDomainId())) { if(s_logger.isDebugEnabled()) { s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + " does not match the account id in session " + accountObj.getId() + " and the domain-admin caller does not manage the target domain"); @@ -437,10 +443,10 @@ public class ConsoleProxyServlet extends HttpServlet { public boolean verifyUser(Long userId) { // copy from ApiServer.java, a bit ugly here - User user = _ms.findUserById(userId); + User user = _accountMgr.getUser(userId); Account account = null; if (user != null) { - account = _ms.findAccountById(user.getAccountId()); + account = _accountMgr.getAccount(user.getAccountId()); } if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) @@ -502,7 +508,7 @@ public class ConsoleProxyServlet extends HttpServlet { txn.close(); User user = null; // verify there is a user with this api key - Pair userAcctPair = _ms.findUserByApiKey(apiKey); + Pair userAcctPair = _accountMgr.findUserByApiKey(apiKey); if (userAcctPair == null) { s_logger.debug("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey); return false; diff --git a/server/src/com/cloud/servlet/RegisterCompleteServlet.java b/server/src/com/cloud/servlet/RegisterCompleteServlet.java index a9c70d74ae7..72bc82c281d 100644 --- a/server/src/com/cloud/servlet/RegisterCompleteServlet.java +++ b/server/src/com/cloud/servlet/RegisterCompleteServlet.java @@ -99,8 +99,8 @@ public class RegisterCompleteServlet extends HttpServlet implements ServletConte _accountSvc.markUserRegistered(resourceAdminUser.getId()); } - Account resourceAdminAccount = _accountSvc.getActiveAccount(resourceAdminUser.getAccountId()); - Account rsUserAccount = _accountSvc.getActiveAccount(resourceAdminAccount.getAccountName()+"-user", resourceAdminAccount.getDomainId()); + Account resourceAdminAccount = _accountSvc.getActiveAccountById(resourceAdminUser.getAccountId()); + Account rsUserAccount = _accountSvc.getActiveAccountByName(resourceAdminAccount.getAccountName()+"-user", resourceAdminAccount.getDomainId()); List users = _userDao.listByAccount(rsUserAccount.getId()); User rsUser = users.get(0); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index cd2054bda95..15bb604dd8b 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -80,7 +80,7 @@ import com.cloud.cluster.ClusterManagerListener; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.ClusterVO; @@ -143,6 +143,7 @@ import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -284,6 +285,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag protected VolumeDao _volumeDao; @Inject protected OCFS2Manager _ocfs2Mgr; + @Inject + protected ResourceLimitService _resourceLimitMgr; @Inject(adapter = StoragePoolAllocator.class) protected Adapters _storagePoolAllocators; @@ -1626,7 +1629,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag // check if the volume can be created for the user // Check that the resource limit for volumes won't be exceeded - if (_accountMgr.resourceLimitExceeded(targetAccount, ResourceType.volume)) { + if (_resourceLimitMgr.resourceLimitExceeded(targetAccount, ResourceType.volume)) { UserContext.current().setEventDetails("Maximum number of volumes for account: " + targetAccount.getAccountName() + " has been exceeded."); ResourceAllocationException rae = new ResourceAllocationException("Maximum number of volumes for account: " + targetAccount.getAccountName() + " has been exceeded."); rae.setResourceType("volume"); @@ -1775,7 +1778,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag UserContext.current().setEventDetails("Volume Id: " + volume.getId()); // Increment resource count during allocation; if actual creation fails, decrement it - _accountMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); return volume; } @@ -1803,7 +1806,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } finally { if (!created) { s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); - _accountMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); } } } @@ -1829,7 +1832,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { // Decrement the resource count for volumes belonging user VM's only - _accountMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); // Log usage event for volumes belonging user VM's only UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); _usageEventDao.persist(usageEvent); @@ -2543,7 +2546,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size); _usageEventDao.persist(usageEvent); - _accountMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); } return toDiskProfile(vol, offering); } @@ -2593,7 +2596,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag vol.getSize()); _usageEventDao.persist(usageEvent); - _accountMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); } return toDiskProfile(vol, offering); } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 33aa2aefda6..aaa637fbc09 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -47,7 +47,7 @@ import com.cloud.api.commands.ListSnapshotPoliciesCmd; import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.async.AsyncJobManager; import com.cloud.configuration.Config; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; @@ -92,6 +92,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -163,6 +164,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject private UsageEventDao _usageEventDao; @Inject + private ResourceLimitService _resourceLimitMgr; + @Inject private SwiftDao _swiftDao; String _name; private int _totalRetries; @@ -437,7 +440,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma snapshot.setStatus(Status.Error); _snapshotDao.update(snapshot.getId(), snapshot); } else { - _accountMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot); + _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot); } } @@ -720,7 +723,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L); _usageEventDao.persist(usageEvent); } - _accountMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); + _resourceLimitMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); txn.commit(); long lastId = snapshotId; @@ -1004,7 +1007,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma for (SnapshotVO snapshot : snapshots) { if (_snapshotDao.expunge(snapshot.getId())) { if (snapshot.getType() == Type.MANUAL) { - _accountMgr.decrementResourceCount(accountId, ResourceType.snapshot); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot); } // Log event after successful deletion @@ -1079,8 +1082,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } // Verify that max doesn't exceed domain and account snapshot limits - long accountLimit = _accountMgr.findCorrectResourceLimit(owner.getId(), ResourceType.snapshot); - long domainLimit = _accountMgr.findCorrectResourceLimit(domain, ResourceType.snapshot); + long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner.getId(), ResourceType.snapshot); + long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(null, ResourceType.snapshot); int max = cmd.getMaxSnaps().intValue(); if (owner.getType() != Account.ACCOUNT_TYPE_ADMIN && ((accountLimit != -1 && max > accountLimit) || (domainLimit != -1 && max > domainLimit))) { throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the domain/account level snapshot limit"); @@ -1267,7 +1270,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma _accountMgr.checkAccess(caller, null, volume); Account owner = _accountMgr.getAccount(volume.getAccountId()); - if (_accountMgr.resourceLimitExceeded(owner, ResourceType.snapshot)) { + if (_resourceLimitMgr.resourceLimitExceeded(owner, ResourceType.snapshot)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of snapshots for account: " + owner.getAccountName() + " has been exceeded."); rae.setResourceType("snapshot"); throw rae; diff --git a/server/src/com/cloud/template/HyervisorTemplateAdapter.java b/server/src/com/cloud/template/HyervisorTemplateAdapter.java index 2d7244c2beb..da7de2005ea 100755 --- a/server/src/com/cloud/template/HyervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HyervisorTemplateAdapter.java @@ -5,7 +5,6 @@ import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; -import java.util.ArrayList; import java.util.List; import javax.ejb.Local; @@ -16,19 +15,19 @@ import com.cloud.api.commands.DeleteIsoCmd; import com.cloud.api.commands.DeleteTemplateCmd; import com.cloud.api.commands.RegisterIsoCmd; import com.cloud.api.commands.RegisterTemplateCmd; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.download.DownloadMonitor; import com.cloud.user.Account; import com.cloud.utils.component.Inject; @@ -116,7 +115,7 @@ public class HyervisorTemplateAdapter extends TemplateAdapterBase implements Tem VMTemplateVO template = persistTemplate(profile); _downloadMonitor.downloadTemplateToStorage(template, profile.getZoneId()); - _accountMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); + _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); return template; } @@ -214,7 +213,7 @@ public class HyervisorTemplateAdapter extends TemplateAdapterBase implements Tem success = false; } else if (_tmpltDao.remove(templateId)) { // Decrement the number of templates - _accountMgr.decrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); } } finally { diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 24062027752..45f76122ce3 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -13,7 +13,7 @@ import com.cloud.api.commands.DeleteIsoCmd; import com.cloud.api.commands.DeleteTemplateCmd; import com.cloud.api.commands.RegisterIsoCmd; import com.cloud.api.commands.RegisterTemplateCmd; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; @@ -35,6 +35,7 @@ import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.UserContext; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; @@ -57,6 +58,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter { protected @Inject VMTemplateZoneDao _tmpltZoneDao; protected @Inject UsageEventDao _usageEventDao; protected @Inject HostDao _hostDao; + protected @Inject ResourceLimitService _resourceLimitMgr; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -206,7 +208,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter { } AccountVO account = _accountDao.findById(accountId); - if (_accountMgr.resourceLimitExceeded(account, ResourceType.template)) { + if (_resourceLimitMgr.resourceLimitExceeded(account, ResourceType.template)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded."); rae.setResourceType("template"); throw rae; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 26f8f6bc4c0..1a2e3867da3 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -52,7 +52,7 @@ import com.cloud.api.commands.RegisterTemplateCmd; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; import com.cloud.configuration.Config; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; @@ -106,6 +106,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; @@ -164,6 +165,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe @Inject UsageEventDao _usageEventDao; @Inject HypervisorGuruManager _hvGuruMgr; @Inject AccountService _accountService; + @Inject ResourceLimitService _resourceLimitMgr; int _primaryStorageDownloadWait; protected SearchBuilder HostTemplateStatesSearch; @@ -523,7 +525,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe throw new StorageUnavailableException("Destination zone is not ready", DataCenter.class, dstZone.getId()); } AccountVO account = _accountDao.findById(template.getAccountId()); - if (_accountMgr.resourceLimitExceeded(account, ResourceType.template)) { + if (_resourceLimitMgr.resourceLimitExceeded(account, ResourceType.template)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded."); rae.setResourceType("template"); throw rae; diff --git a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java b/server/src/com/cloud/upgrade/dao/Upgrade218to22.java index 76477a41171..88c712d392a 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade218to22.java @@ -37,7 +37,7 @@ import java.util.UUID; import org.apache.log4j.Logger; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; @@ -1477,30 +1477,9 @@ public class Upgrade218to22 implements DbUpgrade { upgradeDomainResourceCounts(conn, ResourceType.public_ip); } - private void upgradeDomainResourceCounts(Connection conn, ResourceType type) { + private void upgradeDomainResourceCounts(Connection conn, ResourceType resourceType) { try { - String resourceType; - switch (type) { - case user_vm: - resourceType = "user_vm"; - break; - case volume: - resourceType = "volume"; - break; - case snapshot: - resourceType = "snapshot"; - break; - case template: - resourceType = "template"; - break; - case public_ip: - resourceType = "public_ip"; - break; - default: - resourceType = "user_vm"; - } - PreparedStatement account_count_pstmt = conn.prepareStatement("SELECT account_id, count from resource_count where type='" + resourceType + "'"); ResultSet rs_account_count = account_count_pstmt.executeQuery(); @@ -1541,7 +1520,7 @@ public class Upgrade218to22 implements DbUpgrade { update_domain_count_pstmt.close(); } else { PreparedStatement update_domain_count_pstmt = conn.prepareStatement("INSERT INTO resource_count (type, count, domain_id) VALUES (?,?,?)"); - update_domain_count_pstmt.setString(1, resourceType); + update_domain_count_pstmt.setString(1, resourceType.getName()); update_domain_count_pstmt.setLong(2, accountCount); update_domain_count_pstmt.setLong(3, domainId); update_domain_count_pstmt.executeUpdate(); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java b/server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java index a10244370a9..f7288ebb715 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java @@ -27,8 +27,8 @@ import java.util.List; import org.apache.log4j.Logger; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @@ -95,8 +95,7 @@ public class Upgrade2211to2212 implements DbUpgrade { rs.close(); for (Long accountId : accounts) { - ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); - for (ResourceType resourceType : resourceTypes) { + for (ResourceType resourceType : Resource.ResourceType.values()) { pstmt = conn.prepareStatement("SELECT * FROM resource_count WHERE type=? and account_id=?"); pstmt.setString(1, resourceType.toString()); pstmt.setLong(2, accountId); @@ -114,8 +113,7 @@ public class Upgrade2211to2212 implements DbUpgrade { } for (Long domainId : domains) { - ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); - for (ResourceType resourceType : resourceTypes) { + for (ResourceType resourceType : Resource.ResourceType.values()) { pstmt = conn.prepareStatement("SELECT * FROM resource_count WHERE type=? and domain_id=?"); pstmt.setString(1, resourceType.toString()); pstmt.setLong(2, domainId); diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index 20481638190..ceec0b89476 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -18,98 +18,21 @@ package com.cloud.user; -import java.util.List; +import java.util.Map; import com.cloud.acl.ControlledEntity; import com.cloud.acl.SecurityChecker.AccessType; -import com.cloud.api.commands.CreateUserCmd; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceCount.ResourceType; -import com.cloud.configuration.ResourceLimitVO; import com.cloud.domain.Domain; -import com.cloud.domain.DomainVO; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.server.Criteria; +import com.cloud.utils.Pair; /** * AccountManager includes logic that deals with accounts, domains, and users. * */ public interface AccountManager extends AccountService { - - /** - * Finds all ISOs that are usable for a user. This includes ISOs usable for the user's account and for all of the account's parent domains. - * @param userId - * @return List of IsoVOs - */ - // public List findAllIsosForUser(long userId); - - /** - * Finds the resource limit for a specified account and type. If the account has an infinite limit, will check - * the account's parent domain, and if that limit is also infinite, will return the ROOT domain's limit. - * @param accountId - * @param type - * @return resource limit - */ - public long findCorrectResourceLimit(long accountId, ResourceType type); - - /** - * Finds the resource limit for a specified domain and type. If the domain has an infinite limit, will check - * up the domain hierarchy - * @param account - * @param type - * @return resource limit - */ - public long findCorrectResourceLimit(DomainVO domain, ResourceType type); - - /** - * Updates the resource count of an account to reflect current usage by account - * @param accountId - * @param type - */ - public long updateAccountResourceCount(long accountId, ResourceType type); - - /** - * Updates the resource count of the domain to reflect current usage in the domain - * @param domainId - * @param type - */ - public long updateDomainResourceCount(long domainId, ResourceType type); - /** - * Increments the resource count - * @param accountId - * @param type - * @param delta - */ - public void incrementResourceCount(long accountId, ResourceType type, Long...delta); - - /** - * Decrements the resource count - * @param accountId - * @param type - * @param delta - */ - public void decrementResourceCount(long accountId, ResourceType type, Long...delta); - - /** - * Checks if a limit has been exceeded for an account - * @param account - * @param type - * @param count the number of resources being allocated, count will be added to current allocation and compared against maximum allowed allocation - * @return true if the limit has been exceeded - */ - public boolean resourceLimitExceeded(Account account, ResourceCount.ResourceType type, long...count); - - /** - * Gets the count of resources for a resource type and account - * @param account - * @param type - * @return count of resources - */ - public long getResourceCount(AccountVO account, ResourceType type); - /** * Disables an account by accountId * @param accountId @@ -125,9 +48,43 @@ public interface AccountManager extends AccountService { boolean cleanupAccount(AccountVO account, long callerUserId, Account caller); - @Override - UserVO createUser(CreateUserCmd cmd); - Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId); + + Account createAccount(String accountName, short accountType, Long domainId, String networkDomain); + + UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone); + + /** + * Logs out a user + * @param userId + */ + void logoutUser(Long userId); + UserAccount getUserAccount(String username, Long domainId); + + /** + * Authenticates a user when s/he logs in. + * + * @param username + * required username for authentication + * @param password + * password to use for authentication, can be null for single sign-on case + * @param domainId + * id of domain where user with username resides + * @param requestParameters + * the request parameters of the login request, which should contain timestamp of when the request signature is + * made, and the signature itself in the single sign-on case + * @return a user object, null if the user failed to authenticate + */ + UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters); + + /** + * Locate a user by their apiKey + * + * @param apiKey + * that was created for a particular user + * @return the user/account pair if one exact match was found, null otherwise + */ + Pair findUserByApiKey(String apiKey); + } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 73f5515b951..946ea1942e9 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -18,60 +18,51 @@ package com.cloud.user; +import java.net.URLEncoder; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import com.cloud.acl.ControlledEntity; import com.cloud.acl.SecurityChecker; import com.cloud.acl.SecurityChecker.AccessType; -import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; -import com.cloud.api.commands.CreateAccountCmd; -import com.cloud.api.commands.CreateDomainCmd; -import com.cloud.api.commands.CreateUserCmd; -import com.cloud.api.commands.DeleteAccountCmd; import com.cloud.api.commands.DeleteUserCmd; -import com.cloud.api.commands.DisableAccountCmd; -import com.cloud.api.commands.DisableUserCmd; -import com.cloud.api.commands.EnableAccountCmd; -import com.cloud.api.commands.EnableUserCmd; -import com.cloud.api.commands.LockUserCmd; +import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.UpdateAccountCmd; -import com.cloud.api.commands.UpdateResourceCountCmd; import com.cloud.api.commands.UpdateUserCmd; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceCount.ResourceType; -import com.cloud.configuration.ResourceCountVO; import com.cloud.configuration.ResourceLimit; -import com.cloud.configuration.ResourceLimit.OwnerType; -import com.cloud.configuration.ResourceLimitVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceCountDao; -import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; -import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; +import com.cloud.event.EventUtils; import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.CloudAuthenticationException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; @@ -81,13 +72,13 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.RemoteAccessVpnVO; import com.cloud.network.VpnUserVO; -import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.vpn.RemoteAccessVpnService; +import com.cloud.server.auth.UserAuthenticator; import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; @@ -110,10 +101,7 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -138,10 +126,6 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Inject ConfigurationDao _configDao; @Inject - private DomainDao _domainDao; - @Inject - private ResourceLimitDao _resourceLimitDao; - @Inject private ResourceCountDao _resourceCountDao; @Inject private UserDao _userDao; @@ -162,8 +146,6 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Inject private VMInstanceDao _vmDao; @Inject - private IPAddressDao _ipAddressDao; - @Inject protected SnapshotDao _snapshotDao; @Inject protected VMTemplateDao _vmTemplateDao; @@ -192,12 +174,11 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private VpnUserDao _vpnUser; @Inject private DataCenterDao _dcDao; - @Inject - private AlertManager _alertMgr; + @Inject + private DomainManager _domainMgr; + private Adapters _userAuthenticators; private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker")); - - protected SearchBuilder ResourceCountSearch; UserVO _systemUser; AccountVO _systemAccount; @@ -226,11 +207,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag String value = configs.get(Config.AccountCleanupInterval.key()); _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 hour. - ResourceCountSearch = _resourceCountDao.createSearchBuilder(); - ResourceCountSearch.and("id", ResourceCountSearch.entity().getId(), SearchCriteria.Op.IN); - ResourceCountSearch.and("accountId", ResourceCountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ); - ResourceCountSearch.done(); + _userAuthenticators = locator.getAdapters(UserAuthenticator.class); + if (_userAuthenticators == null || !_userAuthenticators.isSet()) { + s_logger.error("Unable to find an user authenticator."); + } return true; } @@ -256,513 +236,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag return true; } - @Override - public void incrementResourceCount(long accountId, ResourceType type, Long... delta) { - //don't upgrade resource count for system account - if (accountId == Account.ACCOUNT_ID_SYSTEM) { - s_logger.trace("Not incrementing resource count for system accounts, returning"); - return; - } - long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue(); - if (!updateResourceCount(accountId, type, true, numToIncrement)) { - //we should fail the operation (resource creation) when failed to update the resource count - throw new CloudRuntimeException("Failed to increment resource count of type " + type + " for account id=" + accountId); - } - } - - @Override - public void decrementResourceCount(long accountId, ResourceType type, Long... delta) { - //don't upgrade resource count for system account - if (accountId == Account.ACCOUNT_ID_SYSTEM) { - s_logger.trace("Not decrementing resource count for system accounts, returning"); - return; - } - long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue(); - - if (!updateResourceCount(accountId, type, false, numToDecrement)) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId, - "Failed to decrement resource count of type " + type + " for account id=" + accountId + "; use updateResourceCount API to recalculate/fix the problem"); - } - } - - @Override - public long findCorrectResourceLimit(long accountId, ResourceType type) { - long max = -1; - - ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(accountId, type); - - // Check if limit is configured for account - if (limit != null) { - max = limit.getMax().longValue(); - } else { - // 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."); - } - } - - return max; - } - - @Override - public long findCorrectResourceLimit(DomainVO domain, ResourceType type) { - long max = -1; - - // Check account - ResourceLimitVO limit = _resourceLimitDao.findByDomainIdAndType(domain.getId(), type); - - if (limit != null) { - max = limit.getMax().longValue(); - } else { - // check domain hierarchy - Long domainId = domain.getParent(); - while ((domainId != null) && (limit == null)) { - limit = _resourceLimitDao.findByDomainIdAndType(domainId, type); - DomainVO tmpDomain = _domainDao.findById(domainId); - domainId = tmpDomain.getParent(); - } - - if (limit != null) { - max = limit.getMax().longValue(); - } - } - - return max; - } - - @Override @DB - public boolean resourceLimitExceeded(Account account, ResourceType type, long... count) { - long numResources = ((count.length == 0) ? 1 : count[0]); - - // Don't place any limits on system or admin accounts - if (isAdmin(account.getType())) { - return false; - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - //Lock all rows first so nobody else can read it - Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdateForAccount(account.getId(), account.getDomainId(), type); - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowIdsToLock.toArray()); - _resourceCountDao.lockRows(sc, null, true); - - // Check account limits - long accountLimit = findCorrectResourceLimit(account.getId(), type); - long potentialCount = _resourceCountDao.getAccountCount(account.getId(), type) + numResources; - if (accountLimit != -1 && potentialCount > accountLimit) { - return true; - } - - // check all domains in the account's domain hierarchy - Long domainId = account.getDomainId(); - while (domainId != null) { - ResourceLimitVO domainLimit = _resourceLimitDao.findByDomainIdAndType(domainId, type); - if (domainLimit != null) { - long domainCount = _resourceCountDao.getDomainCount(domainId, type); - if ((domainCount + numResources) > domainLimit.getMax().longValue()) { - return true; - } - } - DomainVO domain = _domainDao.findById(domainId); - domainId = domain.getParent(); - } - - return false; - } finally { - txn.commit(); - } - } - - @Override - public long getResourceCount(AccountVO account, ResourceType type) { - return _resourceCountDao.getAccountCount(account.getId(), type); - } - - - @Override - public List searchForLimits(Long id, String accountName, Long domainId, Integer type, Long startIndex, Long pageSizeVal) { - Account caller = UserContext.current().getCaller(); - List limits = new ArrayList(); - boolean isAccount = true; - - Long accountId = null; - - if (!isAdmin(caller.getType())) { - accountId = caller.getId(); - domainId = null; - } else { - if (domainId != null) { - //verify domain information and permissions - Domain domain = _domainDao.findById(domainId); - if (domain == null) { - //return empty set - return limits; - } - - checkAccess(caller, domain); - - if (accountName != null) { - //Verify account information and permissions - Account account = _accountDao.findAccount(accountName, domainId); - if (account == null) { - //return empty set - return limits; - } - - checkAccess(caller, null, account); - - accountId = account.getId(); - domainId = null; - } - } - } - - // Map resource type - ResourceType resourceType = null; - if (type != null) { - try { - resourceType = ResourceType.values()[type]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidParameterValueException("Please specify a valid resource type."); - } - } - - //If id is passed in, get the record and return it if permission check has passed - if (id != null) { - ResourceLimitVO vo = _resourceLimitDao.findById(id); - if (vo.getAccountId() != null) { - checkAccess(caller, null, _accountDao.findById(vo.getAccountId())); - limits.add(vo); - } else if (vo.getDomainId() != null) { - checkAccess(caller, _domainDao.findById(vo.getDomainId())); - limits.add(vo); - } - - return limits; - } - - - //If account is not specified, default it to caller account - if (accountId == null) { - if (domainId == null) { - accountId = caller.getId(); - isAccount = true; - } else { - isAccount = false; - } - } else { - isAccount = true; - } - - SearchBuilder sb = _resourceLimitDao.createSearchBuilder(); - sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); - sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); - sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); - - SearchCriteria sc = sb.create(); - Filter filter = new Filter(ResourceLimitVO.class, "id", true, startIndex, pageSizeVal); - - if (accountId != null) { - sc.setParameters("accountId", accountId); - } - - if (domainId != null) { - sc.setParameters("domainId", domainId); - sc.setParameters("accountId", null); - } - - if (resourceType != null) { - sc.setParameters("type", resourceType); - } - - List foundLimits = _resourceLimitDao.search(sc, filter); - - if (resourceType != null) { - if (foundLimits.isEmpty()) { - if (isAccount) { - limits.add(new ResourceLimitVO(null, accountId, resourceType, findCorrectResourceLimit(accountId, resourceType))); - } else { - limits.add(new ResourceLimitVO(domainId, null, resourceType, findCorrectResourceLimit(_domainDao.findById(domainId), resourceType))); - } - } else { - limits.addAll(foundLimits); - } - } else { - limits.addAll(foundLimits); - - //see if any limits are missing from the table, and if yes - get it from the config table and add - ResourceType[] resourceTypes = ResourceCount.ResourceType.values(); - if (foundLimits.size() != resourceTypes.length) { - List accountLimitStr = new ArrayList(); - List domainLimitStr = new ArrayList(); - for (ResourceLimitVO foundLimit : foundLimits) { - if (foundLimit.getAccountId() != null) { - accountLimitStr.add(foundLimit.getType().toString()); - } else { - domainLimitStr.add(foundLimit.getType().toString()); - } - } - - //get default from config values - if (isAccount) { - if (accountLimitStr.size() < resourceTypes.length) { - for (ResourceType rt : resourceTypes) { - if (!accountLimitStr.contains(rt.toString())) { - limits.add(new ResourceLimitVO(null, accountId, rt, findCorrectResourceLimit(accountId, rt))); - } - } - } - - } else { - if (domainLimitStr.size() < resourceTypes.length) { - for (ResourceType rt : resourceTypes) { - if (!domainLimitStr.contains(rt.toString())) { - limits.add(new ResourceLimitVO(domainId, null, rt, findCorrectResourceLimit(_domainDao.findById(domainId), rt))); - } - } - } - } - } - } - - return limits; - } - - @Override - public ResourceLimitVO updateResourceLimit(String accountName, Long domainId, int typeId, Long max) { - Account caller = UserContext.current().getCaller(); - Long ownerId = null; - OwnerType ownerType = OwnerType.Account; - - if (max == null) { - max = new Long(-1); - } else if (max < -1) { - throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'."); - } - - // Map resource type - ResourceType resourceType = null; - try { - resourceType = ResourceType.values()[typeId]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidParameterValueException("Please specify a valid resource type."); - } - - //check permisions - if (domainId != null) { - //verify domain information and permissions - Domain domain = _domainDao.findById(domainId); - if (domain == null) { - throw new InvalidParameterValueException("Unable to find domain by id " + domainId); - } - - checkAccess(caller, domain); - - if (accountName != null) { - //Verify account information and permissions - Account account = _accountDao.findAccount(accountName, domainId); - - checkAccess(caller, null, account); - - if (account.getType() == Account.ACCOUNT_ID_SYSTEM) { - throw new InvalidParameterValueException("Can't update system account"); - } - - ownerId = account.getId(); - } else { - if ((caller.getDomainId() == domainId.longValue()) && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - // if the admin is trying to update their own domain, disallow... - throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied"); - } - - Long parentDomainId = domain.getParent(); - if (parentDomainId != null) { - DomainVO parentDomain = _domainDao.findById(parentDomainId); - long parentMaximum = findCorrectResourceLimit(parentDomain, resourceType); - if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) { - throw new InvalidParameterValueException("Domain (id: " + domainId + ") has maximum allowed resource limit " + parentMaximum + " for " + resourceType - + ", please specify a value less that or equal to " + parentMaximum); - } - } - - ownerId = domain.getId(); - ownerType = OwnerType.Domain; - } - } - - ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(ownerId, ownerType, resourceType); - if (limit != null) { - // Update the existing limit - _resourceLimitDao.update(limit.getId(), max); - return _resourceLimitDao.findById(limit.getId()); - } else { - if (ownerType == OwnerType.Account) { - return _resourceLimitDao.persist(new ResourceLimitVO(null, ownerId, resourceType, max)); - } else { - return _resourceLimitDao.persist(new ResourceLimitVO(ownerId, null, resourceType, max)); - } - } - } - - @Override @DB - public long updateAccountResourceCount(long accountId, ResourceType type) { - Long count=null; - - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table - // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("accountId", accountId); - _resourceCountDao.lockRows(sc, null, true); - - switch (type) { - case user_vm: - count = _userVmDao.countAllocatedVMsForAccount(accountId); - break; - case volume: - count = _volumeDao.countAllocatedVolumesForAccount(accountId); - long virtualRouterCount = _vmDao.countAllocatedVirtualRoutersForAccount(accountId); - count = count - virtualRouterCount; // don't count the volumes of virtual router - break; - case snapshot: - count = _snapshotDao.countSnapshotsForAccount(accountId); - break; - case public_ip: - count = _ipAddressDao.countAllocatedIPsForAccount(accountId); - break; - case template: - count = _vmTemplateDao.countTemplatesForAccount(accountId); - break; - } - _resourceCountDao.setAccountCount(accountId, type, (count == null) ? 0 : count.longValue()); - } catch (Exception e) { - throw new CloudRuntimeException("Failed to update resource count for account with Id" + accountId); - } finally { - txn.commit(); - } - - return (count==null)?0:count.longValue(); - } - - @Override @DB - public long updateDomainResourceCount(long domainId, ResourceType type) { - long count=0; - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - try { - //Lock all rows first so nobody else can read it - Set rowIdsToLock = _resourceCountDao.listRowsToUpdateForDomain(domainId, type); - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowIdsToLock.toArray()); - _resourceCountDao.lockRows(sc, null, true); - - List domainChildren = _domainDao.findImmediateChildrenForParent(domainId); - // for each child domain update the resource count - for (DomainVO domainChild : domainChildren) { - long domainCount = updateDomainResourceCount(domainChild.getId(), type); - count = count + domainCount; // add the child domain count to parent domain count - } - - List accounts = _accountDao.findActiveAccountsForDomain(domainId); - for (AccountVO account : accounts) { - long accountCount = updateAccountResourceCount(account.getId(), type); - count = count + accountCount; // add account's resource count to parent domain count - } - - _resourceCountDao.setDomainCount(domainId, type, count); - } catch (Exception e) { - throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId); - } finally { - txn.commit(); - } - - return count; - } - - @Override - public List updateResourceCount(UpdateResourceCountCmd cmd) throws InvalidParameterValueException, CloudRuntimeException, PermissionDeniedException{ - Account callerAccount = UserContext.current().getCaller(); - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - Long accountId = null; - long count=0; - List counts = new ArrayList(); - List resourceTypes = new ArrayList(); - - ResourceType resourceType=null; - Integer typeId = cmd.getResourceType(); - - if (typeId != null) { - try { - resourceType = ResourceType.values()[typeId]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidParameterValueException("Please specify a valid resource type."); - } - } - - DomainVO domain = _domainDao.findById(domainId); - if (domain == null) { - throw new InvalidParameterValueException("Please specify a valid domain ID."); - } - checkAccess(callerAccount, domain); - - if (accountName != null) { - Account userAccount = _accountDao.findActiveAccount(accountName, domainId); - if (userAccount == null) { - throw new InvalidParameterValueException("unable to find account by name " + accountName + " in domain with id " + domainId); - } - accountId = userAccount.getId(); - } - - try { - if (resourceType != null) { - resourceTypes.add(resourceType); - } else { - resourceTypes = Arrays.asList(ResourceType.values()); - } - - for (ResourceType type : resourceTypes) { - if (accountId != null) { - count = updateAccountResourceCount(accountId, type); - counts.add(new ResourceCountVO(accountId, domainId, type, count)); - } else { - count = updateDomainResourceCount(domainId, type); - counts.add(new ResourceCountVO(accountId, domainId, type, count)); - } - } - } catch (Exception e) { - throw new CloudRuntimeException(e.getMessage()); - } - - return counts; - } - - @Override public AccountVO getSystemAccount() { if (_systemAccount == null) { _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM); @@ -837,7 +311,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag for (Map.Entry> domain : domains.entrySet()) { for (SecurityChecker checker : _securityCheckers) { - Domain d = _domainDao.findById(domain.getKey()); + Domain d = _domainMgr.getDomain(domain.getKey()); if (d == null || d.getRemoved() != null) { throw new PermissionDeniedException("Domain is not found.", caller, domain.getValue()); } @@ -1120,48 +594,28 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag // /////////////////////////////////////////////////// @Override - @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account") @DB - public UserAccount createAccount(CreateAccountCmd cmd) { - Long accountId = null; - String username = cmd.getUsername(); - String password = cmd.getPassword(); - String firstName = cmd.getFirstname(); - String lastName = cmd.getLastname(); - Long domainId = cmd.getDomainId(); - String email = cmd.getEmail(); - String timezone = cmd.getTimezone(); - String accountName = cmd.getAccountName(); - short userType = cmd.getAccountType().shortValue(); - - String networkDomain = cmd.getNetworkDomain(); + public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain) { if (accountName == null) { - accountName = username; + accountName = userName; } if (domainId == null) { domainId = DomainVO.ROOT_DOMAIN; } - DomainVO domain = _domainDao.findById(domainId); - + //Validate domain + Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account"); - } + } + //Check permissions checkAccess(UserContext.current().getCaller(), domain); - Account account = _accountDao.findActiveAccount(accountName, domainId); - if (account != null) { - throw new InvalidParameterValueException("The specified account: " + account.getAccountName() + " already exists"); - } - if (domain.getState().equals(Domain.State.Inactive)) { - throw new CloudRuntimeException("The account cannot be created as domain " + domain.getName() + " is being deleted"); - } - - if (!_userAccountDao.validateUsernameInDomain(username, domainId)) { - throw new InvalidParameterValueException("The user " + username + " already exists in domain " + domainId); + if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) { + throw new InvalidParameterValueException("The user " + userName + " already exists in domain " + domainId); } if (networkDomain != null) { @@ -1174,140 +628,55 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Transaction txn = Transaction.currentTxn(); txn.start(); - - //Create account itself - if (accountId == null) { - if ((userType < Account.ACCOUNT_TYPE_NORMAL) || (userType > Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)) { - throw new InvalidParameterValueException("Invalid account type " + userType + " given; unable to create user"); - } - - // create a new account for the user - AccountVO newAccount = new AccountVO(); - if (domainId == null) { - // root domain is default - domainId = DomainVO.ROOT_DOMAIN; - } - - if ((domainId != DomainVO.ROOT_DOMAIN) && (userType == Account.ACCOUNT_TYPE_ADMIN)) { - throw new InvalidParameterValueException("Invalid account type " + userType + " given for an account in domain " + domainId + "; unable to create user."); - } - - newAccount.setAccountName(accountName); - newAccount.setDomainId(domainId); - newAccount.setType(userType); - newAccount.setState(State.enabled); - newAccount.setNetworkDomain(networkDomain); - newAccount = _accountDao.persist(newAccount); - accountId = newAccount.getId(); - } - - if (userType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - List dc = _dcDao.findZonesByDomainId(domainId); - if (dc == null || dc.size() == 0) { - throw new CloudRuntimeException("The account cannot be created as domain " + domain.getName() + " is not associated with any private Zone"); - } - } - if (accountId == null) { - throw new CloudRuntimeException("Failed to create account for user: " + username + "; unable to create user"); - } - - UserVO user = new UserVO(); - user.setUsername(username); - user.setPassword(password); - user.setState(State.enabled); - user.setFirstname(firstName); - user.setLastname(lastName); - user.setAccountId(accountId.longValue()); - user.setEmail(email); - user.setTimezone(timezone); - if(userType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN){ + //create account + Account account = createAccount(accountName, accountType, domainId, networkDomain); + long accountId = account.getId(); + + //create the first user for the account + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); + + if(accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN){ //set registration token - byte[] bytes = (domainId + accountName + username + System.currentTimeMillis()).getBytes(); + byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); user.setRegistrationToken(registrationToken); } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating user: " + username + ", account: " + accountName + " (id:" + accountId + "), domain: " + domainId + " timezone:" + timezone); - } - //Create resource count records for the account - _resourceCountDao.createResourceCounts(accountId, ResourceLimit.OwnerType.Account); - - //Create a user - UserVO dbUser = _userDao.persist(user); - - //Create default security group - _networkGroupMgr.createDefaultSecurityGroup(accountId); txn.commit(); - - if (!user.getPassword().equals(dbUser.getPassword())) { - throw new CloudRuntimeException("The user " + username + " being creating is using a password that is different than what's in the db"); - } - return _userAccountDao.findById(dbUser.getId()); - + return _userAccountDao.findById(account.getId()); } @Override - @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") - public UserVO createUser(CreateUserCmd cmd) { - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - String userName = cmd.getUsername(); - String password = cmd.getPassword(); - String firstName = cmd.getFirstname(); - String lastName = cmd.getLastname(); - String email = cmd.getEmail(); - String timeZone = cmd.getTimezone(); - Long accountId = null; + public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId) { // default domain to ROOT if not specified if (domainId == null) { domainId = Domain.ROOT_DOMAIN; } - DomainVO domain = _domainDao.findById(domainId); + + Domain domain = _domainMgr.getDomain(domainId); + if (domain == null) { + throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user"); + } else if (domain.getState().equals(Domain.State.Inactive)) { + throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted"); + } + checkAccess(UserContext.current().getCaller(), domain); + Account account = _accountDao.findActiveAccount(accountName, domainId); - if (account == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user"); - } else { - accountId = account.getAccountId(); - } - - if (domain == null) { - throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user"); - } else { - if (domain.getState().equals(Domain.State.Inactive)) { - throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted"); - } - } + } if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) { throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId); } - UserVO user = new UserVO(); - user.setUsername(userName); - user.setPassword(password); - user.setState(State.enabled); - user.setFirstname(firstName); - user.setLastname(lastName); - user.setAccountId(accountId.longValue()); - user.setEmail(email); - user.setTimezone(timeZone); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating user: " + userName + ", account: " + accountName + " (id:" + accountId + "), domain: " + domainId + " timezone:" + timeZone); - } + UserVO user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone); - UserVO dbUser = _userDao.persist(user); - - if (!user.getPassword().equals(dbUser.getPassword())) { - throw new CloudRuntimeException("The user " + userName + " being creating is using a password that is different than what's in the db"); - } - - return dbUser; + return user; } @Override @@ -1408,9 +777,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_USER_DISABLE, eventDescription = "disabling User", async = true) - public UserAccount disableUser(DisableUserCmd cmd) { - Long userId = cmd.getId(); - Account adminAccount = UserContext.current().getCaller(); + public UserAccount disableUser(long userId) { + Account caller = UserContext.current().getCaller(); // Check if user exists in the system User user = _userDao.findById(userId); @@ -1423,10 +791,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if ((account != null) && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { throw new InvalidParameterValueException("User id : " + userId + " is a system user, disabling is not allowed"); } - - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { - throw new PermissionDeniedException("Failed to disable user " + userId + ", permission denied."); - } + + checkAccess(caller, null, account); boolean success = doSetUserStatus(userId, State.disabled); if (success) { @@ -1439,10 +805,9 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User") - public UserAccount enableUser(EnableUserCmd cmd) { - Long userId = cmd.getId(); - Account adminAccount = UserContext.current().getCaller(); - boolean success = false; + public UserAccount enableUser(long userId) { + + Account caller = UserContext.current().getCaller(); // Check if user exists in the system User user = _userDao.findById(userId); @@ -1456,11 +821,9 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag throw new InvalidParameterValueException("User id : " + userId + " is a system user, enabling is not allowed"); } - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { - throw new PermissionDeniedException("Failed to enable user " + userId + ", permission denied."); - } + checkAccess(caller, null, account); - success = doSetUserStatus(userId, State.enabled); + boolean success = doSetUserStatus(userId, State.enabled); // make sure the account is enabled too success = (success && enableAccount(user.getAccountId())); @@ -1474,35 +837,29 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_USER_LOCK, eventDescription = "locking User") - public UserAccount lockUser(LockUserCmd cmd) { - boolean success = false; - - Account adminAccount = UserContext.current().getCaller(); - Long id = cmd.getId(); + public UserAccount lockUser(long userId) { + Account caller = UserContext.current().getCaller(); // Check if user with id exists in the system - User user = _userDao.findById(id); - if (user == null) { + User user = _userDao.findById(userId); + if (user == null || user.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find user by id"); - } else if (user.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find user by id"); - } - + } // If the user is a System user, return an error. We do not allow this Account account = _accountDao.findById(user.getAccountId()); if ((account != null) && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { - throw new PermissionDeniedException("user id : " + id + " is a system user, locking is not allowed"); + throw new PermissionDeniedException("user id : " + userId + " is a system user, locking is not allowed"); } + + checkAccess(caller, null, account); - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { - throw new PermissionDeniedException("Failed to lock user " + id + ", permission denied."); - } // make sure the account is enabled too // if the user is either locked already or disabled already, don't change state...only lock currently enabled users + boolean success = true; if (user.getState().equals(State.locked)) { // already locked...no-op - return _userAccountDao.findById(id); + return _userAccountDao.findById(userId); } else if (user.getState().equals(State.enabled)) { success = doSetUserStatus(user.getId(), State.locked); @@ -1522,58 +879,52 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (s_logger.isInfoEnabled()) { s_logger.info("Attempting to lock a non-enabled user, current state is " + user.getState() + " (userId: " + user.getId() + "), locking failed."); } + success = false; } if (success) { - return _userAccountDao.findById(id); + return _userAccountDao.findById(userId); } else { - throw new CloudRuntimeException("Unable to lock user " + id); + throw new CloudRuntimeException("Unable to lock user " + userId); } } @Override @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true) // This method deletes the account - public boolean deleteUserAccount(DeleteAccountCmd cmd) { + public boolean deleteUserAccount(long accountId) { UserContext ctx = UserContext.current(); long callerUserId = ctx.getCallerUserId(); Account caller = ctx.getCaller(); - - Long accountId = cmd.getId(); - + // If the user is a System user, return an error. We do not allow this AccountVO account = _accountDao.findById(accountId); - checkAccess(UserContext.current().getCaller(), null, account); - if ((account != null) && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { - throw new PermissionDeniedException("Account id : " + accountId + " is a system account, delete is not allowed"); - } - + if (account == null) { throw new InvalidParameterValueException("The specified account does not exist in the system"); } - + + checkAccess(caller, null, account); + if (account.getRemoved() != null) { s_logger.info("The account:" + account.getAccountName() + " is already removed"); return true; } - - if(!deleteAccount(account, callerUserId, caller)){ - throw new CloudRuntimeException("Unable to delete account " + account.getAccountName() + " in domain " + account.getDomainId()); + + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { + throw new PermissionDeniedException("Account id : " + accountId + " is a system account, delete is not allowed"); } - return true; + + return deleteAccount(account, callerUserId, caller); } @Override - public AccountVO enableAccount(EnableAccountCmd cmd) { - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - boolean success = false; - Account account = _accountDao.findActiveAccount(accountName, domainId); - + public AccountVO enableAccount(String accountName, long domainId) { + // Check if account exists + Account account = _accountDao.findActiveAccount(accountName, domainId); if (account == null) { - s_logger.error("Unable to find account " + accountName + " in domain " + domainId); throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } @@ -1583,12 +934,11 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } // Check if user performing the action is allowed to modify this account - Account adminAccount = UserContext.current().getCaller(); - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { - throw new PermissionDeniedException("Invalid account " + accountName + " in domain " + domainId + " given, permission denied"); - } + Account caller = UserContext.current().getCaller(); + checkAccess(caller, null, account); + - success = enableAccount(account.getId()); + boolean success = enableAccount(account.getId()); if (success) { return _accountDao.findById(account.getId()); } else { @@ -1598,20 +948,16 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "locking account", async = true) - public AccountVO lockAccount(DisableAccountCmd cmd) { - Account adminAccount = UserContext.current().getCaller(); - Long domainId = cmd.getDomainId(); - String accountName = cmd.getAccountName(); - - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), domainId)) { - throw new PermissionDeniedException("Failed to lock account " + accountName + " in domain " + domainId + ", permission denied."); - } - + public AccountVO lockAccount(String accountName, Long domainId) { + Account caller = UserContext.current().getCaller(); + Account account = _accountDao.findActiveAccount(accountName, domainId); if (account == null) { throw new InvalidParameterValueException("Unable to find active account with name " + accountName + " in domain " + domainId); } - + + checkAccess(caller, null, account); + // don't allow modify system account if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new InvalidParameterValueException("can not lock system account"); @@ -1626,19 +972,16 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "disabling account", async = true) - public AccountVO disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - - Account adminAccount = UserContext.current().getCaller(); - if ((adminAccount != null) && !_domainDao.isChildDomain(adminAccount.getDomainId(), domainId)) { - throw new PermissionDeniedException("Failed to disable account " + accountName + " in domain " + domainId + ", permission denied."); - } - + public AccountVO disableAccount(String accountName, Long domainId) throws ConcurrentOperationException, ResourceUnavailableException { + Account caller = UserContext.current().getCaller(); + Account account = _accountDao.findActiveAccount(accountName, domainId); if (account == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } + + checkAccess(caller, null, account); + if (disableAccount(account.getId())) { return _accountDao.findById(account.getId()); } else { @@ -1669,7 +1012,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag // Check if user performing the action is allowed to modify this account Account adminAccount = UserContext.current().getCaller(); - if ((adminAccount != null) && (adminAccount.getType() != Account.ACCOUNT_TYPE_ADMIN) && _domainDao.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { + if ((adminAccount != null) && (adminAccount.getType() != Account.ACCOUNT_TYPE_ADMIN) && _domainMgr.isChildDomain(adminAccount.getDomainId(), account.getDomainId())) { throw new PermissionDeniedException("Invalid account " + accountName + " in domain " + domainId + " given, permission denied"); } @@ -1785,15 +1128,15 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } //cleanup inactive domains - List inactiveDomains = _domainDao.findInactiveDomains(); + List inactiveDomains = _domainMgr.findInactiveDomains(); s_logger.info("Found " + inactiveDomains.size() + " inactive domains to cleanup"); - for (DomainVO inactiveDomain : inactiveDomains) { + for (Domain inactiveDomain : inactiveDomains) { long domainId = inactiveDomain.getId(); try { List accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId); if (accountsForCleanupInDomain.isEmpty()) { s_logger.debug("Removing inactive domain id=" + domainId); - _domainDao.remove(domainId); + _domainMgr.removeDomain(domainId); } else { s_logger.debug("Can't remove inactive domain id=" + domainId + " as it has accounts that need clenaup"); } @@ -1825,7 +1168,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } if (isAdmin(caller.getType()) && accountName != null && domainId != null) { - DomainVO domain = _domainDao.findById(domainId); + Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); } @@ -1853,7 +1196,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public Account getActiveAccount(String accountName, Long domainId) { + public Account getActiveAccountByName(String accountName, Long domainId) { if (accountName == null || domainId == null) { throw new InvalidParameterValueException("Both accountName and domainId are required for finding active account in the system"); } else { @@ -1862,7 +1205,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public Account getActiveAccount(Long accountId) { + public Account getActiveAccountById(Long accountId) { if (accountId == null) { throw new InvalidParameterValueException("AccountId is required by account search"); } else { @@ -1889,18 +1232,13 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag return _userDao.findByIdIncludingRemoved(userId); } - @Override - public Domain getDomain(long domainId) { - return _domainDao.findById(domainId); - } - @Override public Pair finalizeAccountDomainForList(Account caller, String accountName, Long domainId) { if (isAdmin(caller.getType())) { if (domainId == null && accountName != null) { throw new InvalidParameterValueException("accountName and domainId might be specified together"); } else if (domainId != null) { - Domain domain = getDomain(domainId); + Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); } @@ -1908,7 +1246,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag checkAccess(caller, domain); if (accountName != null) { - Account owner = getActiveAccount(accountName, domainId); + Account owner = getActiveAccountByName(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account with name " + accountName + " in domain id=" + domainId); } @@ -1937,85 +1275,29 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag userForUpdate.setRegistered(true); _userDao.update(Long.valueOf(userId), userForUpdate); } - - @Override - public Set getDomainParentIds(long domainId) { - return _domainDao.getDomainParentIds(domainId); - } - - @Override - public Set getDomainChildrenIds(String parentDomainPath) { - Set childDomains = new HashSet(); - SearchCriteria sc = _domainDao.createSearchCriteria(); - sc.addAnd("path", SearchCriteria.Op.LIKE, parentDomainPath + "%"); - - List domains = _domainDao.search(sc, null); - - for (DomainVO domain : domains) { - childDomains.add(domain.getId()); - } - - return childDomains; - } - - @DB - public boolean updateResourceCount(long accountId, ResourceType type, boolean increment, long delta) { - boolean result = true; - try { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Set rowsToLock = _resourceCountDao.listAllRowsToUpdateForAccount(accountId, getAccount(accountId).getDomainId(), type); - - //Lock rows first - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowsToLock.toArray()); - List rowsToUpdate = _resourceCountDao.lockRows(sc, null, true); - - for (ResourceCountVO rowToUpdate : rowsToUpdate) { - if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) { - s_logger.trace("Unable to update resource count for the row " + rowToUpdate); - result = false; - } - } - - txn.commit(); - } catch (Exception ex) { - s_logger.error("Failed to update resource count for account id=" + accountId); - result = false; - } - return result; - } - - @Override - @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_CREATE, eventDescription = "creating Domain") - @DB - public Domain createDomain(CreateDomainCmd cmd) { - String name = cmd.getDomainName(); - Long parentId = cmd.getParentDomainId(); - Long ownerId = UserContext.current().getCaller().getId(); - Account caller = UserContext.current().getCaller(); - String networkDomain = cmd.getNetworkDomain(); - - if (ownerId == null) { - ownerId = Long.valueOf(1); - } - - if (parentId == null) { - parentId = Long.valueOf(DomainVO.ROOT_DOMAIN); - } - - DomainVO parentDomain = _domainDao.findById(parentId); - if (parentDomain == null) { - throw new InvalidParameterValueException("Unable to create domain " + name + ", parent domain " + parentId + " not found."); + + @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account") + public Account createAccount(String accountName, short accountType, Long domainId, String networkDomain) { + //Validate domain + Domain domain = _domainMgr.getDomain(domainId); + if (domain == null) { + throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account"); + } + + if (domain.getState().equals(Domain.State.Inactive)) { + throw new CloudRuntimeException("The account cannot be created as domain " + domain.getName() + " is being deleted"); } - if (parentDomain.getState().equals(Domain.State.Inactive)) { - throw new CloudRuntimeException("The domain cannot be created as the parent domain " + parentDomain.getName() + " is being deleted"); + if ((domainId != DomainVO.ROOT_DOMAIN) && (accountType == Account.ACCOUNT_TYPE_ADMIN)) { + throw new InvalidParameterValueException("Invalid account type " + accountType + " given for an account in domain " + domainId + "; unable to create user."); + } + + //Validate account/user/domain settings + if ( _accountDao.findActiveAccount(accountName, domainId) != null) { + throw new InvalidParameterValueException("The specified account: " + accountName + " already exists"); } - checkAccess(caller, parentDomain); - if (networkDomain != null) { if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( @@ -2023,28 +1305,306 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag + "and the hyphen ('-'); can't start or end with \"-\""); } } - - SearchCriteria sc = _domainDao.createSearchCriteria(); - sc.addAnd("name", SearchCriteria.Op.EQ, name); - sc.addAnd("parent", SearchCriteria.Op.EQ, parentId); - List domains = _domainDao.search(sc, null); - if ((domains == null) || domains.isEmpty()) { - DomainVO domain = new DomainVO(name, ownerId, parentId, networkDomain); - try { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - domain = _domainDao.create(domain); - _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.OwnerType.Domain); - - txn.commit(); - return domain; - } catch (IllegalArgumentException ex) { - s_logger.warn("Failed to create domain ", ex); - throw ex; + + //Verify account type + if ((accountType < Account.ACCOUNT_TYPE_NORMAL) || (accountType > Account.ACCOUNT_TYPE_PROJECT)) { + throw new InvalidParameterValueException("Invalid account type " + accountType + " given; unable to create user"); + } + + if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + List dc = _dcDao.findZonesByDomainId(domainId); + if (dc.isEmpty()) { + throw new InvalidParameterValueException("The account cannot be created as domain " + domain.getName() + " is not associated with any private Zone"); } + } + + //Create the account + Transaction txn = Transaction.currentTxn(); + txn.start(); + + Account account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType)); + + if (account == null) { + throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); + } + + Long accountId = account.getId(); + + //Create resource count records for the account + _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account); + + //Create default security group + _networkGroupMgr.createDefaultSecurityGroup(accountId); + + + txn.commit(); + + return account; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); + } + UserVO user = _userDao.persist(new UserVO(accountId, userName, password, firstName, lastName, email, timezone)); + + return user; + } + + + @Override + public void logoutUser(Long userId) { + UserAccount userAcct = _userAccountDao.findById(userId); + if (userAcct != null) { + EventUtils.saveEvent(userId, userAcct.getAccountId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out"); + } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted... + } + + @Override + public UserAccount getUserAccount(String username, Long domainId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Retrieiving user: " + username + " in domain " + domainId); + } + + UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); + if (userAccount == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find user with name " + username + " in domain " + domainId); + } + return null; + } + + return userAccount; + } + + @Override + public UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters) { + UserAccount user = null; + if (password != null) { + user = getUserAccount(username, password, domainId); } else { - throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId); + String key = _configDao.getValue("security.singlesignon.key"); + if (key == null) { + // the SSO key is gone, don't authenticate + return null; + } + + String singleSignOnTolerance = _configDao.getValue("security.singlesignon.tolerance.millis"); + if (singleSignOnTolerance == null) { + // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be valid), + // don't authenticate + return null; + } + + long tolerance = Long.parseLong(singleSignOnTolerance); + String signature = null; + long timestamp = 0L; + String unsignedRequest = null; + + // - build a request string with sorted params, make sure it's all lowercase + // - sign the request, verify the signature is the same + List parameterNames = new ArrayList(); + + for (Object paramNameObj : requestParameters.keySet()) { + parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later + } + + Collections.sort(parameterNames); + + try { + for (String paramName : parameterNames) { + // parameters come as name/value pairs in the form String/String[] + String paramValue = ((String[]) requestParameters.get(paramName))[0]; + + if ("signature".equalsIgnoreCase(paramName)) { + signature = paramValue; + } else { + if ("timestamp".equalsIgnoreCase(paramName)) { + String timestampStr = paramValue; + try { + // If the timestamp is in a valid range according to our tolerance, verify the request + // signature, otherwise return null to indicate authentication failure + timestamp = Long.parseLong(timestampStr); + long currentTime = System.currentTimeMillis(); + if (Math.abs(currentTime - timestamp) > tolerance) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expired timestamp passed in to login, current time = " + currentTime + ", timestamp = " + timestamp); + } + return null; + } + } catch (NumberFormatException nfe) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Invalid timestamp passed in to login: " + timestampStr); + } + return null; + } + } + + if (unsignedRequest == null) { + unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); + } else { + unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); + } + } + } + + if ((signature == null) || (timestamp == 0L)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Missing parameters in login request, signature = " + signature + ", timestamp = " + timestamp); + } + return null; + } + + unsignedRequest = unsignedRequest.toLowerCase(); + + Mac mac = Mac.getInstance("HmacSHA1"); + SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1"); + mac.init(keySpec); + mac.update(unsignedRequest.getBytes()); + byte[] encryptedBytes = mac.doFinal(); + String computedSignature = new String(Base64.encodeBase64(encryptedBytes)); + boolean equalSig = signature.equals(computedSignature); + if (!equalSig) { + s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature); + } else { + user = _userAccountDao.getUserAccount(username, domainId); + } + } catch (Exception ex) { + s_logger.error("Exception authenticating user", ex); + return null; + } + } + + if (user != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); + } + EventUtils.saveEvent(user.getId(), user.getAccountId(), EventTypes.EVENT_USER_LOGIN, "user has logged in"); + return user; + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("User: " + username + " in domain " + domainId + " has failed to log in"); + } + return null; } } + + private UserAccount getUserAccount(String username, String password, Long domainId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Attempting to log in user: " + username + " in domain " + domainId); + } + + // We only use the first adapter even if multiple have been configured + Enumeration en = _userAuthenticators.enumeration(); + UserAuthenticator authenticator = en.nextElement(); + boolean authenticated = authenticator.authenticate(username, password, domainId); + + if (authenticated) { + UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); + if (userAccount == null) { + s_logger.warn("Unable to find an authenticated user with username " + username + " in domain " + domainId); + return null; + } + + Domain domain = _domainMgr.getDomain(domainId); + String domainName = null; + if (domain != null) { + domainName = domain.getName(); + } + + if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { + if (s_logger.isInfoEnabled()) { + s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)"); + } + throw new CloudAuthenticationException("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)"); + // return null; + } + return userAccount; + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to authenticate user with username " + username + " in domain " + domainId); + } + return null; + } + } + + @Override + public Pair findUserByApiKey(String apiKey) { + return _accountDao.findUserAccountByApiKey(apiKey); + } + + @Override + public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { + Long userId = cmd.getId(); + + if (getUser(userId) == null) { + throw new InvalidParameterValueException("unable to find user for id : " + userId); + } + + // generate both an api key and a secret key, update the user table with the keys, return the keys to the user + String[] keys = new String[2]; + keys[0] = createUserApiKey(userId); + keys[1] = createUserSecretKey(userId); + + return keys; + } + + private String createUserApiKey(long userId) { + try { + UserVO updatedUser = _userDao.createForUpdate(); + + String encodedKey = null; + Pair userAcct = null; + int retryLimit = 10; + do { + // FIXME: what algorithm should we use for API keys? + KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1"); + SecretKey key = generator.generateKey(); + encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded()); + userAcct = _accountDao.findUserAccountByApiKey(encodedKey); + retryLimit--; + } while ((userAcct != null) && (retryLimit >= 0)); + + if (userAcct != null) { + return null; + } + updatedUser.setApiKey(encodedKey); + _userDao.update(userId, updatedUser); + return encodedKey; + } catch (NoSuchAlgorithmException ex) { + s_logger.error("error generating secret key for user id=" + userId, ex); + } + return null; + } + + private String createUserSecretKey(long userId) { + try { + UserVO updatedUser = _userDao.createForUpdate(); + String encodedKey = null; + int retryLimit = 10; + UserVO userBySecretKey = null; + do { + KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1"); + SecretKey key = generator.generateKey(); + encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded()); + userBySecretKey = _userDao.findUserBySecretKey(encodedKey); + retryLimit--; + } while ((userBySecretKey != null) && (retryLimit >= 0)); + + if (userBySecretKey != null) { + return null; + } + + updatedUser.setSecretKey(encodedKey); + _userDao.update(userId, updatedUser); + return encodedKey; + } catch (NoSuchAlgorithmException ex) { + s_logger.error("error generating secret key for user id=" + userId, ex); + } + return null; + } + + } diff --git a/server/src/com/cloud/user/DomainManager.java b/server/src/com/cloud/user/DomainManager.java new file mode 100644 index 00000000000..50ec2ade241 --- /dev/null +++ b/server/src/com/cloud/user/DomainManager.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.user; + +import java.util.List; +import java.util.Set; + +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; + +public interface DomainManager extends DomainService{ + Set getDomainChildrenIds(String parentDomainPath); + + Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, Domain.Type domainType); + + /** + * find the domain by its path + * + * @param domainPath + * the path to use to lookup a domain + * @return domainVO the domain with the matching path, or null if no domain with the given path exists + */ + DomainVO findDomainByPath(String domainPath); + + Set getDomainParentIds(long domainId); + + boolean removeDomain(long domainId); + + List findInactiveDomains(); +} diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java new file mode 100644 index 00000000000..23f99b25d02 --- /dev/null +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -0,0 +1,317 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.user; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.configuration.ResourceLimit; +import com.cloud.configuration.dao.ResourceCountDao; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; + +@Local(value = { DomainManager.class, DomainService.class }) +public class DomainManagerImpl implements DomainManager, DomainService, Manager{ + public static final Logger s_logger = Logger.getLogger(DomainManagerImpl.class); + + private String _name; + @Inject + private DomainDao _domainDao; + @Inject + private AccountManager _accountMgr; + @Inject + private ResourceCountDao _resourceCountDao; + @Inject + private AccountDao _accountDao; + @Inject + private DiskOfferingDao _diskOfferingDao; + @Inject + private ServiceOfferingDao _offeringsDao; + + @Override + public Domain getDomain(long domainId) { + return _domainDao.findById(domainId); + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _name = name; + + return true; + } + + @Override + public Set getDomainChildrenIds(String parentDomainPath) { + Set childDomains = new HashSet(); + SearchCriteria sc = _domainDao.createSearchCriteria(); + sc.addAnd("path", SearchCriteria.Op.LIKE, parentDomainPath + "%"); + + List domains = _domainDao.search(sc, null); + + for (DomainVO domain : domains) { + childDomains.add(domain.getId()); + } + + return childDomains; + } + + @Override + public boolean isChildDomain(Long parentId, Long childId) { + return _domainDao.isChildDomain(parentId, childId); + } + + @Override + @DB + public Domain createDomain(String name, Long parentId, String networkDomain) { + Account caller = UserContext.current().getCaller(); + + if (parentId == null) { + parentId = Long.valueOf(DomainVO.ROOT_DOMAIN); + } + + DomainVO parentDomain = _domainDao.findById(parentId); + if (parentDomain == null) { + throw new InvalidParameterValueException("Unable to create domain " + name + ", parent domain " + parentId + " not found."); + } + + if (parentDomain.getState().equals(Domain.State.Inactive)) { + throw new CloudRuntimeException("The domain cannot be created as the parent domain " + parentDomain.getName() + " is being deleted"); + } + + _accountMgr.checkAccess(caller, parentDomain); + + + return createDomain(name, parentId, caller.getId(), networkDomain, null); + + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_CREATE, eventDescription = "creating Domain") + @DB + public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, Domain.Type domainType) { + //Verify network domain + if (networkDomain != null) { + if (!NetUtils.verifyDomainName(networkDomain)) { + throw new InvalidParameterValueException( + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); + } + } + + //verify domainType + if (domainType != null && !(domainType == Domain.Type.Project || domainType == Domain.Type.Normal)) { + throw new InvalidParameterValueException("Invalid domain type; following values are supported: " + Domain.Type.Normal + ", " + Domain.Type.Project); + } + + SearchCriteria sc = _domainDao.createSearchCriteria(); + sc.addAnd("name", SearchCriteria.Op.EQ, name); + sc.addAnd("parent", SearchCriteria.Op.EQ, parentId); + List domains = _domainDao.search(sc, null); + + if (!domains.isEmpty()) { + throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainType)); + _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain); + + txn.commit(); + + return domain; + } + + @Override + public DomainVO findDomainByPath(String domainPath) { + return _domainDao.findDomainByPath(domainPath); + } + + @Override + public Set getDomainParentIds(long domainId) { + return _domainDao.getDomainParentIds(domainId); + } + + @Override + public boolean removeDomain(long domainId) { + return _domainDao.remove(domainId); + } + + @Override + public List findInactiveDomains() { + return _domainDao.findInactiveDomains(); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_DELETE, eventDescription = "deleting Domain", async = true) + public boolean deleteDomain(long domainId, Boolean cleanup) { + Account caller = UserContext.current().getCaller(); + + DomainVO domain = _domainDao.findById(domainId); + + if (domain == null) { + throw new InvalidParameterValueException("Failed to delete domain " + domainId + ", domain not found"); + } else if (domainId == DomainVO.ROOT_DOMAIN) { + throw new PermissionDeniedException("Can't delete ROOT domain"); + } + + _accountMgr.checkAccess(caller, domain); + + //mark domain as inactive + s_logger.debug("Marking domain id=" + domainId + " as " + Domain.State.Inactive + " before actually deleting it"); + domain.setState(Domain.State.Inactive); + _domainDao.update(domainId, domain); + + try { + long ownerId = domain.getAccountId(); + if ((cleanup != null) && cleanup.booleanValue()) { + if (!cleanupDomain(domainId, ownerId)) { + s_logger.error("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domainId + ")."); + return false; + } + } else { + List accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId); + if (accountsForCleanup.isEmpty()) { + if (!_domainDao.remove(domainId)) { + s_logger.error("Delete failed on domain " + domain.getName() + " (id: " + domainId + + "); please make sure all users and sub domains have been removed from the domain before deleting"); + return false; + } + } else { + s_logger.warn("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); + return false; + } + } + + cleanupDomainOfferings(domainId); + return true; + } catch (Exception ex) { + s_logger.error("Exception deleting domain with id " + domainId, ex); + return false; + } + } + + private void cleanupDomainOfferings(Long domainId) { + // delete the service and disk offerings associated with this domain + List diskOfferingsForThisDomain = _diskOfferingDao.listByDomainId(domainId); + for (DiskOfferingVO diskOffering : diskOfferingsForThisDomain) { + _diskOfferingDao.remove(diskOffering.getId()); + } + + List serviceOfferingsForThisDomain = _offeringsDao.findServiceOfferingByDomainId(domainId); + for (ServiceOfferingVO serviceOffering : serviceOfferingsForThisDomain) { + _offeringsDao.remove(serviceOffering.getId()); + } + } + + private boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException { + boolean success = true; + { + DomainVO domainHandle = _domainDao.findById(domainId); + domainHandle.setState(Domain.State.Inactive); + _domainDao.update(domainId, domainHandle); + + SearchCriteria sc = _domainDao.createSearchCriteria(); + sc.addAnd("parent", SearchCriteria.Op.EQ, domainId); + List domains = _domainDao.search(sc, null); + + SearchCriteria sc1 = _domainDao.createSearchCriteria(); + sc1.addAnd("path", SearchCriteria.Op.LIKE, "%" + domainHandle.getPath() + "%"); + List domainsToBeInactivated = _domainDao.search(sc1, null); + + // update all subdomains to inactive so no accounts/users can be created + for (DomainVO domain : domainsToBeInactivated) { + domain.setState(Domain.State.Inactive); + _domainDao.update(domain.getId(), domain); + } + + // cleanup sub-domains first + for (DomainVO domain : domains) { + success = (success && cleanupDomain(domain.getId(), domain.getAccountId())); + if (!success) { + s_logger.warn("Failed to cleanup domain id=" + domain.getId()); + } + } + } + + // delete users which will also delete accounts and release resources for those accounts + SearchCriteria sc = _accountDao.createSearchCriteria(); + sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId); + List accounts = _accountDao.search(sc, null); + for (AccountVO account : accounts) { + success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller())); + if (!success) { + s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup"); + } + } + + //don't remove the domain if there are accounts required cleanup + boolean deleteDomainSuccess = true; + List accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId); + if (accountsForCleanup.isEmpty()) { + deleteDomainSuccess = _domainDao.remove(domainId); + } else { + s_logger.debug("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); + } + + return success && deleteDomainSuccess; + } +} diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 08fc5bda36f..a62d9573681 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -29,7 +29,7 @@ import com.cloud.uservm.UserVm; * UserVmManager contains all of the code to work with user VMs. * */ -public interface UserVmManager extends VirtualMachineGuru{ +public interface UserVmManager extends VirtualMachineGuru, UserVmService{ static final int MAX_USER_DATA_LENGTH_BYTES = 2048; /** diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c9df2f1f31a..42684c73e5a 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -77,7 +77,7 @@ import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ResourceCount.ResourceType; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; @@ -178,6 +178,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.SSHKeyPair; import com.cloud.user.User; import com.cloud.user.UserContext; @@ -337,6 +338,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; @Inject protected VMInstanceDao _vmInstanceDao; + @Inject + protected ResourceLimitService _resourceLimitMgr; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -1076,7 +1079,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } // First check that the maximum number of UserVMs for the given accountId will not be exceeded - if (_accountMgr.resourceLimitExceeded(account, ResourceType.user_vm)) { + if (_resourceLimitMgr.resourceLimitExceeded(account, ResourceType.user_vm)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of virtual machines for account: " + account.getAccountName() + " has been exceeded."); rae.setResourceType("vm"); txn.commit(); @@ -1114,9 +1117,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } - _accountMgr.incrementResourceCount(account.getId(), ResourceType.volume, new Long(volumes.size())); + _resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.volume, new Long(volumes.size())); - _accountMgr.incrementResourceCount(account.getId(), ResourceType.user_vm); + _resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.user_vm); txn.commit(); @@ -1394,7 +1397,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } AccountVO ownerAccount = _accountDao.findById(accountId); - if (_accountMgr.resourceLimitExceeded(ownerAccount, ResourceType.template)) { + if (_resourceLimitMgr.resourceLimitExceeded(ownerAccount, ResourceType.template)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded."); rae.setResourceType("template"); throw rae; @@ -1442,7 +1445,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager VMTemplateVO template = _templateDao.persist(privateTemplate); // Increment the number of templates if (template != null) { - _accountMgr.incrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.template); } return template; @@ -1639,7 +1642,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _templateDao.remove(templateId); // decrement resource count - _accountMgr.decrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); txn.commit(); } } @@ -1688,7 +1691,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager String msg = "Failed to deploy Vm with Id: " + vmId; _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), msg, msg); - _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); + _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); } } } @@ -2373,7 +2376,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } // check if account/domain is with in resource limits to create a new vm - if (_accountMgr.resourceLimitExceeded(owner, ResourceType.user_vm)) { + if (_resourceLimitMgr.resourceLimitExceeded(owner, ResourceType.user_vm)) { UserContext.current().setEventDetails("Maximum number of virtual machines for account: " + owner.getAccountName() + " has been exceeded."); ResourceAllocationException rae = new ResourceAllocationException("Maximum number of virtual machines for account: " + owner.getAccountName() + " has been exceeded."); rae.setResourceType("vm"); @@ -2557,7 +2560,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString()); _usageEventDao.persist(usageEvent); - _accountMgr.incrementResourceCount(accountId, ResourceType.user_vm); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); txn.commit(); // Assign instance to the group try { @@ -2950,7 +2953,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } if (vmState != State.Error) { - _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); + _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); } return _vmDao.findById(vmId); @@ -3324,7 +3327,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } //VV 2: check if account/domain is with in resource limits to create a new vm - if (_accountMgr.resourceLimitExceeded(newAccount, ResourceType.user_vm)) { + if (_resourceLimitMgr.resourceLimitExceeded(newAccount, ResourceType.user_vm)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of virtual machines for account: " + newAccount.getAccountName() + " has been exceeded."); rae.setResourceType("vm"); throw rae; @@ -3353,7 +3356,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _accountMgr.checkAccess(newAccount, domain); DataCenterVO zone = _dcDao.findById(vm.getDataCenterIdToDeployIn()); - VMInstanceVO vmoi = _itMgr.findById(vm.getType(), vm.getId()); + VMInstanceVO vmoi = _itMgr.findByIdAndType(vm.getType(), vm.getId()); VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi); @@ -3417,7 +3420,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager networks.add(new Pair(network, null)); } - VMInstanceVO vmi = _itMgr.findById(vm.getType(), vm.getId()); + VMInstanceVO vmi = _itMgr.findByIdAndType(vm.getType(), vm.getId()); VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi); _networkMgr.allocate(vmProfile, networks); } diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 24d8a191c32..1d655b14577 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -109,7 +109,7 @@ public interface VirtualMachineManager extends Manager { T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; - VMInstanceVO findById(VirtualMachine.Type type, long vmId); + VMInstanceVO findByIdAndType(VirtualMachine.Type type, long vmId); /** * Check to see if a virtual machine can be upgraded to the given service offering @@ -119,5 +119,7 @@ public interface VirtualMachineManager extends Manager { * @return true if the host can handle the upgrade, false otherwise */ boolean isVirtualMachineUpgradable(final UserVm vm, final ServiceOffering offering); + + VMInstanceVO findById(long vmId); } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 92abd626fdb..f17b3eda337 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1491,7 +1491,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } @Override - public VMInstanceVO findById(VirtualMachine.Type type, long vmId) { + public VMInstanceVO findByIdAndType(VirtualMachine.Type type, long vmId) { VirtualMachineGuru guru = _vmGurus.get(type); return guru.findById(vmId); } @@ -1762,7 +1762,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene VirtualMachineGuru vmGuru = getVmGuru(vm); s_logger.debug("VM state is starting on full sync so updating it to running"); - vm = findById(vm.getType(), vm.getId()); + vm = findByIdAndType(vm.getType(), vm.getId()); //grab outstanding work item if any ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); @@ -2069,4 +2069,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene return host; } } + + @Override + public VMInstanceVO findById(long vmId) { + return _vmDao.findById(vmId); + } } diff --git a/server/test/com/cloud/async/TestAsyncJobManager.java b/server/test/com/cloud/async/TestAsyncJobManager.java index 1e259341d21..f047bcf9bbd 100644 --- a/server/test/com/cloud/async/TestAsyncJobManager.java +++ b/server/test/com/cloud/async/TestAsyncJobManager.java @@ -21,7 +21,6 @@ package com.cloud.async; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import junit.framework.Assert; @@ -34,9 +33,6 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDaoImpl; -import com.cloud.network.IPAddressVO; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.server.ManagementServer; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.Transaction; @@ -49,8 +45,8 @@ public class TestAsyncJobManager extends ComponentTestCase { volatile long s_count = 0; - public void asyncCall() { - ManagementServer mgr = (ManagementServer)ComponentLocator.getComponent("management-server"); + public void asyncCall() { + AsyncJobManager asyncMgr = ComponentLocator.getLocator(ManagementServer.Name).getManager(AsyncJobManager.class); // long jobId = mgr.rebootVirtualMachineAsync(1, 1); long jobId = 0L; @@ -59,7 +55,7 @@ public class TestAsyncJobManager extends ComponentTestCase { while(true) { AsyncJobResult result; try { - result = mgr.queryAsyncJobResult(jobId); + result = asyncMgr.queryAsyncJobResult(jobId); if(result.getJobStatus() != AsyncJobResult.STATUS_IN_PROGRESS) { s_logger.info("Async-call completed, result: " + result.toString()); diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index 3eab89e7393..a33f6f20da7 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -1,37 +1,20 @@ package com.cloud.user; -import java.util.List; import java.util.Map; -import java.util.Set; import javax.ejb.Local; import javax.naming.ConfigurationException; import com.cloud.acl.ControlledEntity; import com.cloud.acl.SecurityChecker.AccessType; -import com.cloud.api.commands.CreateAccountCmd; -import com.cloud.api.commands.CreateDomainCmd; -import com.cloud.api.commands.CreateUserCmd; -import com.cloud.api.commands.DeleteAccountCmd; import com.cloud.api.commands.DeleteUserCmd; -import com.cloud.api.commands.DisableAccountCmd; -import com.cloud.api.commands.DisableUserCmd; -import com.cloud.api.commands.EnableAccountCmd; -import com.cloud.api.commands.EnableUserCmd; -import com.cloud.api.commands.LockUserCmd; +import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.UpdateAccountCmd; -import com.cloud.api.commands.UpdateResourceCountCmd; import com.cloud.api.commands.UpdateUserCmd; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit; -import com.cloud.configuration.ResourceLimitVO; -import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.domain.Domain; -import com.cloud.domain.DomainVO; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.server.Criteria; import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; @@ -40,31 +23,31 @@ import com.cloud.utils.component.Manager; public class MockAccountManagerImpl implements Manager, AccountManager { @Override - public UserAccount createAccount(CreateAccountCmd cmd) { + public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain) { // TODO Auto-generated method stub return null; } @Override - public boolean deleteUserAccount(DeleteAccountCmd cmd) { + public boolean deleteUserAccount(long accountId) { // TODO Auto-generated method stub return false; } @Override - public UserAccount disableUser(DisableUserCmd cmd) { + public UserAccount disableUser(long userId) { // TODO Auto-generated method stub return null; } @Override - public UserAccount enableUser(EnableUserCmd cmd) { + public UserAccount enableUser(long userId) { // TODO Auto-generated method stub return null; } @Override - public UserAccount lockUser(LockUserCmd cmd) { + public UserAccount lockUser(long userId) { // TODO Auto-generated method stub return null; } @@ -76,19 +59,19 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } @Override - public Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { + public Account disableAccount(String accountName, Long domainId) throws ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub return null; } @Override - public Account enableAccount(EnableAccountCmd cmd) { + public Account enableAccount(String accountName, long domainId) { // TODO Auto-generated method stub return null; } @Override - public Account lockAccount(DisableAccountCmd cmd) { + public Account lockAccount(String accountName, Long domainId) { // TODO Auto-generated method stub return null; } @@ -99,24 +82,6 @@ public class MockAccountManagerImpl implements Manager, AccountManager { return null; } - @Override - public ResourceLimit updateResourceLimit(String accountName, Long domainId, int typeId, Long max) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List updateResourceCount(UpdateResourceCountCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List searchForLimits(Long id, String accountName, Long domainId, Integer type, Long startIndex, Long pageSizeVal) { - // TODO Auto-generated method stub - return null; - } - @Override public Account getSystemAccount() { // TODO Auto-generated method stub @@ -154,13 +119,13 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } @Override - public Account getActiveAccount(String accountName, Long domainId) { + public Account getActiveAccountByName(String accountName, Long domainId) { // TODO Auto-generated method stub return null; } @Override - public Account getActiveAccount(Long accountId) { + public Account getActiveAccountById(Long accountId) { // TODO Auto-generated method stub return null; } @@ -183,12 +148,6 @@ public class MockAccountManagerImpl implements Manager, AccountManager { return null; } - @Override - public Domain getDomain(long id) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean isRootAdmin(short accountType) { // TODO Auto-generated method stub @@ -207,72 +166,6 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } - @Override - public Set getDomainParentIds(long domainId) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Set getDomainChildrenIds(String parentDomainPath) { - // TODO Auto-generated method stub - return null; - } - - @Override - public long findCorrectResourceLimit(long accountId, ResourceType type) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public long findCorrectResourceLimit(DomainVO domain, ResourceType type) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public long updateAccountResourceCount(long accountId, ResourceType type) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public long updateDomainResourceCount(long domainId, ResourceType type) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void incrementResourceCount(long accountId, ResourceType type, Long... delta) { - // TODO Auto-generated method stub - - } - - @Override - public void decrementResourceCount(long accountId, ResourceType type, Long... delta) { - // TODO Auto-generated method stub - - } - - @Override - public boolean resourceLimitExceeded(Account account, ResourceType type, long... count) { - // TODO Auto-generated method stub - return false; - } - - @Override - public long getResourceCount(AccountVO account, ResourceType type) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public List searchForLimits(Criteria c) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub @@ -291,7 +184,6 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } - @Override public boolean cleanupAccount(AccountVO account, long callerUserId, Account caller) { // TODO Auto-generated method stub @@ -299,7 +191,7 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } @Override - public UserVO createUser(CreateUserCmd cmd) { + public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId) { // TODO Auto-generated method stub return null; } @@ -335,11 +227,40 @@ public class MockAccountManagerImpl implements Manager, AccountManager { @Override public void checkAccess(Account account, AccessType accessType, ControlledEntity... entities) throws PermissionDeniedException { // TODO Auto-generated method stub - } @Override - public Domain createDomain(CreateDomainCmd cmd) { + public void logoutUser(Long userId) { + // TODO Auto-generated method stub + } + + @Override + public UserAccount getUserAccount(String username, Long domainId) { + return null; + } + + @Override + public UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters) { + return null; + } + + @Override + public Pair findUserByApiKey(String apiKey) { + return null; + } + + @Override + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone) { + return null; + } + + @Override + public Account createAccount(String accountName, short accountType, Long domainId, String networkDomain) { + return null; + } + + @Override + public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { return null; } diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 2ab591f6849..d5f448709a9 100644 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -181,7 +181,7 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager { } @Override - public VMInstanceVO findById(Type type, long vmId) { + public VMInstanceVO findByIdAndType(Type type, long vmId) { // TODO Auto-generated method stub return null; } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index ffa7259063c..b368f595e37 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1041,6 +1041,7 @@ CREATE TABLE `cloud`.`domain` ( `removed` datetime COMMENT 'date removed', `state` char(32) NOT NULL default 'Active' COMMENT 'state of the domain', `network_domain` varchar(255), + `type` varchar(255) NOT NULL DEFAULT 'Normal' COMMENT 'type of the domain - can be Normal or Project', PRIMARY KEY (`id`), UNIQUE (parent, name, removed), INDEX `i_domain__path`(`path`), @@ -1667,19 +1668,31 @@ CREATE TABLE `cloud`.`projects` ( `id` bigint unsigned NOT NULL auto_increment, `name` varchar(255) COMMENT 'project name', `display_text` varchar(255) COMMENT 'project name', - `account_id` bigint unsigned, - `domain_id` bigint unsigned, - `data_center_id` bigint unsigned, + `project_account_id` bigint unsigned NOT NULL, + `project_domain_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, `created` datetime COMMENT 'date created', - `removed` datetime COMMENT 'date removed', - `cleanup_needed` tinyint(1) NOT NULL default '0', + `removed` datetime COMMENT 'date removed',\ + `state` varchar(255) NOT NULL COMMENT 'state of the project (Active/Inactive/Suspended)', PRIMARY KEY (`id`), - CONSTRAINT `fk_projects__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_projects__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_projects__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_projects__project_domain_id` FOREIGN KEY(`project_domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_projects__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, INDEX `i_projects__removed`(`removed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`project_account` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_id` bigint unsigned NOT NULL COMMENT'account id', + `account_role` varchar(255) COMMENT 'Account role in the project (Owner or Regular)', + `project_id` bigint unsigned NOT NULL COMMENT 'project id', + PRIMARY KEY (`id`), + CONSTRAINT `fk_project_account__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_account__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, + UNIQUE (`account_id`, `project_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `cloud`.`elastic_lb_vm_map` ( `id` bigint unsigned NOT NULL auto_increment, `ip_addr_id` bigint unsigned NOT NULL, diff --git a/setup/db/db/schema-2212to30.sql b/setup/db/db/schema-2212to30.sql index 3123f2b2c76..6255e9f76a5 100644 --- a/setup/db/db/schema-2212to30.sql +++ b/setup/db/db/schema-2212to30.sql @@ -27,3 +27,35 @@ INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('KVM', 'default', 50, 1); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', 'default', 25, 1); INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', '2.3', 25, 1); + + +CREATE TABLE `cloud`.`projects` ( + `id` bigint unsigned NOT NULL auto_increment, + `name` varchar(255) COMMENT 'project name', + `display_text` varchar(255) COMMENT 'project name', + `project_account_id` bigint unsigned NOT NULL, + `project_domain_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `created` datetime COMMENT 'date created', + `removed` datetime COMMENT 'date removed',\ + `state` varchar(255) NOT NULL COMMENT 'state of the project (Active/Inactive/Suspended)', + PRIMARY KEY (`id`), + CONSTRAINT `fk_projects__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_projects__project_domain_id` FOREIGN KEY(`project_domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_projects__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + INDEX `i_projects__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`project_account` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_id` bigint unsigned NOT NULL COMMENT'account id', + `account_role` varchar(255) COMMENT 'Account role in the project (Owner or Regular)', + `project_id` bigint unsigned NOT NULL COMMENT 'project id', + PRIMARY KEY (`id`), + CONSTRAINT `fk_project_account__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_account__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, + UNIQUE (`account_id`, `project_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE domain ADD COLUMN `type` varchar(255) NOT NULL DEFAULT 'Normal' COMMENT 'type of the domain - can be Normal or Project';