mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss
This commit is contained in:
commit
ac0275b3e8
|
|
@ -25,3 +25,4 @@ deps/cloud.userlibraries
|
|||
.DS_Store
|
||||
.idea
|
||||
*.iml
|
||||
*.swp
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,5 @@ public interface EventDao extends GenericDao<EventVO, Long> {
|
|||
|
||||
public List<EventVO> listOlderEvents(Date oldTime);
|
||||
|
||||
List<EventVO> listStartedEvents(Date minTime, Date maxTime);
|
||||
|
||||
EventVO findCompletedEvent(long startId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,16 +35,9 @@ import com.cloud.utils.db.SearchCriteria;
|
|||
@Local(value={EventDao.class})
|
||||
public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements EventDao {
|
||||
public static final Logger s_logger = Logger.getLogger(EventDaoImpl.class.getName());
|
||||
protected final SearchBuilder<EventVO> StartedEventsSearch;
|
||||
protected final SearchBuilder<EventVO> 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<EventVO, Long> implements Event
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventVO> listStartedEvents(Date minTime, Date maxTime) {
|
||||
if (minTime == null || maxTime == null) return null;
|
||||
SearchCriteria<EventVO> 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<EventVO> sc = CompletedEventSearch.create();
|
||||
|
|
|
|||
|
|
@ -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<String> files = new ArrayList<String>();
|
||||
|
|
|
|||
|
|
@ -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<? extends FirewallRule> rules) throws ResourceUnavailableException {
|
||||
protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<PublicIp> publicIps) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
List<PublicIp> firewallPublicIps = new ArrayList<PublicIp>();
|
||||
List<PublicIp> loadbalncerPublicIps = new ArrayList<PublicIp>();
|
||||
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
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<PublicIp> publicIps) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
List<PublicIp> srcNatpublicIps = new ArrayList<PublicIp>();
|
||||
|
||||
// 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<PublicIp> allIps = new ArrayList<PublicIp>();
|
||||
|
||||
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<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.LoadBalancing);
|
||||
if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
|
||||
return Purpose.LoadBalancing;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewall_rules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall);
|
||||
if (firewall_rules != null && !firewall_rules.isEmpty()) {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat);
|
||||
if (staticNatRules != null && !staticNatRules.isEmpty()) {
|
||||
return Purpose.StaticNat;
|
||||
}
|
||||
|
||||
List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByIp(ip.getId());
|
||||
if (pfRules != null && !pfRules.isEmpty()) {
|
||||
return Purpose.PortForwarding;
|
||||
}
|
||||
} else {
|
||||
List<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.LoadBalancing);
|
||||
if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
|
||||
return Purpose.LoadBalancing;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewall_rules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.Firewall);
|
||||
if (firewall_rules != null && !firewall_rules.isEmpty()) {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.StaticNat);
|
||||
if (staticNatRules != null && !staticNatRules.isEmpty()) {
|
||||
return Purpose.StaticNat;
|
||||
}
|
||||
|
||||
List<PortForwardingRuleVO> 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<? extends Network> 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<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
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<? extends StaticNat> 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<PublicIp> staticNatIps = new ArrayList<PublicIp>();
|
||||
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<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
|
||||
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
|
||||
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ public interface ManagementServer extends ManagementService {
|
|||
*/
|
||||
List<EventVO> getEvents(long userId, long accountId, Long domainId, String type, String level, Date startDate, Date endDate);
|
||||
|
||||
List<EventVO> listPendingEvents(int entryTime, int duration);
|
||||
|
||||
//FIXME - move all console proxy related commands to corresponding managers
|
||||
ConsoleProxyInfo getConsoleProxyForVm(long dataCenterId, long userVmId);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<EventVO> 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<EventVO> startedEvents = _eventDao.searchAllEvents(sc, searchFilter);
|
||||
List<EventVO> pendingEvents = new ArrayList<EventVO>();
|
||||
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<EventVO> 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<EventVO> startedEvents = _eventDao.listStartedEvents(minTime, maxTime);
|
||||
List<EventVO> pendingEvents = new ArrayList<EventVO>();
|
||||
for (EventVO event : startedEvents) {
|
||||
EventVO completedEvent = _eventDao.findCompletedEvent(event.getId());
|
||||
if (completedEvent == null) {
|
||||
pendingEvents.add(event);
|
||||
}
|
||||
}
|
||||
return pendingEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> listCapabilities(ListCapabilitiesCmd cmd) {
|
||||
Map<String, Object> capabilities = new HashMap<String, Object>();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -192,7 +192,8 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase<VMTemplateHostVO, Long
|
|||
public VMTemplateHostVO findByHostTemplate(long hostId, long templateId) {
|
||||
SearchCriteria<VMTemplateHostVO> 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<SwiftVO> listSwifts(ListSwiftsCmd cmd);
|
||||
|
||||
VMTemplateSwiftVO findByTmpltId(Long tmpltId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SwiftVO> listSwifts(ListSwiftsCmd cmd) {
|
||||
if (cmd.getId() == null) {
|
||||
return _swiftDao.listAll();
|
||||
} else {
|
||||
List<SwiftVO> list = new ArrayList<SwiftVO>();
|
||||
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<SwiftVO> 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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: []
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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') {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 = $('<div>').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 $('<div>').addClass('management').data('tab-title', 'Users');
|
||||
},
|
||||
|
||||
invitations: function() {
|
||||
return $('<div>').addClass('management-invite').data('tab-title', 'Invitations');
|
||||
},
|
||||
|
||||
resources: function() {
|
||||
var $resources = $('<div>').addClass('resources').data('tab-title', 'Resources');
|
||||
var $form = $('<form>');
|
||||
var $submit = $('<input>').attr({
|
||||
type: 'submit'
|
||||
}).val('Apply');
|
||||
|
||||
cloudStack.projects.resourceManagement.dataProvider({
|
||||
response: {
|
||||
success: function(args) {
|
||||
$(args.data).each(function() {
|
||||
var resource = this;
|
||||
var $field = $('<div>').addClass('field');
|
||||
var $label = $('<label>').attr({
|
||||
for: resource.type
|
||||
}).html(resource.label);
|
||||
var $input = $('<input>').attr({
|
||||
type: 'text',
|
||||
name: resource.type,
|
||||
value: resource.value
|
||||
}).addClass('required');
|
||||
|
||||
$field.append($label, $input);
|
||||
$field.appendTo($form);
|
||||
});
|
||||
|
||||
$form.validate();
|
||||
$form.submit(function() {
|
||||
if (!$form.valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var $loading = $('<div>').addClass('loading-overlay').appendTo($form);
|
||||
|
||||
cloudStack.projects.resourceManagement.update({
|
||||
data: cloudStack.serializeForm($form),
|
||||
response: {
|
||||
success: function(args) {
|
||||
$loading.remove();
|
||||
$('.notifications').notifications('add', {
|
||||
section: 'dashboard',
|
||||
desc: 'Updated project resources',
|
||||
interval: 1000,
|
||||
poll: function(args) {
|
||||
args.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$submit.appendTo($form);
|
||||
$form.appendTo($resources);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $resources;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Projects dashboard
|
||||
*/
|
||||
dashboard: function() {
|
||||
var tabs = {
|
||||
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 = $('<div>').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;
|
||||
}
|
||||
dashboard: pageElems.dashboardTabs.overview
|
||||
};
|
||||
|
||||
// Only show management tabs to owner of project
|
||||
|
|
@ -89,78 +164,13 @@
|
|||
cloudStack.context.projects &&
|
||||
(cloudStack.context.projects[0].account == cloudStack.context.users[0].account)
|
||||
)) {
|
||||
tabs.users = function() {
|
||||
return $('<div>').addClass('management').data('tab-title', 'Users');
|
||||
};
|
||||
tabs.users = pageElems.dashboardTabs.users;
|
||||
|
||||
if (g_capabilities.projectinviterequired) {
|
||||
tabs.invitations = function() {
|
||||
return $('<div>').addClass('management-invite').data('tab-title', 'Invitations');
|
||||
};
|
||||
tabs.invitations = pageElems.dashboardTabs.invitations;
|
||||
}
|
||||
|
||||
tabs.resources = function() {
|
||||
var $resources = $('<div>').addClass('resources').data('tab-title', 'Resources');
|
||||
var $form = $('<form>');
|
||||
var $submit = $('<input>').attr({
|
||||
type: 'submit'
|
||||
}).val('Apply');
|
||||
|
||||
cloudStack.projects.resourceManagement.dataProvider({
|
||||
response: {
|
||||
success: function(args) {
|
||||
$(args.data).each(function() {
|
||||
var resource = this;
|
||||
var $field = $('<div>').addClass('field');
|
||||
var $label = $('<label>').attr({
|
||||
for: resource.type
|
||||
}).html(resource.label);
|
||||
var $input = $('<input>').attr({
|
||||
type: 'text',
|
||||
name: resource.type,
|
||||
value: resource.value
|
||||
}).addClass('required');
|
||||
|
||||
$field.append($label, $input);
|
||||
$field.appendTo($form);
|
||||
});
|
||||
|
||||
$form.validate();
|
||||
$form.submit(function() {
|
||||
if (!$form.valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var $loading = $('<div>').addClass('loading-overlay').appendTo($form);
|
||||
|
||||
cloudStack.projects.resourceManagement.update({
|
||||
data: cloudStack.serializeForm($form),
|
||||
response: {
|
||||
success: function(args) {
|
||||
$loading.remove();
|
||||
$('.notifications').notifications('add', {
|
||||
section: 'dashboard',
|
||||
desc: 'Updated project resources',
|
||||
interval: 1000,
|
||||
poll: function(args) {
|
||||
args.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$submit.appendTo($form);
|
||||
$form.appendTo($resources);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $resources;
|
||||
};
|
||||
tabs.resources = pageElems.dashboardTabs.resources;
|
||||
}
|
||||
|
||||
var $tabs = $('<div>').addClass('tab-content').append($('<ul>'));
|
||||
|
|
@ -328,7 +338,11 @@
|
|||
);
|
||||
|
||||
var $users = $('<div>').attr({ id: 'new-project-review-tabs-users' }).appendTo($tabs);
|
||||
var $resouces = $('<div>').attr({ id: 'new-project-review-tabs-resouces' }).appendTo($tabs).html('(Resources go here)');
|
||||
cloudStack.context.projects = [project];
|
||||
var $resouces = $('<div>')
|
||||
.attr({ id: 'new-project-review-tabs-resouces' })
|
||||
.appendTo($tabs)
|
||||
.append(pageElems.dashboardTabs.resources);
|
||||
|
||||
$tabs.tabs();
|
||||
|
||||
|
|
@ -383,11 +397,12 @@
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Save button
|
||||
var $saveButton = $nextButton.clone().appendTo($review);
|
||||
$saveButton.html('Save');
|
||||
$saveButton.click(function() {
|
||||
$('#new-project-review-tabs-resouces').find('form').submit();
|
||||
$('.ui-dialog, .overlay').remove();
|
||||
});
|
||||
|
||||
|
|
@ -399,12 +414,16 @@
|
|||
|
||||
return $review;
|
||||
});
|
||||
|
||||
$(':ui-dialog').dialog('option', 'position', 'center');
|
||||
});
|
||||
$laterButton.html('Close').appendTo($userManagement);
|
||||
|
||||
return $userManagement;
|
||||
});
|
||||
|
||||
$(':ui-dialog').dialog('option', 'position', 'center');
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue