bug 14239: limit number of Isolated account specific networks per account

status 14239: resolved fixed

Conflicts:

	api/src/com/cloud/api/commands/CreateNetworkCmd.java
	server/src/com/cloud/network/NetworkManagerImpl.java
	server/test/com/cloud/network/MockNetworkManagerImpl.java
This commit is contained in:
Alena Prokharchyk 2012-03-12 15:50:00 -07:00
parent af06038b9d
commit ad1192e264
17 changed files with 210 additions and 152 deletions

View File

@ -30,6 +30,7 @@ import com.cloud.api.response.NetworkResponse;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.Network.GuestType; import com.cloud.network.Network.GuestType;
import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering;
@ -208,8 +209,8 @@ public class CreateNetworkCmd extends BaseCmd {
} }
@Override @Override
public void execute() throws InsufficientCapacityException, ConcurrentOperationException{ // an exception thrown by createNetwork() will be caught by the dispatcher.
// an exception thrown by createNetwork() will be caught by the dispatcher. public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{
Network result = _networkService.createNetwork(this); Network result = _networkService.createNetwork(this);
if (result != null) { if (result != null) {
NetworkResponse response = _responseGenerator.createNetworkResponse(result); NetworkResponse response = _responseGenerator.createNetworkResponse(result);

View File

@ -30,6 +30,7 @@ import com.cloud.api.response.VlanIpRangeResponse;
import com.cloud.dc.Vlan; import com.cloud.dc.Vlan;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account; import com.cloud.user.Account;
@ -159,7 +160,7 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
} }
@Override @Override
public void execute() throws ResourceUnavailableException{ public void execute() throws ResourceUnavailableException, ResourceAllocationException{
try { try {
Vlan result = _configService.createVlanAndPublicIpRange(this); Vlan result = _configService.createVlanAndPublicIpRange(this);
if (result != null) { if (result != null) {

View File

@ -97,6 +97,25 @@ public class AccountResponse extends BaseResponse {
@SerializedName("vmrunning") @Param(description="the total number of virtual machines running for this account") @SerializedName("vmrunning") @Param(description="the total number of virtual machines running for this account")
private Integer vmRunning; private Integer vmRunning;
@SerializedName("projectlimit") @Param(description="the total number of projects the account can own")
private String projectLimit;
@SerializedName("projecttotal") @Param(description="the total number of projects being administrated by this account")
private Long projectTotal;
@SerializedName("projectavailable") @Param(description="the total number of projects available for administration by this account")
private String projectAvailable;
@SerializedName("networklimit") @Param(description="the total number of networks the account can own")
private String networkLimit;
@SerializedName("networktotal") @Param(description="the total number of networks owned by account")
private Long networkTotal;
@SerializedName("networkavailable") @Param(description="the total number of networks available to be created for this account")
private String networkAvailable;
@SerializedName(ApiConstants.STATE) @Param(description="the state of the account") @SerializedName(ApiConstants.STATE) @Param(description="the state of the account")
private String state; private String state;
@ -113,218 +132,110 @@ public class AccountResponse extends BaseResponse {
@SerializedName(ApiConstants.ACCOUNT_DETAILS) @Param(description="details for the account") @SerializedName(ApiConstants.ACCOUNT_DETAILS) @Param(description="details for the account")
private Map<String, String> details; private Map<String, String> details;
public Long getId() {
return id.getValue();
}
public void setId(Long id) { public void setId(Long id) {
this.id.setValue(id); this.id.setValue(id);
} }
public String getName() {
return name;
}
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public Short getAccountType() {
return accountType;
}
public void setAccountType(Short accountType) { public void setAccountType(Short accountType) {
this.accountType = accountType; this.accountType = accountType;
} }
public Long getDomainId() {
return domainId.getValue();
}
public void setDomainId(Long domainId) { public void setDomainId(Long domainId) {
this.domainId.setValue(domainId); this.domainId.setValue(domainId);
} }
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) { public void setDomainName(String domainName) {
this.domainName = domainName; this.domainName = domainName;
} }
public Long getBytesReceived() {
return bytesReceived;
}
public void setBytesReceived(Long bytesReceived) { public void setBytesReceived(Long bytesReceived) {
this.bytesReceived = bytesReceived; this.bytesReceived = bytesReceived;
} }
public Long getBytesSent() {
return bytesSent;
}
public void setBytesSent(Long bytesSent) { public void setBytesSent(Long bytesSent) {
this.bytesSent = bytesSent; this.bytesSent = bytesSent;
} }
public String getVmLimit() {
return vmLimit;
}
public void setVmLimit(String vmLimit) { public void setVmLimit(String vmLimit) {
this.vmLimit = vmLimit; this.vmLimit = vmLimit;
} }
public Long getVmTotal() {
return vmTotal;
}
public void setVmTotal(Long vmTotal) { public void setVmTotal(Long vmTotal) {
this.vmTotal = vmTotal; this.vmTotal = vmTotal;
} }
public String getVmAvailable() {
return vmAvailable;
}
public void setVmAvailable(String vmAvailable) { public void setVmAvailable(String vmAvailable) {
this.vmAvailable = vmAvailable; this.vmAvailable = vmAvailable;
} }
public String getIpLimit() {
return ipLimit;
}
public void setIpLimit(String ipLimit) { public void setIpLimit(String ipLimit) {
this.ipLimit = ipLimit; this.ipLimit = ipLimit;
} }
public Long getIpTotal() {
return ipTotal;
}
public void setIpTotal(Long ipTotal) { public void setIpTotal(Long ipTotal) {
this.ipTotal = ipTotal; this.ipTotal = ipTotal;
} }
public String getIpAvailable() {
return ipAvailable;
}
public void setIpAvailable(String ipAvailable) { public void setIpAvailable(String ipAvailable) {
this.ipAvailable = ipAvailable; this.ipAvailable = ipAvailable;
} }
public String getVolumeLimit() {
return volumeLimit;
}
public void setVolumeLimit(String volumeLimit) { public void setVolumeLimit(String volumeLimit) {
this.volumeLimit = volumeLimit; this.volumeLimit = volumeLimit;
} }
public Long getVolumeTotal() {
return volumeTotal;
}
public void setVolumeTotal(Long volumeTotal) { public void setVolumeTotal(Long volumeTotal) {
this.volumeTotal = volumeTotal; this.volumeTotal = volumeTotal;
} }
public String getVolumeAvailable() {
return volumeAvailable;
}
public void setVolumeAvailable(String volumeAvailable) { public void setVolumeAvailable(String volumeAvailable) {
this.volumeAvailable = volumeAvailable; this.volumeAvailable = volumeAvailable;
} }
public String getSnapshotLimit() {
return snapshotLimit;
}
public void setSnapshotLimit(String snapshotLimit) { public void setSnapshotLimit(String snapshotLimit) {
this.snapshotLimit = snapshotLimit; this.snapshotLimit = snapshotLimit;
} }
public Long getSnapshotTotal() {
return snapshotTotal;
}
public void setSnapshotTotal(Long snapshotTotal) { public void setSnapshotTotal(Long snapshotTotal) {
this.snapshotTotal = snapshotTotal; this.snapshotTotal = snapshotTotal;
} }
public String getSnapshotAvailable() {
return snapshotAvailable;
}
public void setSnapshotAvailable(String snapshotAvailable) { public void setSnapshotAvailable(String snapshotAvailable) {
this.snapshotAvailable = snapshotAvailable; this.snapshotAvailable = snapshotAvailable;
} }
public String getTemplateLimit() {
return templateLimit;
}
public void setTemplateLimit(String templateLimit) { public void setTemplateLimit(String templateLimit) {
this.templateLimit = templateLimit; this.templateLimit = templateLimit;
} }
public Long getTemplateTotal() {
return templateTotal;
}
public void setTemplateTotal(Long templateTotal) { public void setTemplateTotal(Long templateTotal) {
this.templateTotal = templateTotal; this.templateTotal = templateTotal;
} }
public String getTemplateAvailable() {
return templateAvailable;
}
public void setTemplateAvailable(String templateAvailable) { public void setTemplateAvailable(String templateAvailable) {
this.templateAvailable = templateAvailable; this.templateAvailable = templateAvailable;
} }
public Integer getVmStopped() {
return vmStopped;
}
public void setVmStopped(Integer vmStopped) { public void setVmStopped(Integer vmStopped) {
this.vmStopped = vmStopped; this.vmStopped = vmStopped;
} }
public Integer getVmRunning() {
return vmRunning;
}
public void setVmRunning(Integer vmRunning) { public void setVmRunning(Integer vmRunning) {
this.vmRunning = vmRunning; this.vmRunning = vmRunning;
} }
public String getState() {
return state;
}
public void setState(String state) { public void setState(String state) {
this.state = state; this.state = state;
} }
public Boolean getCleanupRequired() {
return cleanupRequired;
}
public void setCleanupRequired(Boolean cleanupRequired) { public void setCleanupRequired(Boolean cleanupRequired) {
this.cleanupRequired = cleanupRequired; this.cleanupRequired = cleanupRequired;
} }
public List<UserResponse> getUsers() {
return this.users;
}
public void setUsers(List<UserResponse> users) { public void setUsers(List<UserResponse> users) {
this.users = users; this.users = users;
} }
@ -336,8 +247,28 @@ public class AccountResponse extends BaseResponse {
public void setDetails(Map<String, String> details) { public void setDetails(Map<String, String> details) {
this.details = details; this.details = details;
} }
public Map getDetails() { public void setProjectLimit(String projectLimit) {
return details; this.projectLimit = projectLimit;
}
public void setProjectTotal(Long projectTotal) {
this.projectTotal = projectTotal;
}
public void setProjectAvailable(String projectAvailable) {
this.projectAvailable = projectAvailable;
}
public void setNetworkLimit(String networkLimit) {
this.networkLimit = networkLimit;
}
public void setNetworkTotal(Long networkTotal) {
this.networkTotal = networkTotal;
}
public void setNetworkAvailable(String networkAvailable) {
this.networkAvailable = networkAvailable;
} }
} }

View File

@ -47,6 +47,7 @@ import com.cloud.dc.Pod;
import com.cloud.dc.Vlan; import com.cloud.dc.Vlan;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
@ -215,10 +216,11 @@ public interface ConfigurationService {
* @param gateway * @param gateway
* @param startIP * @param startIP
* @param endIP * @param endIP
* @throws ResourceAllocationException TODO
* @throws * @throws
* @return The new Vlan object * @return The new Vlan object
*/ */
Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException; Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;
boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd); boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd);

View File

@ -27,7 +27,8 @@ public interface Resource {
volume("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain), volume("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain),
snapshot("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain), snapshot("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
template("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain), template("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
project("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain); project("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain),
network("network", 6, ResourceOwnerType.Account, ResourceOwnerType.Domain);
private String name; private String name;
private ResourceOwnerType[] supportedOwners; private ResourceOwnerType[] supportedOwners;

View File

@ -57,7 +57,7 @@ public interface NetworkService {
boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException; Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
List<? extends Network> searchForNetworks(ListNetworksCmd cmd); List<? extends Network> searchForNetworks(ListNetworksCmd cmd);

View File

@ -279,7 +279,7 @@ public class ApiResponseHelper implements ResponseGenerator {
Long ips = ipLimit - ipTotal; Long ips = ipLimit - ipTotal;
// check how many free ips are left, and if it's less than max allowed number of ips from account - use this // check how many free ips are left, and if it's less than max allowed number of ips from account - use this
// value // value
Long ipsLeft = ApiDBUtils.countFreePublicIps(); Long ipsLeft = ApiDBUtils.countFreePublicIps();
boolean unlimited = true; boolean unlimited = true;
if (ips.longValue() > ipsLeft.longValue()) { if (ips.longValue() > ipsLeft.longValue()) {
@ -341,7 +341,25 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setVmStopped(vmStopped); accountResponse.setVmStopped(vmStopped);
accountResponse.setVmRunning(vmRunning); accountResponse.setVmRunning(vmRunning);
accountResponse.setObjectName("account"); accountResponse.setObjectName("account");
//get resource limits for projects
Long projectLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.project, account.getId());
String projectLimitDisplay = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit);
Long projectTotal = ApiDBUtils.getResourceCount(ResourceType.project, account.getId());
String projectAvail = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal);
accountResponse.setProjectLimit(projectLimitDisplay);
accountResponse.setProjectTotal(projectTotal);
accountResponse.setProjectAvailable(projectAvail);
//get resource limits for networks
Long networkLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.network, account.getId());
String networkLimitDisplay = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit);
Long networkTotal = ApiDBUtils.getResourceCount(ResourceType.network, account.getId());
String networkAvail = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal);
accountResponse.setNetworkLimit(networkLimitDisplay);
accountResponse.setNetworkTotal(networkTotal);
accountResponse.setNetworkAvailable(networkAvail);
// adding all the users for an account as part of the response obj // adding all the users for an account as part of the response obj
List<UserVO> usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId()); List<UserVO> usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId());
List<UserResponse> userResponseList = new ArrayList<UserResponse>(); List<UserResponse> userResponseList = new ArrayList<UserResponse>();

View File

@ -78,7 +78,7 @@ public enum Config {
CopyVolumeWait("Storage", StorageManager.class, Integer.class, "copy.volume.wait", "10800", "In second, timeout for copy volume command", null), CopyVolumeWait("Storage", StorageManager.class, Integer.class, "copy.volume.wait", "10800", "In second, timeout for copy volume command", null),
CreatePrivateTemplateFromVolumeWait("Storage", UserVmManager.class, Integer.class, "create.private.template.from.volume.wait", "10800", "In second, timeout for CreatePrivateTemplateFromVolumeCommand", null), CreatePrivateTemplateFromVolumeWait("Storage", UserVmManager.class, Integer.class, "create.private.template.from.volume.wait", "10800", "In second, timeout for CreatePrivateTemplateFromVolumeCommand", null),
CreatePrivateTemplateFromSnapshotWait("Storage", UserVmManager.class, Integer.class, "create.private.template.from.snapshot.wait", "10800", "In second, timeout for CreatePrivateTemplateFromSnapshotCommand", null), CreatePrivateTemplateFromSnapshotWait("Storage", UserVmManager.class, Integer.class, "create.private.template.from.snapshot.wait", "10800", "In second, timeout for CreatePrivateTemplateFromSnapshotCommand", null),
BackupSnapshotWait( BackupSnapshotWait(
"Storage", StorageManager.class, Integer.class, "backup.snapshot.wait", "21600", "In second, timeout for BackupSnapshotCommand", null), "Storage", StorageManager.class, Integer.class, "backup.snapshot.wait", "21600", "In second, timeout for BackupSnapshotCommand", null),
// Network // Network
@ -300,6 +300,8 @@ public enum Config {
DefaultMaxAccountTemplates("Account Defaults", ManagementServer.class, Long.class, "max.account.templates", "20", "The default maximum number of templates that can be deployed for an account", null), DefaultMaxAccountTemplates("Account Defaults", ManagementServer.class, Long.class, "max.account.templates", "20", "The default maximum number of templates that can be deployed for an account", null),
DefaultMaxAccountSnapshots("Account Defaults", ManagementServer.class, Long.class, "max.account.snapshots", "20", "The default maximum number of snapshots that can be created for an account", null), DefaultMaxAccountSnapshots("Account Defaults", ManagementServer.class, Long.class, "max.account.snapshots", "20", "The default maximum number of snapshots that can be created for an account", null),
DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null), DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null),
DefaultMaxAccountNetworks("Account Defaults", ManagementServer.class, Long.class, "max.account.networks", "20", "The default maximum number of networks that can be created for an account", null),
ResourceCountCheckInterval("Advanced", ManagementServer.class, Long.class, "resourcecount.check.interval", "0", "Time (in seconds) to wait before retrying resource count check task. Default is 0 which is to never run the task", "Seconds"), ResourceCountCheckInterval("Advanced", ManagementServer.class, Long.class, "resourcecount.check.interval", "0", "Time (in seconds) to wait before retrying resource count check task. Default is 0 which is to never run the task", "Seconds"),
DirectAgentLoadSize("Advanced", ManagementServer.class, Integer.class, "direct.agent.load.size", "16", "The number of direct agents to load each time", null), DirectAgentLoadSize("Advanced", ManagementServer.class, Integer.class, "direct.agent.load.size", "16", "The number of direct agents to load each time", null),
@ -320,6 +322,7 @@ public enum Config {
DefaultMaxProjectTemplates("Project Defaults", ManagementServer.class, Long.class, "max.project.templates", "20", "The default maximum number of templates that can be deployed for a project", null), DefaultMaxProjectTemplates("Project Defaults", ManagementServer.class, Long.class, "max.project.templates", "20", "The default maximum number of templates that can be deployed for a project", null),
DefaultMaxProjectSnapshots("Project Defaults", ManagementServer.class, Long.class, "max.project.snapshots", "20", "The default maximum number of snapshots that can be created for a project", null), DefaultMaxProjectSnapshots("Project Defaults", ManagementServer.class, Long.class, "max.project.snapshots", "20", "The default maximum number of snapshots that can be created for a project", null),
DefaultMaxProjectVolumes("Project Defaults", ManagementServer.class, Long.class, "max.project.volumes", "20", "The default maximum number of volumes that can be created for a project", null), DefaultMaxProjectVolumes("Project Defaults", ManagementServer.class, Long.class, "max.project.volumes", "20", "The default maximum number of volumes that can be created for a project", null),
DefaultMaxProjectNetworks("Project Defaults", ManagementServer.class, Long.class, "max.project.networks", "20", "The default maximum number of networks that can be created for a project", null),
ProjectInviteRequired("Project Defaults", ManagementServer.class, Boolean.class, "project.invite.required", "false", "If invitation confirmation is required when add account to project. Default value is false", null), ProjectInviteRequired("Project Defaults", ManagementServer.class, Boolean.class, "project.invite.required", "false", "If invitation confirmation is required when add account to project. Default value is false", null),
ProjectInvitationExpirationTime("Project Defaults", ManagementServer.class, Long.class, "project.invite.timeout", "86400", "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds", null), ProjectInvitationExpirationTime("Project Defaults", ManagementServer.class, Long.class, "project.invite.timeout", "86400", "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds", null),

View File

@ -98,6 +98,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
@ -2063,7 +2064,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
@Override @Override
@DB @DB
@ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_CREATE, eventDescription = "creating vlan ip range", async = false) @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_CREATE, eventDescription = "creating vlan ip range", async = false)
public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException {
Long zoneId = cmd.getZoneId(); Long zoneId = cmd.getZoneId();
Long podId = cmd.getPodId(); Long podId = cmd.getPodId();
String startIP = cmd.getStartIp(); String startIP = cmd.getStartIp();
@ -2279,13 +2280,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (associateIpRangeToAccount) { if (associateIpRangeToAccount) {
_networkMgr.associateIpAddressListToAccount(userId, account.getId(), zoneId, vlan.getId(), network); _networkMgr.associateIpAddressListToAccount(userId, account.getId(), zoneId, vlan.getId(), network);
if (network == null) {
List<? extends Network> networks = _networkMgr.getIsolatedNetworksOwnedByAccountInZone(zoneId, account);
network = networks.get(0);
}
if (network == null) {
throw new CloudRuntimeException("Failed to associate vlan to the account id=" + account.getId() + ", default network failed to create");
}
} }
txn.commit(); txn.commit();

View File

@ -35,6 +35,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network.Capability; import com.cloud.network.Network.Capability;
@ -168,9 +169,10 @@ public interface NetworkManager extends NetworkService {
boolean destroyNetwork(long networkId, ReservationContext context); boolean destroyNetwork(long networkId, ReservationContext context);
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, Long domainId, Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, Long domainId,
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException; PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
/** /**
* @throws ResourceAllocationException TODO
* @throws InsufficientCapacityException * @throws InsufficientCapacityException
* Associates an ip address list to an account. The list of ip addresses are all addresses associated * Associates an ip address list to an account. The list of ip addresses are all addresses associated
* with the * with the
@ -183,7 +185,7 @@ public interface NetworkManager extends NetworkService {
* @throws * @throws
*/ */
boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network networkToAssociateWith) throws InsufficientCapacityException, ConcurrentOperationException, boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network networkToAssociateWith) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException; ResourceUnavailableException, ResourceAllocationException;
Nic getNicInNetwork(long vmId, long networkId); Nic getNicInNetwork(long vmId, long networkId);

View File

@ -2232,7 +2232,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
@DB @DB
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network") @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException { public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
Long networkOfferingId = cmd.getNetworkOfferingId(); Long networkOfferingId = cmd.getNetworkOfferingId();
String gateway = cmd.getGateway(); String gateway = cmd.getGateway();
String startIP = cmd.getStartIp(); String startIP = cmd.getStartIp();
@ -2469,17 +2469,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
@DB @DB
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled,
Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException { Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
// this method supports only guest network creation // this method supports only guest network creation
if (networkOffering.getTrafficType() != TrafficType.Guest) { if (ntwkOff.getTrafficType() != TrafficType.Guest) {
s_logger.warn("Only guest networks can be created using this method"); s_logger.warn("Only guest networks can be created using this method");
return null; return null;
} }
boolean updateResourceCount = (!ntwkOff.getSpecifyVlan() && aclType == ACLType.Account);
//check resource limits
if (updateResourceCount) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.network);
}
// Validate network offering // Validate network offering
if (networkOffering.getState() != NetworkOffering.State.Enabled) { if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
// see NetworkOfferingVO // see NetworkOfferingVO
InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled); InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled);
ex.addProxyObject("network_offerings", networkOfferingId, "networkOfferingId"); ex.addProxyObject("network_offerings", networkOfferingId, "networkOfferingId");
@ -2497,6 +2503,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
// Validate zone // Validate zone
DataCenterVO zone = _dcDao.findById(zoneId); DataCenterVO zone = _dcDao.findById(zoneId);
if (zone.getNetworkType() == NetworkType.Basic) { if (zone.getNetworkType() == NetworkType.Basic) {
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
if (aclType == null || aclType != ACLType.Domain) {
throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
}
// Only one guest network is supported in Basic zone // Only one guest network is supported in Basic zone
List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest); List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
if (!guestNetworks.isEmpty()) { if (!guestNetworks.isEmpty()) {
@ -2504,16 +2515,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} }
// if zone is basic, only Shared network offerings w/o source nat service are allowed // if zone is basic, only Shared network offerings w/o source nat service are allowed
if (!(networkOffering.getGuestType() == GuestType.Shared && !areServicesSupportedByNetworkOffering(networkOffering.getId(), Service.SourceNat))) { if (!(ntwkOff.getGuestType() == GuestType.Shared && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName()
+ " service are allowed"); + " service are allowed");
} }
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
if (aclType == null || aclType != ACLType.Domain) {
throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
}
if (domainId == null || domainId != Domain.ROOT_DOMAIN) { if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain"); throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
} }
@ -2535,8 +2541,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} else if (zone.getNetworkType() == NetworkType.Advanced) { } else if (zone.getNetworkType() == NetworkType.Advanced) {
if (zone.isSecurityGroupEnabled()) { if (zone.isSecurityGroupEnabled()) {
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group // Only Account specific Isolated network with sourceNat service disabled are allowed in security group
// enabled zone // enabled zone
boolean allowCreation = (networkOffering.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(networkOffering.getId(), Service.SourceNat)); boolean allowCreation = (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat));
if (!allowCreation) { if (!allowCreation) {
throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat service disabled are allowed in security group enabled zone"); throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat service disabled are allowed in security group enabled zone");
} }
@ -2545,7 +2551,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
// VlanId can be specified only when network offering supports it // VlanId can be specified only when network offering supports it
boolean vlanSpecified = (vlanId != null); boolean vlanSpecified = (vlanId != null);
if (vlanSpecified != networkOffering.getSpecifyVlan()) { if (vlanSpecified != ntwkOff.getSpecifyVlan()) {
if (vlanSpecified) { if (vlanSpecified) {
throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false"); throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
} else { } else {
@ -2598,10 +2604,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} }
// In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x // In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
// limitation, remove after we introduce support for multiple ip ranges // limitation, remove after we introduce support for multiple ip ranges
// with different Cidrs for the same Shared network // with different Cidrs for the same Shared network
boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced && networkOffering.getTrafficType() == TrafficType.Guest boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced && ntwkOff.getTrafficType() == TrafficType.Guest
&& (networkOffering.getGuestType() == GuestType.Shared || (networkOffering.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(networkOffering.getId(), Service.SourceNat))); && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)));
if (cidr == null && cidrRequired) { if (cidr == null && cidrRequired) {
throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service "
+ Service.SourceNat.getName() + " disabled"); + Service.SourceNat.getName() + " disabled");
@ -2613,7 +2619,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} }
// Check if cidr is RFC1918 compliant if the network is Guest Isolated // Check if cidr is RFC1918 compliant if the network is Guest Isolated
if (cidr != null && networkOffering.getGuestType() == Network.GuestType.Isolated && networkOffering.getTrafficType() == TrafficType.Guest) { if (cidr != null && ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) {
if (!NetUtils.validateGuestCidr(cidr)) { if (!NetUtils.validateGuestCidr(cidr)) {
throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC1918 compliant"); throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC1918 compliant");
} }
@ -2644,7 +2650,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} }
} }
List<NetworkVO> networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccess); List<NetworkVO> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccess);
Network network = null; Network network = null;
if (networks == null || networks.isEmpty()) { if (networks == null || networks.isEmpty()) {
@ -2663,6 +2669,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
network = networks.get(0); network = networks.get(0);
} }
} }
if (updateResourceCount) {
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network);
}
txn.commit(); txn.commit();
UserContext.current().setEventDetails("Network Id: " + network.getId()); UserContext.current().setEventDetails("Network Id: " + network.getId());
@ -3719,7 +3729,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
@DB @DB
public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException, public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException { ResourceUnavailableException, ResourceAllocationException {
Account owner = _accountMgr.getActiveAccountById(accountId); Account owner = _accountMgr.getActiveAccountById(accountId);
boolean createNetwork = false; boolean createNetwork = false;

View File

@ -95,5 +95,7 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long> {
void setCheckForGc(long networkId); void setCheckForGc(long networkId);
int getNetworkCountByNetworkOffId(long networkOfferingId); int getNetworkCountByNetworkOffId(long networkOfferingId);
long countNetworksUserCanCreate(long ownerId);
} }

View File

@ -24,6 +24,7 @@ import java.util.Random;
import javax.ejb.Local; import javax.ejb.Local;
import javax.persistence.TableGenerator; import javax.persistence.TableGenerator;
import com.cloud.acl.ControlledEntity.ACLType;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.Network.Provider; import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service; import com.cloud.network.Network.Service;
@ -35,6 +36,8 @@ import com.cloud.network.NetworkVO;
import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDaoImpl;
import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
@ -61,6 +64,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
final GenericSearchBuilder<NetworkVO, Long> CountByOfferingId; final GenericSearchBuilder<NetworkVO, Long> CountByOfferingId;
final SearchBuilder<NetworkVO> PhysicalNetworkSearch; final SearchBuilder<NetworkVO> PhysicalNetworkSearch;
final SearchBuilder<NetworkVO> SecurityGroupSearch; final SearchBuilder<NetworkVO> SecurityGroupSearch;
final GenericSearchBuilder<NetworkVO, Long> NetworksRegularUserCanCreateSearch;
private final GenericSearchBuilder<NetworkVO, Integer> NetworksCount; private final GenericSearchBuilder<NetworkVO, Integer> NetworksCount;
@ -68,6 +72,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class); NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class);
NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class); NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
NetworkServiceMapDaoImpl _ntwkSvcMap = ComponentLocator.inject(NetworkServiceMapDaoImpl.class); NetworkServiceMapDaoImpl _ntwkSvcMap = ComponentLocator.inject(NetworkServiceMapDaoImpl.class);
NetworkOfferingDaoImpl _ntwkOffDao = ComponentLocator.inject(NetworkOfferingDaoImpl.class);
final TableGenerator _tgMacAddress; final TableGenerator _tgMacAddress;
@ -145,6 +150,18 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
NetworksCount.select(null, Func.COUNT, NetworksCount.entity().getId()); NetworksCount.select(null, Func.COUNT, NetworksCount.entity().getId());
NetworksCount.and("networkOfferingId", NetworksCount.entity().getNetworkOfferingId(), SearchCriteria.Op.EQ); NetworksCount.and("networkOfferingId", NetworksCount.entity().getNetworkOfferingId(), SearchCriteria.Op.EQ);
NetworksCount.done(); NetworksCount.done();
NetworksRegularUserCanCreateSearch = createSearchBuilder(Long.class);
NetworksRegularUserCanCreateSearch.and("aclType", NetworksRegularUserCanCreateSearch.entity().getAclType(), Op.EQ);
NetworksRegularUserCanCreateSearch.select(null, Func.COUNT, NetworksRegularUserCanCreateSearch.entity().getId());
SearchBuilder<NetworkAccountVO> join4 = _accountsDao.createSearchBuilder();
join4.and("account", join4.entity().getAccountId(), Op.EQ);
join4.and("isOwner", join4.entity().isOwner(), Op.EQ);
NetworksRegularUserCanCreateSearch.join("accounts", join4, NetworksRegularUserCanCreateSearch.entity().getId(), join4.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
SearchBuilder<NetworkOfferingVO> join5 = _ntwkOffDao.createSearchBuilder();
join5.and("specifyVlan", join5.entity().getSpecifyVlan(), Op.EQ);
NetworksRegularUserCanCreateSearch.join("ntwkOff", join5, NetworksRegularUserCanCreateSearch.entity().getNetworkOfferingId(), join5.entity().getId(), JoinBuilder.JoinType.INNER);
NetworksRegularUserCanCreateSearch.done();
_tgMacAddress = _tgs.get("macAddress"); _tgMacAddress = _tgs.get("macAddress");
@ -416,5 +433,14 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
List<Integer> count = customSearch(sc, null); List<Integer> count = customSearch(sc, null);
return count.get(0); return count.get(0);
} }
@Override
public long countNetworksUserCanCreate(long ownerId) {
SearchCriteria<Long> sc = NetworksRegularUserCanCreateSearch.create();
sc.setParameters("aclType", ACLType.Account);
sc.setJoinParameters("accounts", "account", ownerId);
sc.setJoinParameters("ntwkOff", "specifyVlan", false);
return customSearch(sc, null).get(0);
}
} }

View File

@ -52,6 +52,7 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.projects.Project; import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount.Role; import com.cloud.projects.ProjectAccount.Role;
import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectAccountDao;
@ -117,6 +118,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
private ProjectDao _projectDao; private ProjectDao _projectDao;
@Inject @Inject
private ProjectAccountDao _projectAccountDao; private ProjectAccountDao _projectAccountDao;
@Inject
private NetworkDao _networkDao;
protected SearchBuilder<ResourceCountVO> ResourceCountSearch; protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
ScheduledExecutorService _rcExecutor; ScheduledExecutorService _rcExecutor;
@ -162,12 +165,14 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
projectResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectTemplates.key()))); projectResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectTemplates.key())));
projectResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectUserVms.key()))); projectResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectUserVms.key())));
projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key()))); projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key())));
projectResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectNetworks.key())));
accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key()))); accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key()))); accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
accountResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key()))); accountResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key())));
accountResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key()))); accountResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())));
accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key()))); accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())));
accountResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountNetworks.key())));
return true; return true;
} }
@ -724,6 +729,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
newCount = _vmTemplateDao.countTemplatesForAccount(accountId); newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
} else if (type == Resource.ResourceType.project) { } else if (type == Resource.ResourceType.project) {
newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin); newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
} else if (type == Resource.ResourceType.network) {
newCount = _networkDao.countNetworksUserCanCreate(accountId);
} else { } else {
throw new InvalidParameterValueException("Unsupported resource type " + type); throw new InvalidParameterValueException("Unsupported resource type " + type);
} }

View File

@ -1477,7 +1477,7 @@ public class Upgrade218to22 implements DbUpgrade {
upgradeDomainResourceCounts(conn, ResourceType.public_ip); upgradeDomainResourceCounts(conn, ResourceType.public_ip);
} }
private void upgradeDomainResourceCounts(Connection conn, ResourceType resourceType) { public static void upgradeDomainResourceCounts(Connection conn, ResourceType resourceType) {
try { try {
PreparedStatement account_count_pstmt = conn.prepareStatement("SELECT account_id, count from resource_count where type='" + resourceType + "'"); PreparedStatement account_count_pstmt = conn.prepareStatement("SELECT account_id, count from resource_count where type='" + resourceType + "'");

View File

@ -31,6 +31,7 @@ import java.util.UUID;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering;
import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -88,6 +89,10 @@ public class Upgrade2214to30 implements DbUpgrade {
migrateUserConcentratedPlannerChoice(conn); migrateUserConcentratedPlannerChoice(conn);
// update domain router table for element it; // update domain router table for element it;
updateRouters(conn); updateRouters(conn);
// update network account resource count
udpateAccountNetworkResourceCount(conn);
// update network domain resource count
udpateDomainNetworkResourceCount(conn);
} }
@Override @Override
@ -1089,5 +1094,57 @@ public class Upgrade2214to30 implements DbUpgrade {
} catch (SQLException e) { } catch (SQLException e) {
} }
} }
} }
protected void udpateAccountNetworkResourceCount(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
ResultSet rs1 = null;
long accountId = 0;
try {
pstmt = conn.prepareStatement("select id from `cloud`.`account` where removed is null");
rs = pstmt.executeQuery();
while (rs.next()) {
accountId = rs.getLong(1);
//get networks count for the account
pstmt = conn.prepareStatement("select count(*) from `cloud`.`networks` n, `cloud`.`account_network_ref` a, `cloud`.`network_offerings` no" +
" WHERE n.acl_type='Account' and n.id=a.network_id and a.account_id=? and a.is_owner=1 and no.specify_vlan=false and no.traffic_type='Guest'");
pstmt.setLong(1, accountId);
rs1 = pstmt.executeQuery();
long count = 0;
while (rs1.next()) {
count = rs1.getLong(1);
}
pstmt = conn.prepareStatement("insert into `cloud`.`resource_count` (account_id, domain_id, type, count) VALUES (?, null, 'network', ?)");
pstmt.setLong(1, accountId);
pstmt.setLong(2, count);
pstmt.executeUpdate();
s_logger.debug("Updated network resource count for account id=" + accountId + " to be " + count);
}
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to update network resource count for account id=" + accountId, e);
} finally {
try {
if (rs != null) {
rs.close();
}
if (rs1 != null) {
rs1.close();
}
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
}
}
}
protected void udpateDomainNetworkResourceCount(Connection conn) {
Upgrade218to22.upgradeDomainResourceCounts(conn, ResourceType.network);
}
} }

