diff --git a/.gitignore b/.gitignore index 784ca1b1ba3..7d89223ac65 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ deps/cloud.userlibraries .DS_Store .idea *.iml +*.swp diff --git a/api/src/com/cloud/api/commands/DeleteAccountCmd.java b/api/src/com/cloud/api/commands/DeleteAccountCmd.java old mode 100644 new mode 100755 index 7e35858b24b..e24495726af --- a/api/src/com/cloud/api/commands/DeleteAccountCmd.java +++ b/api/src/com/cloud/api/commands/DeleteAccountCmd.java @@ -72,7 +72,7 @@ public class DeleteAccountCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - Account account = _entityMgr.findById(Account.class, getId()); + Account account = UserContext.current().getCaller();// Let's give the caller here for event logging. if (account != null) { return account.getAccountId(); } diff --git a/api/src/com/cloud/api/commands/ListSwiftsCmd.java b/api/src/com/cloud/api/commands/ListSwiftsCmd.java index 42cde414e17..04edb1b318f 100644 --- a/api/src/com/cloud/api/commands/ListSwiftsCmd.java +++ b/api/src/com/cloud/api/commands/ListSwiftsCmd.java @@ -24,10 +24,9 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd; +import com.cloud.api.BaseListCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; import com.cloud.api.response.HostResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.SwiftResponse; @@ -35,9 +34,9 @@ import com.cloud.storage.Swift; import com.cloud.user.Account; @Implementation(description = "List Swift.", responseObject = HostResponse.class) -public class ListSwiftsCmd extends BaseCmd { +public class ListSwiftsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListSwiftsCmd.class.getName()); - private static final String s_name = "listswiftresponse"; + private static final String s_name = "listswiftsresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -79,12 +78,9 @@ public class ListSwiftsCmd extends BaseCmd { swiftResponse.setObjectName("swift"); swiftResponses.add(swiftResponse); } - response.setResponses(swiftResponses); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - - } else { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to add Swift"); } + response.setResponses(swiftResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); } } diff --git a/core/src/com/cloud/event/dao/EventDao.java b/core/src/com/cloud/event/dao/EventDao.java index 58390bb58ff..ce834e1b00d 100644 --- a/core/src/com/cloud/event/dao/EventDao.java +++ b/core/src/com/cloud/event/dao/EventDao.java @@ -31,7 +31,5 @@ public interface EventDao extends GenericDao { public List listOlderEvents(Date oldTime); - List listStartedEvents(Date minTime, Date maxTime); - EventVO findCompletedEvent(long startId); } diff --git a/core/src/com/cloud/event/dao/EventDaoImpl.java b/core/src/com/cloud/event/dao/EventDaoImpl.java index c508a003249..de6f64b5449 100644 --- a/core/src/com/cloud/event/dao/EventDaoImpl.java +++ b/core/src/com/cloud/event/dao/EventDaoImpl.java @@ -35,16 +35,9 @@ import com.cloud.utils.db.SearchCriteria; @Local(value={EventDao.class}) public class EventDaoImpl extends GenericDaoBase implements EventDao { public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName()); - protected final SearchBuilder StartedEventsSearch; protected final SearchBuilder CompletedEventSearch; public EventDaoImpl () { - StartedEventsSearch = createSearchBuilder(); - StartedEventsSearch.and("state",StartedEventsSearch.entity().getState(),SearchCriteria.Op.NEQ); - StartedEventsSearch.and("startId", StartedEventsSearch.entity().getStartId(), SearchCriteria.Op.EQ); - StartedEventsSearch.and("createDate", StartedEventsSearch.entity().getCreateDate(), SearchCriteria.Op.BETWEEN); - StartedEventsSearch.done(); - CompletedEventSearch = createSearchBuilder(); CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); @@ -65,16 +58,6 @@ public class EventDaoImpl extends GenericDaoBase implements Event } - @Override - public List listStartedEvents(Date minTime, Date maxTime) { - if (minTime == null || maxTime == null) return null; - SearchCriteria sc = StartedEventsSearch.create(); - sc.setParameters("state", State.Completed); - sc.setParameters("startId", 0); - sc.setParameters("createDate", minTime, maxTime); - return listIncludingRemovedBy(sc, null); - } - @Override public EventVO findCompletedEvent(long startId) { SearchCriteria sc = CompletedEventSearch.create(); diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 7ce5e212a8a..8ea82e1d3a0 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -177,7 +177,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S try { String parent = getRootDir(secondaryStorageUrl); String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString(); - String result = swiftDownload(swift, "T-" + templateId.toString(), "", lPath); + String result = swiftDownloadContainer(swift, "T-" + templateId.toString(), lPath); if (result != null) { String errMsg = "failed to download template from Swift to secondary storage " + lPath + " , err=" + result; s_logger.warn(errMsg); @@ -268,6 +268,32 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } + String swiftDownloadContainer(SwiftTO swift, String container, String ldir) { + Script command = new Script("/bin/bash", s_logger); + command.add("-c"); + command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + + swift.getKey() + " download " + container); + OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); + String result = command.execute(parser); + if (result != null) { + String errMsg = "swiftDownloadContainer failed err=" + result; + s_logger.warn(errMsg); + return errMsg; + } + if (parser.getLines() != null) { + String[] lines = parser.getLines().split("\\n"); + for (String line : lines) { + if (line.contains("Errno") || line.contains("failed")) { + String errMsg = "swiftDownloadContainer failed , err=" + lines.toString(); + s_logger.warn(errMsg); + return errMsg; + } + } + } + return null; + + } + String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) { long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L; List files = new ArrayList(); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 1be3b72c696..f94511bd796 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -269,6 +269,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject FirewallRulesDao _firewallDao; @Inject + PortForwardingRulesDao _portForwardingDao; + @Inject ResourceLimitService _resourceLimitMgr; @Inject DomainRouterDao _routerDao; @Inject DomainManager _domainMgr; @@ -576,7 +578,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - boolean success = applyIpAssociations(network, continueOnError, publicIps); + boolean success = applyIpAssociations(network, false, continueOnError, publicIps); if (success) { for (IPAddressVO addr : userIps) { @@ -601,87 +603,98 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } - protected boolean applyProviderIpAssociations(Network network, Purpose purpose, boolean continueOnError, List rules) throws ResourceUnavailableException { + protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List publicIps) throws ResourceUnavailableException { boolean success = true; + List firewallPublicIps = new ArrayList(); + List loadbalncerPublicIps = new ArrayList(); - List publicIps = new ArrayList(); - for (FirewallRule rule : rules) { - IPAddressVO lbIp = _ipAddressDao.findById(rule.getSourceIpAddressId()); - PublicIp publicIp = new PublicIp(lbIp, _vlanDao.findById(lbIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(lbIp.getMacAddress())); - publicIps.add(publicIp); - } - - for (NetworkElement ne : _networkElements) { - try { - boolean handled; - switch (purpose) { - case LoadBalancing: - if (!(ne instanceof LoadBalancingServiceProvider)) { - continue; - } - LoadBalancingServiceProvider lbProvider = (LoadBalancingServiceProvider) ne; - s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); - handled = lbProvider.applyLoadBalancerIp(network, publicIps); - break; - - case PortForwarding: - if (!(ne instanceof PortForwardingServiceProvider)) { - continue; - } - PortForwardingServiceProvider pfProvider = (PortForwardingServiceProvider) ne; - s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); - handled = pfProvider.applyIps(network, publicIps); - break; - - case StaticNat: - case Firewall: - if (!(ne instanceof FirewallServiceProvider)) { - continue; - } - s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); - FirewallServiceProvider fwProvider = (FirewallServiceProvider) ne; - handled = fwProvider.applyIps(network, publicIps); - break; - - default: - s_logger.debug("Unable to handle IP association for purpose: " + purpose.toString()); - handled = false; - } - s_logger.debug("Network Rules for network " + network.getId() + " were " + (handled ? "" : " not") + " handled by " + ne.getName()); - } catch (ResourceUnavailableException e) { - success = false; - if (!continueOnError) { - throw e; + if (publicIps != null && !publicIps.isEmpty()) { + for (PublicIp ip : publicIps) { + if (ip.isSourceNat()) { + // Source nat ip address should always be sent first + firewallPublicIps.add(0, ip); + } else if (ip.isOneToOneNat()) { + firewallPublicIps.add(ip); } else { - s_logger.debug("Resource is not available: " + ne.getName(), e); + //if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service provider + if (ip.getState() == State.Allocating) { + continue; + } + + // check if any active rules are applied on the public IP + Purpose purpose = getPublicIpPurpose(ip, false); + if (purpose == null) { + // since no active rules are there check if any rules are applied on the public IP but are in revoking state + purpose = getPublicIpPurpose(ip, true); + if (purpose == null) { + // IP is not being used for any purpose so skip IPAssoc to network service provider + continue; + } else { + if (rulesRevoked) { + // no active rules/revoked rules are associated with this public IP, so remove the association with the provider + ip.setState(State.Releasing); + } else { + if (ip.getState() == State.Releasing) { + // rules are not revoked yet, so don't let the network service provider revoke the IP association + // mark IP is allocated so that IP association will not be removed from the provider + ip.setState(State.Allocated); + } + } + } + } + + switch(purpose) { + case LoadBalancing: + loadbalncerPublicIps.add(ip); + break; + + case PortForwarding: + case StaticNat: + case Firewall: + firewallPublicIps.add(ip); + break; + default: + } } } } - return success; - } - - protected boolean applyIpAssociations(Network network, boolean continueOnError, List publicIps) throws ResourceUnavailableException { - boolean success = true; - List srcNatpublicIps = new ArrayList(); - - // apply IP only for source NAT public IP at this point. Depending on the network service for which - // public IP will be used do IP Association to respective network service provider before apply rules - if (publicIps != null && !publicIps.isEmpty()) { - for (PublicIp ip : publicIps) { - if (ip.isSourceNat()) { - srcNatpublicIps.add(ip); - } - } - } - + + String lbProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Lb); + String fwProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Firewall); + for (NetworkElement element : _networkElements) { try { - if (!(element instanceof FirewallServiceProvider)) { + if (element instanceof FirewallServiceProvider && element instanceof LoadBalancingServiceProvider) { + List allIps = new ArrayList(); + + if (lbProvider.equalsIgnoreCase(element.getProvider().getName()) && fwProvider.equalsIgnoreCase(element.getProvider().getName())) { + allIps.addAll(firewallPublicIps); + allIps.addAll(loadbalncerPublicIps); + } else if (fwProvider.equalsIgnoreCase(element.getProvider().getName())) { + allIps.addAll(firewallPublicIps); + } else if (lbProvider.equalsIgnoreCase(element.getProvider().getName())) { + allIps.addAll(loadbalncerPublicIps); + } else { + continue; + } + + FirewallServiceProvider fwElement = (FirewallServiceProvider)element; + fwElement.applyIps(network, allIps); + } else if (element instanceof FirewallServiceProvider) { + FirewallServiceProvider fwElement = (FirewallServiceProvider)element; + if (fwProvider.equalsIgnoreCase(element.getProvider().getName())) { + fwElement.applyIps(network, firewallPublicIps); + } + } else if (element instanceof LoadBalancingServiceProvider) { + LoadBalancingServiceProvider lbElement = (LoadBalancingServiceProvider) element; + if (lbProvider.equalsIgnoreCase(element.getProvider().getName())) { + if (loadbalncerPublicIps != null && !loadbalncerPublicIps.isEmpty()) { + lbElement.applyLoadBalancerIp(network, publicIps); + } + } + } else { continue; } - FirewallServiceProvider e = (FirewallServiceProvider)element; - s_logger.trace("Asking " + element + " to apply ip associations"); - e.applyIps(network, srcNatpublicIps); } catch (ResourceUnavailableException e) { success = false; if (!continueOnError) { @@ -691,10 +704,56 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } + return success; } + Purpose getPublicIpPurpose(PublicIp ip, boolean includeRevoked) { + if (includeRevoked) { + List loadBalancingRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.LoadBalancing); + if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) { + return Purpose.LoadBalancing; + } + List firewall_rules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall); + if (firewall_rules != null && !firewall_rules.isEmpty()) { + return Purpose.Firewall; + } + + List staticNatRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat); + if (staticNatRules != null && !staticNatRules.isEmpty()) { + return Purpose.StaticNat; + } + + List pfRules = _portForwardingDao.listByIp(ip.getId()); + if (pfRules != null && !pfRules.isEmpty()) { + return Purpose.PortForwarding; + } + } else { + List loadBalancingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.LoadBalancing); + if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) { + return Purpose.LoadBalancing; + } + + List firewall_rules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.Firewall); + if (firewall_rules != null && !firewall_rules.isEmpty()) { + return Purpose.Firewall; + } + + List staticNatRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.StaticNat); + if (staticNatRules != null && !staticNatRules.isEmpty()) { + return Purpose.StaticNat; + } + + List pfRules = _portForwardingDao.listByIpAndNotRevoked(ip.getId()); + if (pfRules != null && !pfRules.isEmpty()) { + return Purpose.PortForwarding; + } + } + + // we are here means, public IP has no active/revoked rules to know the purpose + return null; + } @Override public List getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) { @@ -2655,8 +2714,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Network network = _networksDao.findById(rules.get(0).getNetworkId()); Purpose purpose = rules.get(0).getPurpose(); - // associate the IP with corresponding network service provider - applyProviderIpAssociations(network, purpose, continueOnError, rules); + // get the list of public ip's owned by the network + List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); + List publicIps = new ArrayList(); + if (userIps != null && !userIps.isEmpty()) { + for (IPAddressVO userIp : userIps) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + publicIps.add(publicIp); + } + } + + // rules can not programmed unless IP is associated with network service provider, so run IP assoication for + // the network so as to ensure IP is associated before applying rules (in add state) + applyIpAssociations(network, false, continueOnError, publicIps); for (NetworkElement ne : _networkElements) { try { @@ -2697,6 +2767,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + // if all the rules configured on public IP are revoked then dis-associate IP with network service provider + applyIpAssociations(network, true, continueOnError, publicIps); + return success; } @@ -3701,35 +3774,35 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean applyStaticNats(List staticNats, boolean continueOnError) throws ResourceUnavailableException { - if (staticNats == null || staticNats.size() == 0) { + Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); + boolean success = true; + + if (staticNats == null || staticNats.size() == 0) { s_logger.debug("There are no static nat rules for the network elements"); return true; } - List staticNatIps = new ArrayList(); - for (StaticNat rule : staticNats) { - IPAddressVO staticNatIP = _ipAddressDao.findById(rule.getSourceIpAddressId()); - PublicIp publicIp = new PublicIp(staticNatIP, _vlanDao.findById(staticNatIP.getVlanId()), NetUtils.createSequenceBasedMacAddress(staticNatIP.getMacAddress())); - staticNatIps.add(publicIp); + // get the list of public ip's owned by the network + List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); + List publicIps = new ArrayList(); + if (userIps != null && !userIps.isEmpty()) { + for (IPAddressVO userIp : userIps) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + publicIps.add(publicIp); + } } - - boolean success = true; - boolean handled = false; - Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); + + // static NAT rules can not programmed unless IP is associated with network service provider, so run IP association for + // the network so as to ensure IP is associated before applying rules (in add state) + applyIpAssociations(network, false, continueOnError, publicIps); + for (NetworkElement ne : _networkElements) { try { if (!(ne instanceof StaticNatServiceProvider)) { continue; } - // associate the IP's with StaticNatServiceProvider for the network - handled = ((StaticNatServiceProvider)ne).applyIps(network, staticNatIps); - if(!handled) { - s_logger.debug(ne.getName() +" did not assocate IP with source Nat service provider for the network " + network.getId() + "so skippg apply static nats"); - continue; - } - - handled = ((StaticNatServiceProvider)ne).applyStaticNats(network, staticNats); + boolean handled = ((StaticNatServiceProvider)ne).applyStaticNats(network, staticNats); s_logger.debug("Static Nat for network " + network.getId() + " were " + (handled ? "" : " not") + " handled by " + ne.getName()); } catch (ResourceUnavailableException e) { if (!continueOnError) { @@ -3740,6 +3813,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + // if all the rules configured on public IP are revoked then, dis-associate IP with network service provider + applyIpAssociations(network, true, continueOnError, publicIps); + return success; } @@ -4770,7 +4846,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } try { - if (!applyIpAssociations(network, true, publicIpsToRelease)) { + if (!applyIpAssociations(network, true, true, publicIpsToRelease)) { s_logger.warn("Unable to apply ip address associations for " + network + " as a part of shutdownNetworkRules"); success = false; } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 225d8e43221..d384d2e0198 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1758,11 +1758,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (!publicIps.isEmpty()) { - // Re-apply public ip addresses - should come before PF/LB/VPN - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) { - createAssociateIPCommands(router, publicIps, cmds, 0); - } - List vpns = new ArrayList(); List pfRules = new ArrayList(); List staticNatFirewallRules = new ArrayList(); diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index c623685e8e8..2a6de5c7251 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -78,8 +78,6 @@ public interface ManagementServer extends ManagementService { */ List getEvents(long userId, long accountId, Long domainId, String type, String level, Date startDate, Date endDate); - List listPendingEvents(int entryTime, int duration); - //FIXME - move all console proxy related commands to corresponding managers ConsoleProxyInfo getConsoleProxyForVm(long dataCenterId, long userVmId); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 3ffab2f58d3..67630053992 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1500,13 +1500,6 @@ public class ManagementServerImpl implements ManagementServer { Integer entryTime = cmd.getEntryTime(); Integer duration = cmd.getDuration(); - if ((entryTime != null) && (duration != null)) { - if (entryTime <= duration) { - throw new InvalidParameterValueException("Entry time must be greater than duration"); - } - return listPendingEvents(entryTime, duration); - } - SearchBuilder sb = _eventDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("levelL", sb.entity().getLevel(), SearchCriteria.Op.LIKE); @@ -1519,6 +1512,9 @@ public class ManagementServerImpl implements ManagementServer { sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ); sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ); sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ); + sb.and("state", sb.entity().getState(),SearchCriteria.Op.NEQ); + sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ); + sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN); if (isAdmin && permittedAccounts.isEmpty() && domainId != null) { // if accountId isn't specified, we can do a domain match for the admin case @@ -1565,8 +1561,33 @@ public class ManagementServerImpl implements ManagementServer { } else if (endDate != null) { sc.setParameters("createDateL", endDate); } - - return _eventDao.searchAllEvents(sc, searchFilter); + + if ((entryTime != null) && (duration != null)) { + if (entryTime <= duration) { + throw new InvalidParameterValueException("Entry time must be greater than duration"); + } + Calendar calMin = Calendar.getInstance(); + Calendar calMax = Calendar.getInstance(); + calMin.add(Calendar.SECOND, -entryTime); + calMax.add(Calendar.SECOND, -duration); + Date minTime = calMin.getTime(); + Date maxTime = calMax.getTime(); + + sc.setParameters("state", com.cloud.event.Event.State.Completed); + sc.setParameters("startId", 0); + sc.setParameters("createDate", minTime, maxTime); + List startedEvents = _eventDao.searchAllEvents(sc, searchFilter); + List pendingEvents = new ArrayList(); + for (EventVO event : startedEvents) { + EventVO completedEvent = _eventDao.findCompletedEvent(event.getId()); + if (completedEvent == null) { + pendingEvents.add(event); + } + } + return pendingEvents; + } else { + return _eventDao.searchAllEvents(sc, searchFilter); + } } @@ -3072,25 +3093,6 @@ public class ManagementServerImpl implements ManagementServer { return cloudParams; } - @Override - public List listPendingEvents(int entryTime, int duration) { - Calendar calMin = Calendar.getInstance(); - Calendar calMax = Calendar.getInstance(); - calMin.add(Calendar.SECOND, -entryTime); - calMax.add(Calendar.SECOND, -duration); - Date minTime = calMin.getTime(); - Date maxTime = calMax.getTime(); - List startedEvents = _eventDao.listStartedEvents(minTime, maxTime); - List pendingEvents = new ArrayList(); - for (EventVO event : startedEvents) { - EventVO completedEvent = _eventDao.findCompletedEvent(event.getId()); - if (completedEvent == null) { - pendingEvents.add(event); - } - } - return pendingEvents; - } - @Override public Map listCapabilities(ListCapabilitiesCmd cmd) { Map capabilities = new HashMap(); diff --git a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java index 88bc676cafd..770d14674fb 100755 --- a/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java +++ b/server/src/com/cloud/storage/allocator/AbstractStoragePoolAllocator.java @@ -46,6 +46,7 @@ import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume.Type; import com.cloud.storage.dao.StoragePoolDao; @@ -54,6 +55,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.swift.SwiftManager; import com.cloud.template.TemplateManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -75,6 +77,8 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement @Inject StoragePoolHostDao _poolHostDao; @Inject ConfigurationDao _configDao; @Inject ClusterDao _clusterDao; + @Inject + SwiftManager _swiftMgr; float _storageOverprovisioningFactor; long _extraBytesPerVolume = 0; Random _rand; @@ -238,7 +242,15 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement VMTemplateHostVO templateHostVO = _storageMgr.findVmTemplateHost(template.getId(), pool); if (templateHostVO == null) { - s_logger.info("Did not find template downloaded on secondary hosts in zone " + plan.getDataCenterId()); + VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(template.getId()); + if (templateSwiftVO == null) { + s_logger.info("Did not find template downloaded on secondary hosts in zone " + plan.getDataCenterId()); + } + long templateSize = templateSwiftVO.getPhysicalSize(); + if (templateSize == 0) { + templateSize = templateSwiftVO.getSize(); + } + totalAllocatedSize += (templateSize + _extraBytesPerVolume); return false; } else { long templateSize = templateHostVO.getPhysicalSize(); diff --git a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java index be32cae63c2..796be63f9e1 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java @@ -192,7 +192,8 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase sc = HostTemplateSearch.create(); sc.setParameters("host_id", hostId); - sc.setParameters("template_id", templateId); + sc.setParameters("template_id", templateId); + sc.setParameters("download_state", Status.DOWNLOADED.toString()); return findOneIncludingRemovedBy(sc); } diff --git a/server/src/com/cloud/storage/swift/SwiftManager.java b/server/src/com/cloud/storage/swift/SwiftManager.java index de7797c59f8..61f23096386 100644 --- a/server/src/com/cloud/storage/swift/SwiftManager.java +++ b/server/src/com/cloud/storage/swift/SwiftManager.java @@ -34,6 +34,7 @@ import com.cloud.api.commands.ListSwiftsCmd; import com.cloud.exception.DiscoveryException; import com.cloud.storage.Swift; import com.cloud.storage.SwiftVO; +import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.utils.component.Manager; public interface SwiftManager extends Manager { @@ -58,4 +59,6 @@ public interface SwiftManager extends Manager { Long chooseZoneForTmpltExtract(Long tmpltId); List listSwifts(ListSwiftsCmd cmd); + + VMTemplateSwiftVO findByTmpltId(Long tmpltId); } diff --git a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java index 5a4782fc42f..75daa6e3d9f 100644 --- a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java +++ b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java @@ -59,6 +59,8 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.utils.component.Inject; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -267,16 +269,19 @@ public class SwiftManagerImpl implements SwiftManager { @Override public List listSwifts(ListSwiftsCmd cmd) { - if (cmd.getId() == null) { - return _swiftDao.listAll(); - } else { - List list = new ArrayList(); - SwiftVO swift = _swiftDao.findById(cmd.getId()); - list.add(swift); - return list; + Filter searchFilter = new Filter(SwiftVO.class, "id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchCriteria sc = _swiftDao.createSearchCriteria(); + if (cmd.getId() != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, cmd.getId()); } + return _swiftDao.search(sc, searchFilter); + } + @Override + public VMTemplateSwiftVO findByTmpltId(Long tmpltId) { + return _vmTmpltSwiftlDao.findOneByTemplateId(tmpltId); + } @Override public boolean stop() { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index bea8cc0c321..fe0297f7aa7 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -475,7 +475,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe s_logger.warn(errMsg); return errMsg; } - VMTemplateSwiftVO tmpltSwift = _tmpltSwiftDao.findOneByTemplateId(templateId); + VMTemplateSwiftVO tmpltSwift = _swiftMgr.findByTmpltId(templateId); if ( tmpltSwift == null ) { String errMsg = " Template " + templateId + " doesn't exist in swift"; s_logger.warn(errMsg); diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 932692cb6a8..ecd22a23cf2 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7121,6 +7121,22 @@ div.panel.ui-dialog div.list-view div.fixed-header { margin: -2px 0 -4px auto; } +#new-project-review-tabs-resouces { + background: #D2D2D2; +} + +.new-project .resources .ui-widget-content { + background: #FFFFFF; +} + +.new-project .resources .field { + height: 39px; + padding: 0; +} + +.new-project .resources .field input { +} + .new-project .field span.value { color: #475765; /*+placement:shift 21px 20px;*/ @@ -7140,6 +7156,12 @@ div.panel.ui-dialog div.list-view div.fixed-header { padding: 20px 24px 0 0; } +.new-project .resources .field label { + font-size: 14px; + height: auto; + padding: 10px 14px 14px 40px; +} + .new-project .field label.error { color: #FF0000; font-size: 9px; @@ -7167,12 +7189,16 @@ div.panel.ui-dialog div.list-view div.fixed-header { -o-box-shadow: inset 0px 1px 0px #A1A1A1; box-shadow: inset 0px 1px 0px #A1A1A1; width: 506px; - height: 21px; + height: 20px; margin: 17px 25px 0 0; float: right; border: 1px solid #C7C7C7; } +.new-project .resources .field input[type=text] { + margin: 6px 9px 0 0; +} + .new-project .button.cancel { color: #808080; background: none; @@ -7377,6 +7403,10 @@ div.panel.ui-dialog div.list-view div.fixed-header { background-position: -3px -369px; } +.new-project .resources input[type=submit] { + display: none; +} + .new-project .multi-edit { width: 671px; } diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 465485e2c3b..b68585b768d 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -234,17 +234,21 @@ args.response.error(); } }); - - $.ajax({ - url: createURL("listSwift"), - dataType: "json", - async: false, - success: function(json) { - var items = json.ListSwiftresponse.swift; - if(items != null && items.length > 0) - havingSwift = true; - } - }); + + if (isAdmin()) { + $.ajax({ + url: createURL("listSwifts"), + dataType: "json", + async: false, + success: function(json) { + var items = json.ListSwiftresponse.swift; + if(items != null && items.length > 0) + havingSwift = true; + } + }); + } else { + havingSwift = false; + } // Get project configuration // TEMPORARY -- replace w/ output of capability response, etc., once implemented diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 3bf0f01dc34..cc53d22849f 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -305,9 +305,10 @@ args.response.success({ type: 'select-security-group', data: { - defaultNetworks: [], - optionalNetworks: [], - securityGroups: securityGroupArray + myNetworks: [], //not used any more + sharedNetworks: [], + securityGroups: securityGroupArray, + networkOfferings: [] } }); } @@ -316,9 +317,10 @@ args.response.success({ type: 'nothing-to-select', data: { - defaultNetworks: [], - optionalNetworks: [], - securityGroups: [] + myNetworks: [], //not used any more + sharedNetworks: [], + securityGroups: [], + networkOfferings: [] } }); } diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index 8c5650d88f1..3e0804b0868 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -819,7 +819,7 @@ var projectsActionFilter = function(args) { var allowedActions = ['destroy']; - if (args.context.item.account == cloudStack.context.users[0].account || args.context.users[0].role == '1') { + if (args.context.item.account == cloudStack.context.users[0].account || isAdmin()) { if (args.context.item.state == 'Suspended') { allowedActions.push('enable'); } else if (args.context.item.state == 'Active') { diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 4d852c2866b..09dfc1aaa47 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -451,8 +451,15 @@ label: 'Instance', select: function(args) { var items = []; + var url; + + if (cloudStack.context.projects && cloudStack.context.projects[0]) { + url = args.context.volumes[0].zoneid; + } else { + url = args.context.volumes[0].zoneid + "&domainid=" + args.context.volumes[0].domainid + "&account=" + args.context.volumes[0].account; + } $.ajax({ - url: createURL("listVirtualMachines&state=Running&zoneid=" + args.context.volumes[0].zoneid + "&domainid=" + args.context.volumes[0].domainid + "&account=" + args.context.volumes[0].account), + url: createURL("listVirtualMachines&state=Running&zoneid=" + url), dataType: "json", async: false, success: function(json) { @@ -463,7 +470,7 @@ } }); $.ajax({ - url: createURL("listVirtualMachines&state=Stopped&zoneid=" + args.context.volumes[0].zoneid + "&domainid=" + args.context.volumes[0].domainid + "&account=" + args.context.volumes[0].account), + url: createURL("listVirtualMachines&state=Stopped&zoneid=" + url), dataType: "json", async: false, success: function(json) { diff --git a/ui/scripts/ui-custom/projects.js b/ui/scripts/ui-custom/projects.js index 3905a547ce6..822d510edeb 100644 --- a/ui/scripts/ui-custom/projects.js +++ b/ui/scripts/ui-custom/projects.js @@ -13,75 +13,150 @@ })); }, + dashboardTabs: { + overview: function() { + var $dashboard = $('#template').find('.project-dashboard-view').clone(); + $dashboard.data('tab-title', 'Dashboard'); + + var getData = function() { + // Populate data + $dashboard.find('[data-item]').hide(); + var $loading = $('
').addClass('loading-overlay').prependTo($dashboard); + cloudStack.projects.dashboard({ + response: { + success: function(args) { + $loading.remove(); + var data = args.data; + + // Iterate over data; populate corresponding DOM elements + $.each(data, function(key, value) { + var $elem = $dashboard.find('[data-item=' + key + ']'); + + // This assumes an array of data + if ($elem.is('ul')) { + $elem.show(); + var $liTmpl = $elem.find('li').remove(); + $(value).each(function() { + var item = this; + var $li = $liTmpl.clone().appendTo($elem).hide(); + + $.each(item, function(arrayKey, arrayValue) { + var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']'); + + $arrayElem.html(arrayValue); + }); + + $li.attr({ title: item.description }); + + $li.fadeIn(); + }); + } else { + $elem.each(function() { + var $item = $(this); + if ($item.hasClass('chart-line')) { + $item.show().animate({ width: value + '%' }); + } else { + $item.hide().html(value).fadeIn(); + } + }); + } + }); + } + } + }); + }; + + getData(); + + $dashboard.find('.button.manage-resources').click(function() { + $('.navigation-item.network').click(); + }); + + $dashboard.find('.info-box.events .button').click(function() { + $('.navigation-item.events').click(); + }); + + return $dashboard; + }, + + users: function() { + return $('
').addClass('management').data('tab-title', 'Users'); + }, + + invitations: function() { + return $('
').addClass('management-invite').data('tab-title', 'Invitations'); + }, + + resources: function() { + var $resources = $('
').addClass('resources').data('tab-title', 'Resources'); + var $form = $('
'); + var $submit = $('').attr({ + type: 'submit' + }).val('Apply'); + + cloudStack.projects.resourceManagement.dataProvider({ + response: { + success: function(args) { + $(args.data).each(function() { + var resource = this; + var $field = $('
').addClass('field'); + var $label = $('