View File

@ -139,6 +139,7 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT'
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.templates', '20', 'The default maximum number of templates that can be deployed for a project'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.templates', '20', 'The default maximum number of templates that can be deployed for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.snapshots', '20', 'The default maximum number of snapshots that can be created for a project'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.snapshots', '20', 'The default maximum number of snapshots that can be created for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.volumes', '20', 'The default maximum number of volumes that can be created for a project'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.volumes', '20', 'The default maximum number of volumes that can be created for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.networks', '20', 'The default maximum number of networks that can be created for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'project.invite.required', 'false', 'If invitation confirmation is required when add account to project. Default value is false'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'project.invite.required', 'false', 'If invitation confirmation is required when add account to project. Default value is false');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'project.invite.timeout', '86400', 'Invitation expiration time (in seconds). Default is 1 day - 86400 seconds'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'project.invite.timeout', '86400', 'Invitation expiration time (in seconds). Default is 1 day - 86400 seconds');
@ -716,3 +717,5 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag
UPDATE `cloud`.`network_offerings` SET display_text='Offering for Shared Security group enabled networks' where display_text='System-Guest-Network'; UPDATE `cloud`.`network_offerings` SET display_text='Offering for Shared Security group enabled networks' where display_text='System-Guest-Network';
UPDATE `cloud`.`configuration` SET category = 'Secure' where name in ('alert.smtp.password', 'network.loadbalancer.haproxy.stats.auth', 'security.singlesignon.key', 'project.smtp.password'); UPDATE `cloud`.`configuration` SET category = 'Secure' where name in ('alert.smtp.password', 'network.loadbalancer.haproxy.stats.auth', 'security.singlesignon.key', 'project.smtp.password');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.networks', '20', 'The default maximum number of networks that can be created for an account');