diff --git a/api/src/com/cloud/acl/ControlledEntity.java b/api/src/com/cloud/acl/ControlledEntity.java
new file mode 100644
index 00000000000..be7449d3456
--- /dev/null
+++ b/api/src/com/cloud/acl/ControlledEntity.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.acl;
+
+import com.cloud.domain.PartOf;
+import com.cloud.user.OwnedBy;
+
+/**
+ * ControlledEntity defines an object for which the access from an
+ * account can be controlled. Any object that must have limited
+ * access must inherit this interface.
+ *
+ */
+public interface ControlledEntity extends OwnedBy, PartOf {
+}
diff --git a/api/src/com/cloud/acl/SecurityChecker.java b/api/src/com/cloud/acl/SecurityChecker.java
index b878ca0b005..d39e9841c2a 100644
--- a/api/src/com/cloud/acl/SecurityChecker.java
+++ b/api/src/com/cloud/acl/SecurityChecker.java
@@ -3,12 +3,9 @@
*/
package com.cloud.acl;
-import java.security.acl.NotOwnerException;
-
-import com.cloud.domain.PartOf;
+import com.cloud.domain.Domain;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.user.Account;
-import com.cloud.user.OwnedBy;
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
@@ -25,7 +22,7 @@ public interface SecurityChecker extends Adapter {
* @return true if access allowed. false if this adapter cannot authenticate ownership.
* @throws PermissionDeniedException if this adapter is suppose to authenticate ownership and the check failed.
*/
- boolean checkOwnership(Account account, OwnedBy object) throws NotOwnerException;
+ boolean checkAccess(Account account, Domain domain) throws PermissionDeniedException;
/**
* Checks if the user belongs to an account that owns the object.
@@ -35,27 +32,27 @@ public interface SecurityChecker extends Adapter {
* @return true if access allowed. false if this adapter cannot authenticate ownership.
* @throws PermissionDeniedException if this adapter is suppose to authenticate ownership and the check failed.
*/
- boolean checkOwnership(User user, OwnedBy object) throws NotOwnerException;
+ boolean checkAccess(User user, Domain domain) throws PermissionDeniedException;
/**
* Checks if the account can access the object.
*
* @param account account to check against.
- * @param object object that the account is trying to access.
+ * @param entity object that the account is trying to access.
* @return true if access allowed. false if this adapter cannot provide permission.
* @throws PermissionDeniedException if this adapter is suppose to authenticate ownership and the check failed.
*/
- boolean checkAccess(Account account, PartOf object) throws PermissionDeniedException;
+ boolean checkAccess(Account account, ControlledEntity entity) throws PermissionDeniedException;
/**
* Checks if the user belongs to an account that can access the object.
*
* @param user user to check against.
- * @param object object that the account is trying to access.
+ * @param entity object that the account is trying to access.
* @return true if access allowed. false if this adapter cannot authenticate ownership.
* @throws PermissionDeniedException if this adapter is suppose to authenticate ownership and the check failed.
*/
- boolean checkAccess(User user, PartOf object) throws PermissionDeniedException;
+ boolean checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException;
// We should be able to use this method to check against commands. For example, we can
// annotate the command with access annotations and this method can use it to extract
diff --git a/api/src/com/cloud/exception/ConnectionException.java b/api/src/com/cloud/exception/ConnectionException.java
new file mode 100644
index 00000000000..02386a274b5
--- /dev/null
+++ b/api/src/com/cloud/exception/ConnectionException.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.exception;
+
+import com.cloud.utils.SerialVersionUID;
+
+public class ConnectionException extends Exception {
+
+ private static final long serialVersionUID = SerialVersionUID.ConnectionException;
+ boolean _error;
+
+ public ConnectionException(boolean setupError, String msg) {
+ this(setupError, msg, null);
+ }
+
+ public ConnectionException(boolean setupError, String msg, Throwable cause) {
+ super(msg, cause);
+ _error = setupError;
+
+ }
+
+ public boolean isSetupError() {
+ return _error;
+ }
+
+}
diff --git a/api/src/com/cloud/exception/PermissionDeniedException.java b/api/src/com/cloud/exception/PermissionDeniedException.java
index 1141fa6d260..bb304011aad 100644
--- a/api/src/com/cloud/exception/PermissionDeniedException.java
+++ b/api/src/com/cloud/exception/PermissionDeniedException.java
@@ -17,6 +17,7 @@
*/
package com.cloud.exception;
+import com.cloud.utils.SerialVersionUID;
import com.cloud.utils.exception.CloudRuntimeException;
/**
@@ -25,7 +26,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
*/
public class PermissionDeniedException extends CloudRuntimeException {
- private static final long serialVersionUID = -4631412831814398074L;
+ private static final long serialVersionUID = SerialVersionUID.PermissionDeniedException;
public PermissionDeniedException(String message) {
super(message);
diff --git a/api/src/com/cloud/network/NetworkConfiguration.java b/api/src/com/cloud/network/NetworkConfiguration.java
index bed8dcae9ea..25d125bc878 100644
--- a/api/src/com/cloud/network/NetworkConfiguration.java
+++ b/api/src/com/cloud/network/NetworkConfiguration.java
@@ -92,4 +92,8 @@ public interface NetworkConfiguration extends OwnedBy, PartOf {
State getState();
long getRelated();
+
+ String getBroadcastUri();
+
+ String getDns();
}
diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java
index bd663f142f6..dbcf926b93e 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -21,14 +21,13 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
-import com.cloud.domain.PartOf;
+import com.cloud.acl.ControlledEntity;
import com.cloud.template.BasedOn;
-import com.cloud.user.OwnedBy;
import com.cloud.utils.fsm.FiniteState;
import com.cloud.utils.fsm.StateMachine;
-public interface Volume extends PartOf, OwnedBy, BasedOn {
+public interface Volume extends ControlledEntity, BasedOn {
enum VolumeType {UNKNOWN, ROOT, SWAP, DATADISK, ISO};
enum MirrorState {NOT_MIRRORED, ACTIVE, DEFUNCT};
diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java
index 1697c1f5a3b..d740db19d0a 100755
--- a/api/src/com/cloud/template/VirtualMachineTemplate.java
+++ b/api/src/com/cloud/template/VirtualMachineTemplate.java
@@ -17,9 +17,9 @@
*/
package com.cloud.template;
-import com.cloud.storage.Storage.FileSystem;
+import com.cloud.acl.ControlledEntity;
-public interface VirtualMachineTemplate {
+public interface VirtualMachineTemplate extends ControlledEntity {
public static enum BootloaderType { PyGrub, HVM, External, CD };
diff --git a/api/src/com/cloud/user/Account.java b/api/src/com/cloud/user/Account.java
index d8cc9f84d4e..557bb876fb6 100644
--- a/api/src/com/cloud/user/Account.java
+++ b/api/src/com/cloud/user/Account.java
@@ -53,8 +53,10 @@ public interface Account extends PartOf {
public short getType();
public String getState();
public void setState(String state);
+ @Override
public long getDomainId();
public Date getRemoved();
public String getNetworkDomain();
public void setNetworkDomain(String networkDomain);
+
}
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java
index 1984f83eac6..70b6eab45a9 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -19,14 +19,13 @@ package com.cloud.vm;
import java.util.Date;
-import com.cloud.domain.PartOf;
-import com.cloud.user.OwnedBy;
+import com.cloud.acl.ControlledEntity;
/**
* VirtualMachine describes the properties held by a virtual machine
*
*/
-public interface VirtualMachine extends RunningOn, OwnedBy, PartOf {
+public interface VirtualMachine extends RunningOn, ControlledEntity {
public enum Event {
CreateRequested,
StartRequested,
diff --git a/core/src/com/cloud/agent/Listener.java b/core/src/com/cloud/agent/Listener.java
index 19f0babd116..6b5619cdf56 100755
--- a/core/src/com/cloud/agent/Listener.java
+++ b/core/src/com/cloud/agent/Listener.java
@@ -22,6 +22,7 @@ import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand;
+import com.cloud.exception.ConnectionException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
@@ -73,8 +74,9 @@ public interface Listener {
* been registered for host events.
* @param agentId id of the agent
* @param cmd command sent by the agent to the server on startup.
+ * @throws ConnectionException if host has problems and needs to put into maintenance state.
*/
- boolean processConnect(HostVO host, StartupCommand cmd);
+ void processConnect(HostVO host, StartupCommand cmd) throws ConnectionException;
/**
* This method is called by AgentManager when an agent disconnects
diff --git a/core/src/com/cloud/domain/DomainVO.java b/core/src/com/cloud/domain/DomainVO.java
index 9b97065723c..90ebd1e10a3 100644
--- a/core/src/com/cloud/domain/DomainVO.java
+++ b/core/src/com/cloud/domain/DomainVO.java
@@ -71,14 +71,17 @@ public class DomainVO implements Domain {
this.level = 0;
}
+ @Override
public long getId() {
return id;
}
+ @Override
public Long getParent() {
return parent;
}
+ @Override
public void setParent(Long parent) {
if(parent == null) {
this.parent = DomainVO.ROOT_DOMAIN;
@@ -90,30 +93,37 @@ public class DomainVO implements Domain {
}
}
+ @Override
public String getName() {
return name;
}
+ @Override
public void setName(String name) {
this.name = name;
}
+ @Override
public long getAccountId() {
return accountId;
}
+ @Override
public Date getRemoved() {
return removed;
}
+ @Override
public String getPath() {
return path;
}
+ @Override
public void setPath(String path) {
this.path = path;
}
+ @Override
public int getLevel() {
return level;
}
@@ -122,6 +132,7 @@ public class DomainVO implements Domain {
this.level = level;
}
+ @Override
public int getChildCount() {
return childCount;
}
@@ -130,12 +141,18 @@ public class DomainVO implements Domain {
childCount = count;
}
+ @Override
public long getNextChildSeq() {
return nextChildSeq;
}
public void setNextChildSeq(long seq) {
nextChildSeq = seq;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("Domain:").append(id).append(path).toString();
}
}
diff --git a/core/src/com/cloud/offerings/NetworkOfferingVO.java b/core/src/com/cloud/offerings/NetworkOfferingVO.java
index 6a0a4339501..e4a034c3a80 100644
--- a/core/src/com/cloud/offerings/NetworkOfferingVO.java
+++ b/core/src/com/cloud/offerings/NetworkOfferingVO.java
@@ -30,6 +30,7 @@ import javax.persistence.Table;
import com.cloud.network.Network.TrafficType;
import com.cloud.offering.NetworkOffering;
+import com.cloud.service.ServiceOfferingVO;
import com.cloud.utils.db.GenericDao;
@Entity
@@ -72,6 +73,9 @@ public class NetworkOfferingVO implements NetworkOffering {
@Column(name="system_only")
boolean systemOnly;
+ @Column(name="service_offering_id")
+ Long serviceOfferingId;
+
@Column(name="tags")
String tags;
@@ -128,6 +132,14 @@ public class NetworkOfferingVO implements NetworkOffering {
return removed;
}
+ public Long getServiceOfferingId() {
+ return serviceOfferingId;
+ }
+
+ public void setServiceOfferingId(long serviceOfferingId) {
+ this.serviceOfferingId = serviceOfferingId;
+ }
+
@Override
public Integer getConcurrentConnections() {
return concurrentConnections;
@@ -144,6 +156,50 @@ public class NetworkOfferingVO implements NetworkOffering {
public NetworkOfferingVO() {
}
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setDisplayText(String displayText) {
+ this.displayText = displayText;
+ }
+
+ public void setRateMbps(Integer rateMbps) {
+ this.rateMbps = rateMbps;
+ }
+
+ public void setMulticastRateMbps(Integer multicastRateMbps) {
+ this.multicastRateMbps = multicastRateMbps;
+ }
+
+ public void setConcurrentConnections(Integer concurrentConnections) {
+ this.concurrentConnections = concurrentConnections;
+ }
+
+ public void setGuestIpType(GuestIpType guestIpType) {
+ this.guestIpType = guestIpType;
+ }
+
+ public void setTrafficType(TrafficType trafficType) {
+ this.trafficType = trafficType;
+ }
+
+ public void setSystemOnly(boolean systemOnly) {
+ this.systemOnly = systemOnly;
+ }
+
+ public void setServiceOfferingId(Long serviceOfferingId) {
+ this.serviceOfferingId = serviceOfferingId;
+ }
+
+ public void setRemoved(Date removed) {
+ this.removed = removed;
+ }
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, GuestIpType type, boolean systemOnly, Integer rateMbps, Integer multicastRateMbps, Integer concurrentConnections) {
this.name = name;
this.displayText = displayText;
@@ -155,6 +211,11 @@ public class NetworkOfferingVO implements NetworkOffering {
this.systemOnly = systemOnly;
}
+ public NetworkOfferingVO(ServiceOfferingVO offering) {
+ this("Network Offering for " + offering.getName(), "Network Offering for " + offering.getDisplayText(), TrafficType.Guest, offering.getGuestIpType(), false, offering.getRateMbps(), offering.getMulticastRateMbps(), null);
+ this.serviceOfferingId = offering.getId();
+ }
+
/**
* Network Offering for all system vms.
* @param name
diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/core/src/com/cloud/storage/VMTemplateVO.java
index f21e28a1b85..87ee98bc1e3 100644
--- a/core/src/com/cloud/storage/VMTemplateVO.java
+++ b/core/src/com/cloud/storage/VMTemplateVO.java
@@ -18,28 +18,23 @@
package com.cloud.storage;
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import com.cloud.async.AsyncInstanceCreateStatus;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.FileSystem;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
-import com.cloud.utils.db.GenericDao;
-import com.google.gson.annotations.Expose;
-import com.cloud.storage.Storage;
import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.db.GenericDao;
@Entity
@Table(name="vm_template")
@@ -248,7 +243,8 @@ public class VMTemplateVO implements VirtualMachineTemplate {
requiresHvm = value;
}
- public long getAccountId() {
+ @Override
+ public long getAccountId() {
return accountId;
}
@@ -303,6 +299,11 @@ public class VMTemplateVO implements VirtualMachineTemplate {
public void setHypervisorType(HypervisorType hyperType) {
hypervisorType = hyperType.toString();
}
+
+ @Override
+ public long getDomainId() {
+ return -1;
+ }
@Override
public boolean equals(Object that) {
@@ -320,5 +321,15 @@ public class VMTemplateVO implements VirtualMachineTemplate {
public int hashCode() {
return uniqueName.hashCode();
}
+
+ @Transient
+ String toString;
+ @Override
+ public String toString() {
+ if (toString == null) {
+ toString = new StringBuilder("Template:").append(id).append(":").append(format).append(":").append(uniqueName).toString();
+ }
+ return toString;
+ }
}
diff --git a/core/src/com/cloud/user/AccountVO.java b/core/src/com/cloud/user/AccountVO.java
index d47d7ddbbb5..bccb54a2749 100644
--- a/core/src/com/cloud/user/AccountVO.java
+++ b/core/src/com/cloud/user/AccountVO.java
@@ -77,12 +77,15 @@ public class AccountVO implements Account {
return id;
}
+ @Override
public String getAccountName() {
return accountName;
}
+ @Override
public void setAccountName(String accountName) {
this.accountName = accountName;
}
+ @Override
public short getType() {
return type;
}
@@ -90,6 +93,7 @@ public class AccountVO implements Account {
this.type = type;
}
+ @Override
public long getDomainId() {
return domainId;
}
@@ -98,20 +102,30 @@ public class AccountVO implements Account {
this.domainId = domainId;
}
+ @Override
public String getState() {
return state;
}
+ @Override
public void setState(String state) {
this.state = state;
}
+ @Override
public Date getRemoved() {
return removed;
}
+ @Override
public String getNetworkDomain() {
return networkDomain;
}
+ @Override
public void setNetworkDomain(String networkDomain) {
this.networkDomain = networkDomain;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("Acct:").append(id).append(":").append(accountName).toString();
}
}
diff --git a/core/src/com/cloud/user/UserVO.java b/core/src/com/cloud/user/UserVO.java
index 2c04e9f48d4..6138a58ffea 100644
--- a/core/src/com/cloud/user/UserVO.java
+++ b/core/src/com/cloud/user/UserVO.java
@@ -18,15 +18,16 @@
package com.cloud.user;
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
import com.cloud.utils.db.GenericDao;
/**
@@ -84,77 +85,111 @@ public class UserVO implements User {
this.id = id;
}
- public Long getId() {
+ @Override
+ public Long getId() {
return id;
}
+ @Override
public Date getCreated() {
return created;
}
+ @Override
public Date getRemoved() {
return removed;
}
- public String getUsername() {
+ @Override
+ public String getUsername() {
return username;
}
- public void setUsername(String username) {
+ @Override
+ public void setUsername(String username) {
this.username = username;
}
- public String getPassword() {
+ @Override
+ public String getPassword() {
return password;
}
- public void setPassword(String password) {
+ @Override
+ public void setPassword(String password) {
this.password = password;
}
- public String getFirstname() {
+ @Override
+ public String getFirstname() {
return firstname;
}
- public void setFirstname(String firstname) {
+ @Override
+ public void setFirstname(String firstname) {
this.firstname = firstname;
}
- public String getLastname() {
+ @Override
+ public String getLastname() {
return lastname;
}
- public void setLastname(String lastname) {
+ @Override
+ public void setLastname(String lastname) {
this.lastname = lastname;
}
- public long getAccountId() {
+ @Override
+ public long getAccountId() {
return accountId;
}
- public void setAccountId(long accountId) {
+ @Override
+ public void setAccountId(long accountId) {
this.accountId = accountId;
}
+ @Override
public String getEmail() {
return email;
}
+ @Override
public void setEmail(String email) {
this.email = email;
}
+ @Override
public String getState() {
return state;
}
+ @Override
public void setState(String state) {
this.state = state;
}
- public String getApiKey() {
+ @Override
+ public String getApiKey() {
return apiKey;
}
- public void setApiKey(String apiKey) {
+ @Override
+ public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
+ @Override
public String getSecretKey() {
return secretKey;
}
+ @Override
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
+ @Override
public String getTimezone()
{
return timezone;
}
+ @Override
public void setTimezone(String timezone)
{
this.timezone = timezone;
+ }
+
+ @Transient
+ String toString = null;
+
+ @Override
+ public String toString() {
+ if (toString == null) {
+ toString = new StringBuilder("User:").append(id).append(":").append(username).toString();
+ }
+ return toString;
}
}
diff --git a/core/src/com/cloud/vm/UserVmVO.java b/core/src/com/cloud/vm/UserVmVO.java
index b4c9049fa94..18716657636 100755
--- a/core/src/com/cloud/vm/UserVmVO.java
+++ b/core/src/com/cloud/vm/UserVmVO.java
@@ -139,7 +139,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
super(id, serviceOfferingId, displayName, instanceName, Type.User, templateId, guestOsId, domainId, accountId, haEnabled);
this.userData = userData;
this.displayName = displayName;
-
}
public UserVmVO(long id,
diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java
new file mode 100644
index 00000000000..723ceb121bf
--- /dev/null
+++ b/server/src/com/cloud/acl/DomainChecker.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.acl;
+
+import javax.ejb.Local;
+
+import com.cloud.api.BaseCmd;
+import com.cloud.domain.Domain;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.storage.LaunchPermissionVO;
+import com.cloud.storage.dao.LaunchPermissionDao;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+
+@Local(value=DomainChecker.class)
+public class DomainChecker extends AdapterBase implements SecurityChecker {
+
+ @Inject DomainDao _domainDao;
+ @Inject AccountDao _accountDao;
+ @Inject LaunchPermissionDao _launchPermissionDao;
+
+ protected DomainChecker() {
+ super();
+ }
+
+ @Override
+ public boolean checkAccess(Account account, Domain domain) throws PermissionDeniedException {
+ if (!account.getState().equals(Account.ACCOUNT_STATE_ENABLED)) {
+ throw new PermissionDeniedException(account + " is disabled.");
+ }
+
+ if (!_domainDao.isChildDomain(account.getDomainId(), domain.getId())) {
+ throw new PermissionDeniedException(account + " does not have permission to operate within " + domain);
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean checkAccess(User user, Domain domain) throws PermissionDeniedException {
+ if (user.getRemoved() != null) {
+ throw new PermissionDeniedException(user + " is no longer active.");
+ }
+ Account account = _accountDao.findById(user.getAccountId());
+ return checkAccess(account, domain);
+ }
+
+ @Override
+ public boolean checkAccess(Account account, ControlledEntity entity) throws PermissionDeniedException {
+ if (entity instanceof VirtualMachineTemplate) {
+
+ VirtualMachineTemplate template = (VirtualMachineTemplate)entity;
+
+ // validate that the template is usable by the account
+ if (!template.isPublicTemplate()) {
+ Account owner = _accountDao.findById(template.getAccountId());
+ if (BaseCmd.isAdmin(owner.getType()) || (owner.getId() != account.getId())) {
+ return true;
+ }
+
+ // since the current account is not the owner of the template, check the launch permissions table to see if the
+ // account can launch a VM from this template
+ LaunchPermissionVO permission = _launchPermissionDao.findByTemplateAndAccount(template.getId(), account.getId());
+ if (permission == null) {
+ throw new PermissionDeniedException(account + " does not have permission to launch instances from " + template);
+ }
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
+ Account account = _accountDao.findById(user.getAccountId());
+ return checkAccess(account, entity);
+ }
+}
diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
index 78a5b76f407..741b7d13699 100755
--- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
@@ -96,6 +96,7 @@ import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.event.dao.EventDao;
import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.OperationTimedoutException;
@@ -1050,11 +1051,18 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
s_logger.debug("Sending Connect to listener: " + monitor.second().getClass().getSimpleName());
}
for (int i = 0; i < cmd.length; i++) {
- if (!monitor.second().processConnect(host, cmd[i])) {
- s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId);
- handleDisconnect(attache, Event.AgentDisconnected, false);
- return attache;
- }
+ try {
+ monitor.second().processConnect(host, cmd[i]);
+ } catch (ConnectionException e) {
+ if (e.isSetupError()) {
+ s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage());
+ handleDisconnect(attache, Event.AgentDisconnected, false);
+ } else {
+ s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId + " due to " + e.getMessage());
+ handleDisconnect(attache, Event.ShutdownRequested, false);
+ }
+ return null;
+ }
}
}
diff --git a/server/src/com/cloud/agent/manager/AgentMonitor.java b/server/src/com/cloud/agent/manager/AgentMonitor.java
index 237aa66c9ff..17ed235c56c 100755
--- a/server/src/com/cloud/agent/manager/AgentMonitor.java
+++ b/server/src/com/cloud/agent/manager/AgentMonitor.java
@@ -195,9 +195,8 @@ public class AgentMonitor extends Thread implements Listener {
}
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
+ public void processConnect(HostVO host, StartupCommand cmd) {
s_logger.debug("Registering agent monitor for " + host.getId());
- return true;
}
@Override
diff --git a/server/src/com/cloud/agent/manager/SynchronousListener.java b/server/src/com/cloud/agent/manager/SynchronousListener.java
index dd5d1d001fd..7f1293d0c20 100755
--- a/server/src/com/cloud/agent/manager/SynchronousListener.java
+++ b/server/src/com/cloud/agent/manager/SynchronousListener.java
@@ -80,8 +80,7 @@ public class SynchronousListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
- return false;
+ public void processConnect(HostVO agent, StartupCommand cmd) {
}
@Override
diff --git a/server/src/com/cloud/api/commands/DeployVm2Cmd.java b/server/src/com/cloud/api/commands/DeployVm2Cmd.java
index 8ad461b8ba2..5ec94a8d779 100644
--- a/server/src/com/cloud/api/commands/DeployVm2Cmd.java
+++ b/server/src/com/cloud/api/commands/DeployVm2Cmd.java
@@ -23,8 +23,9 @@ import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
-import com.cloud.api.BaseAsyncCmd;
+import com.cloud.api.BaseAsyncCreateCmd;
import com.cloud.api.BaseCmd;
+import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
@@ -39,7 +40,7 @@ import com.cloud.uservm.UserVm;
import com.cloud.vm.InstanceGroupVO;
@Implementation(createMethod="createVirtualMachine", method="startVirtualMachine", manager=Manager.UserVmManager, description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.")
-public class DeployVm2Cmd extends BaseAsyncCmd {
+public class DeployVm2Cmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName());
private static final String s_name = "deployvirtualmachineresponse";
diff --git a/server/src/com/cloud/async/executor/VMOperationListener.java b/server/src/com/cloud/async/executor/VMOperationListener.java
index c37ddec25bc..c15b901b030 100644
--- a/server/src/com/cloud/async/executor/VMOperationListener.java
+++ b/server/src/com/cloud/async/executor/VMOperationListener.java
@@ -50,6 +50,7 @@ public class VMOperationListener implements Listener {
_cookie = cookie;
}
+ @Override
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
Answer answer = null;
if(answers != null)
@@ -61,33 +62,40 @@ public class VMOperationListener implements Listener {
return true;
}
+ @Override
public boolean processCommands(long agentId, long seq, Command[] commands) {
return true;
}
+ @Override
public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
return null;
}
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
- return true;
+ @Override
+ public void processConnect(HostVO agent, StartupCommand cmd) {
+// return true;
}
+ @Override
public boolean processDisconnect(long agentId, Status state) {
if(_vm.getHostId() == agentId)
_executor.processDisconnect(this, agentId);
return true;
}
+ @Override
public boolean isRecurring() {
return false;
}
+ @Override
public int getTimeout() {
// TODO : no time out support for now as underlying support does not work as expected
return -1;
}
+ @Override
public boolean processTimeout(long agentId, long seq) {
if(s_logger.isDebugEnabled())
s_logger.debug("Process time out for " + agentId + "-" + seq);
diff --git a/server/src/com/cloud/async/executor/VolumeOperationListener.java b/server/src/com/cloud/async/executor/VolumeOperationListener.java
index 39f5668396a..0ef17af29de 100644
--- a/server/src/com/cloud/async/executor/VolumeOperationListener.java
+++ b/server/src/com/cloud/async/executor/VolumeOperationListener.java
@@ -52,6 +52,7 @@ public class VolumeOperationListener implements Listener {
_cookie = cookie;
}
+ @Override
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
Answer answer = null;
if(answers != null)
@@ -64,33 +65,39 @@ public class VolumeOperationListener implements Listener {
return true;
}
+ @Override
public boolean processCommands(long agentId, long seq, Command[] commands) {
return true;
}
+ @Override
public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
return null;
}
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
- return true;
+ @Override
+ public void processConnect(HostVO agent, StartupCommand cmd) {
}
+ @Override
public boolean processDisconnect(long agentId, Status state) {
if(_vm.getHostId() == agentId)
_executor.processDisconnect(this, agentId);
return true;
}
+ @Override
public boolean isRecurring() {
return false;
}
+ @Override
public int getTimeout() {
// TODO : no time out support for now as underlying support does not work as expected
return -1;
}
+ @Override
public boolean processTimeout(long agentId, long seq) {
if(s_logger.isDebugEnabled())
s_logger.debug("Process time out for " + agentId + "-" + seq);
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
index 67dca3aa760..ef653085f23 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
@@ -64,9 +64,8 @@ public class ConsoleProxyListener implements Listener {
}
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
+ public void processConnect(HostVO host, StartupCommand cmd) {
_proxyMgr.onAgentConnect(host, cmd);
- return true;
}
@Override
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 6bc8aaf3e49..875d7fe483f 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -2429,7 +2429,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
}
@Override
- public boolean checkDeploymentResult(Commands cmds, ConsoleProxyVO proxy, VirtualMachineProfile profile, DeployDestination dest) {
+ public boolean processDeploymentResult(Commands cmds, ConsoleProxyVO proxy, VirtualMachineProfile profile, DeployDestination dest) {
return true;
}
}
diff --git a/server/src/com/cloud/ha/VmSyncListener.java b/server/src/com/cloud/ha/VmSyncListener.java
index eb179dce44b..26898aedd97 100644
--- a/server/src/com/cloud/ha/VmSyncListener.java
+++ b/server/src/com/cloud/ha/VmSyncListener.java
@@ -33,6 +33,8 @@ import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.manager.Commands;
import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
@@ -119,9 +121,9 @@ public class VmSyncListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
+ public void processConnect(HostVO agent, StartupCommand cmd) throws ConnectionException {
if (!(cmd instanceof StartupRoutingCommand)) {
- return true;
+ return;
}
long agentId = agent.getId();
@@ -135,12 +137,13 @@ public class VmSyncListener implements Listener {
Commands cmds = new Commands(OnError.Continue);
cmds.addCommands(commands);
try {
- _agentMgr.send(agentId, cmds, this);
+ Answer[] answers = _agentMgr.send(agentId, cmds);
} catch (final AgentUnavailableException e) {
s_logger.warn("Agent is unavailable now", e);
+ throw new ConnectionException(true, "Unable to sync", e);
+ } catch (final OperationTimedoutException e) {
+ throw new ConnectionException(true, "Unable to sync", e);
}
}
-
- return true;
}
}
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
index cb3b993b921..8fb84b3d3e5 100644
--- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
+++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
@@ -71,9 +71,7 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer,
}
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
- // TODO Auto-generated method stub
- return false;
+ public void processConnect(HostVO host, StartupCommand cmd) {
}
@Override
diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
index 17002c5a132..bdca29c3468 100644
--- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
+++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
@@ -45,6 +45,7 @@ import com.cloud.alert.AlertManager;
import com.cloud.configuration.Config;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.dao.ClusterDao;
+import com.cloud.exception.ConnectionException;
import com.cloud.exception.DiscoveryException;
import com.cloud.host.HostInfo;
import com.cloud.host.HostVO;
@@ -521,12 +522,10 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
+ public void processConnect(HostVO agent, StartupCommand cmd) throws ConnectionException {
if (cmd instanceof StartupStorageCommand) {
createPVTemplate(agent.getId(), (StartupStorageCommand)cmd);
- return true;
}
- return true;
}
@Override
diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java
index 1f0823a3a13..24fb515a524 100644
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -316,4 +316,6 @@ public interface NetworkManager extends Manager {
AccountVO getNetworkConfigurationOwner(long configurationId);
List getNetworkConfigurationsforOffering(long offeringId, long dataCenterId, long accountId);
+
+ List setupNetworkConfiguration(Account owner, ServiceOfferingVO offering, DeploymentPlan plan);
}
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index ab8f755254d..90c27bc4331 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -1789,16 +1789,47 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
return to;
}
+ @DB
+ protected Pair implementNetworkConfiguration(long configId, DeployDestination dest) throws ConcurrentOperationException {
+ Transaction txn = Transaction.currentTxn();
+ NetworkConfigurationVO config = _networkConfigDao.acquire(configId);
+ if (config == null) {
+ throw new ConcurrentOperationException("Unable to acquire network configuration: " + configId);
+ }
+
+ try {
+ NetworkGuru guru = _networkGurus.get(config.getGuruName());
+ if (config.getState() == NetworkConfiguration.State.Implemented || config.getState() == NetworkConfiguration.State.Setup) {
+ return new Pair(guru, config);
+ }
+
+
+ NetworkConfiguration result = guru.implement(config, _networkOfferingDao.findById(config.getNetworkOfferingId()), dest);
+ config.setCidr(result.getCidr());
+ config.setBroadcastUri(result.getBroadcastUri());
+ config.setGateway(result.getGateway());
+ config.setDns(result.getDns());
+ config.setMode(result.getMode());
+ config.setState(NetworkConfiguration.State.Implemented);
+ _networkConfigDao.update(configId, config);
+
+ return new Pair(guru, config);
+ } finally {
+ _networkConfigDao.release(configId);
+ }
+ }
+
@Override
public NicTO[] prepare(VirtualMachineProfile vmProfile, DeployDestination dest, Account user) throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapcityException, ConcurrentOperationException, ResourceUnavailableException {
List nics = _nicDao.listBy(vmProfile.getId());
NicTO[] nicTos = new NicTO[nics.size()];
int i = 0;
for (NicVO nic : nics) {
- NetworkConfigurationVO config = _networkConfigDao.findById(nic.getNetworkConfigurationId());
+ Pair implemented = implementNetworkConfiguration(nic.getNetworkConfigurationId(), dest);
+ NetworkGuru concierge = implemented.first();
+ NetworkConfigurationVO config = implemented.second();
NicProfile profile = null;
if (nic.getReservationStrategy() == ReservationStrategy.Start) {
- NetworkGuru concierge = _networkGurus.get(config.getGuruName());
nic.setState(Resource.State.Reserving);
_nicDao.update(nic.getId(), nic);
profile = toNicProfile(nic);
@@ -2490,4 +2521,11 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
public List getNetworkConfigurationsforOffering(long offeringId, long dataCenterId, long accountId) {
return _networkConfigDao.getNetworkConfigurationsForOffering(offeringId, dataCenterId, accountId);
}
+
+ @Override
+ public List setupNetworkConfiguration(Account owner, ServiceOfferingVO offering, DeploymentPlan plan) {
+ NetworkOfferingVO networkOffering = _networkOfferingDao.findByServiceOffering(offering);
+ return setupNetworkConfiguration(owner, networkOffering, plan);
+ }
+
}
diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/com/cloud/network/SshKeysDistriMonitor.java
index c56e3d06178..3ca6e01060a 100644
--- a/server/src/com/cloud/network/SshKeysDistriMonitor.java
+++ b/server/src/com/cloud/network/SshKeysDistriMonitor.java
@@ -31,6 +31,7 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.ConnectionException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
@@ -71,10 +72,10 @@ public class SshKeysDistriMonitor implements Listener {
}
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
+ public void processConnect(HostVO host, StartupCommand cmd) throws ConnectionException {
if (cmd instanceof StartupRoutingCommand) {
if (((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.KVM ||
- ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer) {
+ ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer) {
/*TODO: Get the private/public keys here*/
Map configs = _configDao.getConfiguration("management-server", new HashMap());
@@ -82,11 +83,10 @@ public class SshKeysDistriMonitor implements Listener {
String prvKey = configs.get("ssh.privatekey");
if (!_routerMgr.sendSshKeysToHost(host.getId(), pubKey, prvKey)) {
s_logger.debug("Failed to send keys to agent: " + host.getId());
- return false;
+ throw new ConnectionException(true, "Unable to send keys to the agent");
}
}
}
- return true;
}
@Override
diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
index ff037fd9db1..dff4271b733 100644
--- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
+++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
@@ -1999,12 +1999,11 @@ public class DomainRouterManagerImpl implements DomainRouterManager, VirtualMach
@Override @DB
public DomainRouterVO deploy(NetworkConfiguration publicConfig, NetworkConfiguration virtualConfig, NetworkOffering offering, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException {
- long dcId = publicConfig.getDataCenterId();
+ long dcId = virtualConfig.getDataCenterId();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Starting a router for network configurations: public=" + publicConfig + "; virtual=" + virtualConfig);
}
- assert dcId == virtualConfig.getDataCenterId() : "Domain router cannot span networks in two data centers";
assert publicConfig.getState() == NetworkConfiguration.State.Implemented : "Network is not yet fully implemented: " + publicConfig;
assert virtualConfig.getState() == NetworkConfiguration.State.Implemented : "Network is not yet fully implemented: " + virtualConfig;
@@ -2092,7 +2091,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, VirtualMach
}
@Override
- public boolean checkDeploymentResult(Commands cmds, DomainRouterVO router, VirtualMachineProfile profile, DeployDestination dest) {
+ public boolean processDeploymentResult(Commands cmds, DomainRouterVO router, VirtualMachineProfile profile, DeployDestination dest) {
return true;
}
diff --git a/server/src/com/cloud/network/security/NetworkGroupListener.java b/server/src/com/cloud/network/security/NetworkGroupListener.java
index e93f4e9792c..885eef3b643 100644
--- a/server/src/com/cloud/network/security/NetworkGroupListener.java
+++ b/server/src/com/cloud/network/security/NetworkGroupListener.java
@@ -111,9 +111,7 @@ public class NetworkGroupListener implements Listener {
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
-
- return true;
+ public void processConnect(HostVO host, StartupCommand cmd) {
}
diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java
index f244864c97c..60e478f37ca 100644
--- a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java
+++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java
@@ -4,6 +4,7 @@
package com.cloud.offerings.dao;
import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.service.ServiceOfferingVO;
import com.cloud.utils.db.GenericDao;
/**
@@ -28,4 +29,6 @@ public interface NetworkOfferingDao extends GenericDao
* @return NetworkOfferingVO backed by a row in the database
*/
NetworkOfferingVO persistSystemNetworkOffering(NetworkOfferingVO offering);
+
+ NetworkOfferingVO findByServiceOffering(ServiceOfferingVO offering);
}
diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
index dc63e8dd0a8..08c7dc4ca68 100644
--- a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
+++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
@@ -3,17 +3,27 @@
*/
package com.cloud.offerings.dao;
+
import javax.ejb.Local;
import javax.persistence.EntityExistsException;
+import org.apache.log4j.Logger;
+
import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
-@Local(value=NetworkOfferingDao.class)
+@Local(value=NetworkOfferingDao.class) @DB(txn=false)
public class NetworkOfferingDaoImpl extends GenericDaoBase implements NetworkOfferingDao {
- SearchBuilder NameSearch;
+
+ private final static Logger s_logger = Logger.getLogger(NetworkOfferingDaoImpl.class);
+
+ SearchBuilder NameSearch;
+ SearchBuilder ServiceOfferingSearch;
protected NetworkOfferingDaoImpl() {
super();
@@ -21,6 +31,10 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase sc = ServiceOfferingSearch.create();
+ sc.setParameters("serviceoffering", offering.getId());
+
+ NetworkOfferingVO vo = findOneBy(sc);
+ if (vo != null) {
+ return vo;
+ }
+
+ vo = new NetworkOfferingVO(offering);
+ try {
+ return persist(vo);
+ } catch (Exception e) {
+ s_logger.debug("Got a persistence exception. Assuming it's because service offering id is duplicate");
+ vo = findOneBy(sc);
+ if (vo != null) {
+ return vo;
+ }
+
+ throw new CloudRuntimeException("Unable to persist network offering", e);
+ }
+ }
}
diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java
index fecf47435a6..da7e045e62c 100644
--- a/server/src/com/cloud/storage/LocalStoragePoolListener.java
+++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java
@@ -27,9 +27,9 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.exception.ConnectionException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
-import com.cloud.storage.Storage.StorageResourceType;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.utils.component.Inject;
@@ -65,20 +65,20 @@ public class LocalStoragePoolListener implements Listener {
@Override
@DB
- public boolean processConnect(HostVO host, StartupCommand cmd) {
+ public void processConnect(HostVO host, StartupCommand cmd) throws ConnectionException {
if (!(cmd instanceof StartupStorageCommand)) {
- return true;
+ return;
}
StartupStorageCommand ssCmd = (StartupStorageCommand)cmd;
if (ssCmd.getResourceType() != Storage.StorageResourceType.STORAGE_POOL) {
- return true;
+ return;
}
StoragePoolInfo pInfo = ssCmd.getPoolInfo();
if (pInfo == null) {
- return true;
+ return;
}
try {
@@ -114,9 +114,8 @@ public class LocalStoragePoolListener implements Listener {
}
} catch (Exception e) {
s_logger.warn("Unable to setup the local storage pool for " + host, e);
- return false;
+ throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e);
}
- return true;
}
diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java
index e2b18905355..647afefb4b6 100644
--- a/server/src/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/com/cloud/storage/download/DownloadListener.java
@@ -39,6 +39,7 @@ import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
+import com.cloud.exception.ConnectionException;
import com.cloud.host.HostVO;
import com.cloud.storage.Storage;
import com.cloud.storage.VMTemplateHostVO;
@@ -274,13 +275,13 @@ public class DownloadListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
+ public void processConnect(HostVO agent, StartupCommand cmd) throws ConnectionException {
if (!(cmd instanceof StartupStorageCommand)) {
- return true;
+ return;
}
if (cmd.getGuid().startsWith("iso:")) {
//FIXME: do not download template for ISO secondary
- return true;
+ return;
}
long agentId = agent.getId();
@@ -294,8 +295,6 @@ public class DownloadListener implements Listener {
//downloadMonitor.handlePoolTemplateSync(storage.getPoolInfo(), storage.getTemplateInfo());
//no need to do anything. The storagepoolmonitor will initiate template sync.
}
-
- return true;
}
public void setCommand(DownloadCommand _cmd) {
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index a184b348a09..c9158cea010 100755
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -66,7 +66,7 @@ public class StoragePoolMonitor implements Listener {
}
@Override
- public boolean processConnect(HostVO host, StartupCommand cmd) {
+ public void processConnect(HostVO host, StartupCommand cmd) {
if (cmd instanceof StartupRoutingCommand) {
StartupRoutingCommand scCmd = (StartupRoutingCommand)cmd;
if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() == HypervisorType.KVM ||
@@ -81,7 +81,6 @@ public class StoragePoolMonitor implements Listener {
}
}
}
- return true;
}
diff --git a/server/src/com/cloud/storage/listener/StorageSyncListener.java b/server/src/com/cloud/storage/listener/StorageSyncListener.java
index 5d03ad35421..9cf1be2ad89 100755
--- a/server/src/com/cloud/storage/listener/StorageSyncListener.java
+++ b/server/src/com/cloud/storage/listener/StorageSyncListener.java
@@ -52,8 +52,7 @@ public class StorageSyncListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
- return false;
+ public void processConnect(HostVO agent, StartupCommand cmd) {
}
@Override
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
index f5aba0b66f6..7c61710d737 100644
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
@@ -29,7 +29,6 @@ import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StorageResourceType;
public class SecondaryStorageListener implements Listener {
private final static Logger s_logger = Logger.getLogger(SecondaryStorageListener.class);
@@ -76,11 +75,10 @@ public class SecondaryStorageListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
- if(s_logger.isInfoEnabled())
- s_logger.info("Received a host startup notification");
-
+ public void processConnect(HostVO agent, StartupCommand cmd) {
if (cmd instanceof StartupStorageCommand) {
+ if(s_logger.isInfoEnabled())
+ s_logger.info("Received a host startup notification");
StartupStorageCommand ss = (StartupStorageCommand)cmd;
if (ss.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
@@ -89,8 +87,6 @@ public class SecondaryStorageListener implements Listener {
_ssVmMgr.generateSetupCommand(agent.getDataCenterId());
}
}
-
- return true;
}
@Override
diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java
index 4ed3cd6278d..4cb5ab51c31 100755
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@ -24,15 +24,13 @@ import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.executor.ExtractJobResultObject;
-import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.host.HostVO;
import com.cloud.storage.Storage;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.Upload.Status;
import com.cloud.storage.Upload.Type;
-import com.cloud.storage.upload.UploadMonitorImpl;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.upload.UploadState.UploadEvent;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -210,9 +208,9 @@ public class UploadListener implements Listener {
}
@Override
- public boolean processConnect(HostVO agent, StartupCommand cmd) {
+ public void processConnect(HostVO agent, StartupCommand cmd) {
if (!(cmd instanceof StartupStorageCommand)) {
- return true;
+ return;
}
long agentId = agent.getId();
@@ -223,7 +221,6 @@ public class UploadListener implements Listener {
{
uploadMonitor.handleUploadSync(agentId);
}
- return true;
}
@Override
diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java
index 210f1ebdca7..f43de56fdb9 100644
--- a/server/src/com/cloud/user/AccountManager.java
+++ b/server/src/com/cloud/user/AccountManager.java
@@ -20,11 +20,13 @@ package com.cloud.user;
import java.util.List;
+import com.cloud.acl.ControlledEntity;
import com.cloud.api.commands.ListResourceLimitsCmd;
import com.cloud.api.commands.UpdateResourceLimitCmd;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceLimitVO;
+import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@@ -114,5 +116,9 @@ public interface AccountManager extends Manager {
*/
ResourceLimitVO updateResourceLimit(UpdateResourceLimitCmd cmd) throws InvalidParameterValueException;
+ void checkAccess(Account account, Domain domain) throws PermissionDeniedException;
+
+ void checkAccess(Account account, ControlledEntity... entities) throws PermissionDeniedException;
+
AccountVO getSystemAccount();
}
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index b7282e96750..64b7d3f09e1 100644
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -27,6 +27,8 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
+import com.cloud.acl.ControlledEntity;
+import com.cloud.acl.SecurityChecker;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.ListResourceLimitsCmd;
@@ -35,12 +37,14 @@ import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceLimitVO;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
+import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.Criteria;
import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GlobalLock;
@@ -59,6 +63,8 @@ public class AccountManagerImpl implements AccountManager {
private final GlobalLock m_resourceCountLock = GlobalLock.getInternLock("resource.count");
AccountVO _systemAccount;
+ @Inject(adapter=SecurityChecker.class)
+ Adapters _securityCheckers;
@Override
public boolean configure(final String name, final Map params) throws ConfigurationException {
@@ -342,7 +348,7 @@ public class AccountManagerImpl implements AccountManager {
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Long accountId = null;
- Account account = (Account)UserContext.current().getAccount();
+ Account account = UserContext.current().getAccount();
if ((account == null) ||
(account.getType() == Account.ACCOUNT_TYPE_ADMIN) ||
@@ -409,7 +415,7 @@ public class AccountManagerImpl implements AccountManager {
@Override
public ResourceLimitVO updateResourceLimit(UpdateResourceLimitCmd cmd) throws InvalidParameterValueException {
- Account account = (Account)UserContext.current().getAccount();
+ Account account = UserContext.current().getAccount();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Long max = cmd.getMax();
@@ -560,4 +566,41 @@ public class AccountManagerImpl implements AccountManager {
public AccountVO getSystemAccount() {
return _systemAccount;
}
+
+ public static boolean isAdmin(short accountType) {
+ return ((accountType == Account.ACCOUNT_TYPE_ADMIN) ||
+ (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) ||
+ (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
+ }
+
+ @Override
+ public void checkAccess(Account caller, Domain domain) throws PermissionDeniedException {
+ for (SecurityChecker checker : _securityCheckers) {
+ if (checker.checkAccess(caller, domain)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Access granted to " + caller + " to " + domain + " by " + checker.getName());
+ }
+ return;
+ }
+ }
+
+ assert false : "How can all of the security checkers pass on checking this caller?";
+ throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + domain);
+ }
+
+ @Override
+ public void checkAccess(Account caller, ControlledEntity... entities) {
+ for (ControlledEntity entity : entities) {
+ for (SecurityChecker checker : _securityCheckers) {
+ if (checker.checkAccess(caller, entity)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
+ }
+ }
+ }
+
+ assert false : "How can all of the security checkers pass on checking this check?";
+ throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
+ }
+ }
}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 58b888adb6b..46e3f9063db 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -63,7 +63,6 @@ import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiDBUtils;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AttachVolumeCmd;
@@ -106,6 +105,9 @@ import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.EventState;
import com.cloud.event.EventTypes;
@@ -132,6 +134,7 @@ import com.cloud.network.FirewallRuleVO;
import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddrAllocator;
import com.cloud.network.LoadBalancerVMMapVO;
+import com.cloud.network.NetworkConfigurationVO;
import com.cloud.network.NetworkManager;
import com.cloud.network.SecurityGroupVMMapVO;
import com.cloud.network.dao.FirewallRulesDao;
@@ -205,7 +208,7 @@ import com.cloud.vm.dao.InstanceGroupVMMapDao;
import com.cloud.vm.dao.UserVmDao;
@Local(value={UserVmManager.class, UserVmService.class})
-public class UserVmManagerImpl implements UserVmManager, UserVmService {
+public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualMachineGuru {
private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; // 3 seconds
@@ -250,12 +253,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
@Inject AccountVlanMapDao _accountVlanMapDao;
@Inject StoragePoolDao _storagePoolDao;
@Inject VMTemplateHostDao _vmTemplateHostDao;
- @Inject NetworkGroupManager _networkGroupManager;
+ @Inject NetworkGroupManager _networkGroupMgr;
@Inject ServiceOfferingDao _serviceOfferingDao;
@Inject EventDao _eventDao = null;
@Inject InstanceGroupDao _vmGroupDao;
@Inject InstanceGroupVMMapDao _groupVMMapDao;
-
+ @Inject SecurityGroupDao _networkSecurityGroupDao;
+ @Inject VmManager _itMgr;
+
private IpAddrAllocator _IpAllocator;
ScheduledExecutorService _executor = null;
int _expungeInterval;
@@ -265,6 +270,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
String _name;
String _instance;
String _zone;
+ String _defaultNetworkDomain;
Random _rand = new Random(System.currentTimeMillis());
@@ -1112,7 +1118,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
event.setDescription("successfully started VM: " + vm.getName());
_eventDao.persist(event);
- _networkGroupManager.handleVmStateTransition(vm, State.Running);
+ _networkGroupMgr.handleVmStateTransition(vm, State.Running);
return _vmDao.findById(vm.getId());
} catch (Throwable th) {
@@ -2174,6 +2180,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
}
Map configs = _configDao.getConfiguration("AgentManager", params);
+
+ _defaultNetworkDomain = configs.get("domain");
+ if (_defaultNetworkDomain == null) {
+ _defaultNetworkDomain = ".myvm.com";
+ }
+ if (!_defaultNetworkDomain.startsWith(".")) {
+ _defaultNetworkDomain = "." + _defaultNetworkDomain;
+ }
String value = configs.get("start.retry");
_retry = NumbersUtil.parseInt(value, 2);
@@ -2244,7 +2258,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
@Override
public void completeStartCommand(UserVmVO vm) {
_vmDao.updateIf(vm, Event.AgentReportRunning, vm.getHostId());
- _networkGroupManager.handleVmStateTransition(vm, State.Running);
+ _networkGroupMgr.handleVmStateTransition(vm, State.Running);
}
@@ -2278,7 +2292,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
}
txn.commit();
- _networkGroupManager.handleVmStateTransition(vm, State.Stopped);
+ _networkGroupMgr.handleVmStateTransition(vm, State.Stopped);
} catch (Throwable th) {
s_logger.error("Error during stop: ", th);
throw new CloudRuntimeException("Error during stop: ", th);
@@ -2508,7 +2522,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
_storageMgr.destroy(vm, vols);
_vmDao.remove(vm.getId());
- _networkGroupManager.removeInstanceFromGroups(vm.getId());
+ _networkGroupMgr.removeInstanceFromGroups(vm.getId());
removeInstanceFromGroup(vm.getId());
s_logger.debug("vm is destroyed");
@@ -3133,7 +3147,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
vm.setLastHostId(pod.second());
vm = _vmDao.persist(vm);
- boolean addedToGroups = _networkGroupManager.addInstanceToGroups(vmId, networkGroups);
+ boolean addedToGroups = _networkGroupMgr.addInstanceToGroups(vmId, networkGroups);
if (!addedToGroups) {
s_logger.warn("Not all specified network groups can be found");
_vmDao.expunge(vm.getId());
@@ -3298,7 +3312,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
vm.setLastHostId(pod.second());
_vmDao.persist(vm);
- _networkGroupManager.addInstanceToGroups(vmId, networkGroups);
+ _networkGroupMgr.addInstanceToGroups(vmId, networkGroups);
_accountMgr.incrementResourceCount(account.getId(), ResourceType.user_vm);
_accountMgr.incrementResourceCount(account.getId(), ResourceType.volume, numVolumes);
@@ -3776,193 +3790,174 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService {
}
}
- @Override
+ private boolean validPassword(String password) {
+ for (int i = 0; i < password.length(); i++) {
+ if (password.charAt(i) == ' ') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override @DB
public UserVm createVirtualMachine(DeployVm2Cmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
-// Account account = UserContext.current().getAccount();
-// Account ctxAccount = UserContext.current().getAccount();
-// Long userId = UserContext.current().getUserId();
-// String accountName = cmd.getAccountName();
-// Long domainId = cmd.getDomainId();
-// Long accountId = null;
-// long dataCenterId = cmd.getZoneId();
-// long serviceOfferingId = cmd.getServiceOfferingId();
-// long templateId = cmd.getTemplateId();
-// Long diskOfferingId = cmd.getDiskOfferingId();
-// String domain = null; // FIXME: this was hardcoded to null in DeployVMCmd in the old framework, do we need it?
-// String password = generateRandomPassword();
-// String displayName = cmd.getDisplayName();
-// String group = cmd.getGroup();
-// String userData = cmd.getUserData();
-// String[] networkGroups = null;
-// Long sizeObj = cmd.getSize();
-// long size = (sizeObj == null) ? 0 : sizeObj;
-//
-// if ((ctxAccount == null) || isAdmin(ctxAccount.getType())) {
-// if (domainId != null) {
-// if ((ctxAccount != null) && !_domainDao.isChildDomain(ctxAccount.getDomainId(), domainId)) {
-// throw new PermissionDeniedException("Failed to deploy VM, invalid domain id (" + domainId + ") given.");
-// }
-// if (accountName != null) {
-// Account userAccount = _accountDao.findActiveAccount(accountName, domainId);
-// if (userAccount == null) {
-// throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
-// }
-// accountId = userAccount.getId();
-// }
-// } else {
-// accountId = ((ctxAccount != null) ? ctxAccount.getId() : null);
-// }
-// } else {
-// accountId = ctxAccount.getId();
-// }
-//
-// if (accountId == null) {
-// throw new InvalidParameterValueException("No valid account specified for deploying a virtual machine.");
-// }
-//
-// List netGrpList = cmd.getNetworkGroupList();
-// if ((netGrpList != null) && !netGrpList.isEmpty()) {
-// networkGroups = netGrpList.toArray(new String[netGrpList.size()]);
-// }
-//
-// AccountVO account = _accountDao.findById(accountId);
-// if (account == null) {
-// throw new InvalidParameterValueException("Unable to find account: " + accountId);
-// }
-//
-// DataCenterVO dc = _dcDao.findById(dataCenterId);
-// if (dc == null) {
-// throw new InvalidParameterValueException("Unable to find zone: " + dataCenterId);
-// }
-//
-// ServiceOfferingVO offering = _offeringsDao.findById(serviceOfferingId);
-// if (offering == null) {
-// throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-// }
-//
-// VMTemplateVO template = _templateDao.findById(templateId);
-// // Make sure a valid template ID was specified
-// if (template == null) {
-// throw new InvalidParameterValueException("Please specify a valid template or ISO ID.");
-// }
-//
-// boolean isIso = Storage.ImageFormat.ISO.equals(template.getFormat());
-//
-// if (isIso && !template.isBootable()) {
-// throw new InvalidParameterValueException("Please specify a bootable ISO.");
-// }
-//
-// // If the template represents an ISO, a disk offering must be passed in, and will be used to create the root disk
-// // Else, a disk offering is optional, and if present will be used to create the data disk
-// DiskOfferingVO diskOffering = null;
-//
-// if (diskOfferingId != null) {
-// diskOffering = _diskOfferingDao.findById(diskOfferingId);
-// }
-//
-// if (isIso && diskOffering == null) {
-// throw new InvalidParameterValueException("Please specify a valid disk offering ID.");
-// }
-//
-// // validate that the template is usable by the account
-// if (!template.isPublicTemplate()) {
-// Long templateOwner = template.getAccountId();
-// if (!BaseCmd.isAdmin(account.getType()) && ((templateOwner == null) || (templateOwner.longValue() != accountId))) {
-// // since the current account is not the owner of the template, check the launch permissions table to see if the
-// // account can launch a VM from this template
-// LaunchPermissionVO permission = _launchPermissionDao.findByTemplateAndAccount(templateId, account.getId());
-// if (permission == null) {
-// throw new PermissionDeniedException("Account " + account.getAccountName() + " does not have permission to launch instances from template " + template.getName());
-// }
-// }
-// }
-//
-// byte [] decodedUserData = null;
-// if (userData != null) {
-// if (userData.length() >= 2* UserVmManager.MAX_USER_DATA_LENGTH_BYTES) {
-// throw new InvalidParameterValueException("User data is too long");
-// }
-// decodedUserData = org.apache.commons.codec.binary.Base64.decodeBase64(userData.getBytes());
-// if (decodedUserData.length > UserVmManager.MAX_USER_DATA_LENGTH_BYTES){
-// throw new InvalidParameterValueException("User data is too long");
-// }
-// if (decodedUserData.length < 1) {
-// throw new InvalidParameterValueException("User data is too short");
-// }
-//
-// }
-// if (offering.getGuestIpType() != NetworkOffering.GuestIpType.Virtualized) {
-// _networkGroupMgr.createDefaultNetworkGroup(accountId);
-// }
-//
-// if (networkGroups != null) {
-// if (offering.getGuestIpType() == NetworkOffering.GuestIpType.Virtualized) {
-// throw new InvalidParameterValueException("Network groups are not compatible with service offering " + offering.getName());
-// }
-// Set nameSet = new HashSet(); //handle duplicate names -- allowed
-// nameSet.addAll(Arrays.asList(networkGroups));
-// nameSet.add(NetworkGroupManager.DEFAULT_GROUP_NAME);
-// networkGroups = nameSet.toArray(new String[nameSet.size()]);
-// List networkGroupVOs = _networkSecurityGroupDao.findByAccountAndNames(accountId, networkGroups);
-// if (networkGroupVOs.size() != nameSet.size()) {
-// throw new InvalidParameterValueException("Some network group names do not exist");
-// }
-// } else { //create a default group if necessary
-// if (offering.getGuestIpType() != NetworkOffering.GuestIpType.Virtualized && _networkGroupsEnabled) {
-// networkGroups = new String[]{NetworkGroupManager.DEFAULT_GROUP_NAME};
-// }
-// }
-//
-// Long eventId = cmd.getStartEventId();
-// try {
-// return deployVirtualMachineImpl(userId, accountId, dataCenterId, serviceOfferingId, templateId, diskOfferingId, domain, password, displayName, group, userData, networkGroups, eventId, size);
-// } catch (ResourceAllocationException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: VM_INSUFFICIENT_CAPACITY", null, eventId);
-// throw e;
-// } catch (ExecutionException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: VM_HOST_LICENSE_EXPIRED", null, eventId);
-// throw e;
-// } catch (InvalidParameterValueException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: VM_INVALID_PARAM_ERROR", null, eventId);
-// throw e;
-// } catch (InternalErrorException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: INTERNAL_ERROR", null, eventId);
-// throw e;
-// } catch (InsufficientStorageCapacityException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: VM_INSUFFICIENT_CAPACITY", null, eventId);
-// throw e;
-// } catch (PermissionDeniedException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: ACCOUNT_ERROR", null, eventId);
-// throw e;
-// } catch (ConcurrentOperationException e) {
-// if(s_logger.isDebugEnabled())
-// s_logger.debug("Unable to deploy VM: " + e.getMessage());
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: INTERNAL_ERROR", null, eventId);
-// throw e;
-// } catch(Exception e) {
-// s_logger.warn("Unable to deploy VM : " + e.getMessage(), e);
-// EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_CREATE, "Unable to deploy VM: INTERNAL_ERROR", null, eventId);
-// throw new CloudRuntimeException("Unable to deploy VM : " + e.getMessage());
-// }
- return null;
+ Account caller = UserContext.current().getAccount();
+
+ AccountVO owner = _accountDao.findById(cmd.getAccountId());
+ if (owner == null || owner.getRemoved() != null) {
+ throw new InvalidParameterValueException("Unable to find account: " + cmd.getAccountId());
+ }
+
+ Domain domain = _domainDao.findById(owner.getDomainId());
+ if (domain == null || domain.getRemoved() != null) {
+ throw new InvalidParameterValueException("Unable to find domain: " + cmd.getDomainId());
+ }
+
+ _accountMgr.checkAccess(caller, domain);
+
+ DataCenterVO dc = _dcDao.findById(cmd.getZoneId());
+ if (dc == null) {
+ throw new InvalidParameterValueException("Unable to find zone: " + cmd.getZoneId());
+ }
+
+ ServiceOfferingVO offering = _serviceOfferingDao.findById(cmd.getServiceOfferingId());
+ if (offering == null || offering.getRemoved() != null) {
+ throw new InvalidParameterValueException("Unable to find service offering: " + cmd.getServiceOfferingId());
+ }
+
+ VMTemplateVO template = _templateDao.findById(cmd.getTemplateId());
+ // Make sure a valid template ID was specified
+ if (template == null || template.getRemoved() != null) {
+ throw new InvalidParameterValueException("Unable to use template " + cmd.getTemplateId());
+ }
+ boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
+ if (isIso && !template.isBootable()) {
+ throw new InvalidParameterValueException("Installing from ISO requires an ISO that is bootable: " + template.getId());
+ }
+
+ // If the template represents an ISO, a disk offering must be passed in, and will be used to create the root disk
+ // Else, a disk offering is optional, and if present will be used to create the data disk
+ Pair rootDiskOffering = new Pair(null, null);
+ List> dataDiskOfferings = new ArrayList>();
+
+ if (isIso) {
+ if (cmd.getDiskOfferingId() == null) {
+ throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk.");
+ }
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(cmd.getDiskOfferingId());
+ if (diskOffering == null) {
+ throw new InvalidParameterValueException("Unable to find disk offering " + cmd.getDiskOfferingId());
+ }
+ Long size = null;
+ if (diskOffering.getDiskSize() == 0) {
+ size = cmd.getSize();
+ if (size == null) {
+ throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
+ }
+ }
+ rootDiskOffering.first(diskOffering);
+ rootDiskOffering.second(size);
+ } else {
+ rootDiskOffering.first(offering);
+ if (cmd.getDiskOfferingId() != null) {
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(cmd.getDiskOfferingId());
+ if (diskOffering == null) {
+ throw new InvalidParameterValueException("Unable to find disk offering " + cmd.getDiskOfferingId());
+ }
+ Long size = null;
+ if (diskOffering.getDiskSize() == 0) {
+ size = cmd.getSize();
+ if (size == null) {
+ throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
+ }
+ }
+ dataDiskOfferings.add(new Pair(diskOffering, size));
+ }
+ }
+
+ // Check that the password was passed in and is valid
+ String password = PasswordGenerator.generateRandomPassword();
+ if (!template.getEnablePassword()) {
+ password = "saved_password";
+ }
+ if (password == null || password.equals("") || (!validPassword(password))) {
+ throw new InvalidParameterValueException("A valid password for this virtual machine was not provided.");
+ }
+
+ String networkDomain = null;
+ if (networkDomain == null) {
+ networkDomain = "v" + Long.toHexString(owner.getId()) + _defaultNetworkDomain;
+ }
+
+ String userData = cmd.getUserData();
+ byte [] decodedUserData = null;
+ if (userData != null) {
+ if (userData.length() >= 2 * MAX_USER_DATA_LENGTH_BYTES) {
+ throw new InvalidParameterValueException("User data is too long");
+ }
+ decodedUserData = org.apache.commons.codec.binary.Base64.decodeBase64(userData.getBytes());
+ if (decodedUserData.length > MAX_USER_DATA_LENGTH_BYTES){
+ throw new InvalidParameterValueException("User data is too long");
+ }
+ if (decodedUserData.length < 1) {
+ throw new InvalidParameterValueException("User data is too short");
+ }
+ }
+
+ _accountMgr.checkAccess(caller, template);
+
+ DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), 1);
+
+ long id = _vmDao.getNextInSequence(Long.class, "id");
+
+ UserVmVO vm = new UserVmVO(id, VirtualMachineName.getVmName(id, owner.getId(), _instance), cmd.getDisplayName(),
+ template.getId(), template.getGuestOSId(), offering.getOfferHA(), domain.getId(), owner.getId(), offering.getId(), userData);
+
+ s_logger.debug("Allocating in the DB for vm");
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ vm = _vmDao.persist(vm);
+
+ List configs = _networkMgr.setupNetworkConfiguration(owner, offering, plan);
+ List> networks = new ArrayList>();
+ for (NetworkConfigurationVO config : configs) {
+ networks.add(new Pair(config, null));
+ }
+
+ if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, plan, owner) == null) {
+ return null;
+ }
+
+ txn.commit();
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Successfully allocated DB entry for " + vm);
+ }
+ return vm;
}
@Override
- public UserVm startVirtualMachine(DeployVm2Cmd cmd) {
+ public UserVm startVirtualMachine(DeployVm2Cmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
+ long vmId = cmd.getId();
+ UserVmVO vm = _vmDao.findById(vmId);
- return null;
+ long dcId = cmd.getZoneId();
+ DataCenterDeployment plan = new DataCenterDeployment(dcId, 1);
+
+ AccountVO owner = _accountDao.findById(vm.getAccountId());
+
+ return _itMgr.start(vm, plan, owner, this);
}
+
+ @Override
+ public boolean finalizeDeployment(Commands cmds, UserVmVO vm, VirtualMachineProfile profile, DeployDestination dest) {
+ return true;
+ }
+
+ @Override
+ public boolean processDeploymentResult(Commands cmds, UserVmVO vm, VirtualMachineProfile profile, DeployDestination dest) {
+ return true;
+ }
}
diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java
index ead31b4fd8d..2bda52a8838 100644
--- a/server/src/com/cloud/vm/VirtualMachineGuru.java
+++ b/server/src/com/cloud/vm/VirtualMachineGuru.java
@@ -42,5 +42,5 @@ public interface VirtualMachineGuru {
* @param dest destination it was sent to.
* @return true if deployment was fine; false if it didn't go well.
*/
- boolean checkDeploymentResult(Commands cmds, T vm, VirtualMachineProfile profile, DeployDestination dest);
+ boolean processDeploymentResult(Commands cmds, T vm, VirtualMachineProfile profile, DeployDestination dest);
}
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index 2e292ce6133..3f2b97dff4d 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -155,6 +155,7 @@ CREATE TABLE `cloud`.`network_offerings` (
`traffic_type` varchar(32) NOT NULL COMMENT 'traffic type carried on this network',
`tags` varchar(4096) COMMENT 'tags supported by this offering',
`system_only` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network offering for system use only',
+ `service_offering_id` bigint unsigned UNIQUE COMMENT 'service offering id that this network offering is tied to',
`created` datetime NOT NULL COMMENT 'time the entry was created',
`removed` datetime DEFAULT NULL COMMENT 'time the entry was removed',
PRIMARY KEY (`id`)
diff --git a/utils/src/com/cloud/utils/SerialVersionUID.java b/utils/src/com/cloud/utils/SerialVersionUID.java
index 15ad176a507..a2132767e06 100755
--- a/utils/src/com/cloud/utils/SerialVersionUID.java
+++ b/utils/src/com/cloud/utils/SerialVersionUID.java
@@ -32,12 +32,6 @@ public interface SerialVersionUID {
public static final long CloudRuntimeException = Base | 0x2;
public static final long CloudStartupServlet = Base | 0x3;
public static final long CloudServiceImpl = Base | 0x4;
- public static final long UserRemote = Base | 0x5;
- public static final long ServiceOfferingRemote = Base | 0x6;
- public static final long VMTemplateRemote = Base | 0x7;
- public static final long VMInstanceRemote = Base | 0x8;
- public static final long IPAddressRemote = Base | 0x9;
- public static final long IPForwardingRemote = Base | 0xa;
public static final long UnsupportedVersionException = Base | 0xb;
public static final long DataCenterIpAddressPK = Base | 0xc;
public static final long UnableToExecuteException = Base | 0xd;
@@ -59,4 +53,6 @@ public interface SerialVersionUID {
public static final long CloudAuthenticationException = Base | 0x1d;
public static final long AsyncCommandQueued = Base | 0x1e;
public static final long ResourceUnavailableException = Base | 0x1f;
+ public static final long ConnectionException = Base | 0x20;
+ public static final long PermissionDeniedException = Base | 0x21;
}
diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java
index da785808dd6..530da65469f 100755
--- a/utils/src/com/cloud/utils/db/GenericDao.java
+++ b/utils/src/com/cloud/utils/db/GenericDao.java
@@ -46,6 +46,8 @@ public interface GenericDao {
**/
T findById(ID id);
+ T findByIdIncludingRemoved(ID id);
+
T findById(ID id, boolean fresh);
/**
diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java
index 3f36d69789a..c7afc81eac6 100755
--- a/utils/src/com/cloud/utils/db/GenericDaoBase.java
+++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java
@@ -780,6 +780,11 @@ public abstract class GenericDaoBase implements Gene
}
}
+ @Override @DB(txn=false)
+ public T findByIdIncludingRemoved(ID id) {
+ return findById(id, true, null);
+ }
+
@Override @DB(txn=false)
public T findById(final ID id, boolean fresh) {
if(!fresh)
@@ -793,14 +798,21 @@ public abstract class GenericDaoBase implements Gene
@Override
public T lock(ID id, Boolean lock) {
- String sql = _selectByIdSql;
+ return findById(id, false, lock);
+ }
+
+ protected T findById(ID id, boolean removed, Boolean lock) {
+ StringBuilder sql = new StringBuilder(_selectByIdSql);
+ if (!removed && _removed != null) {
+ sql.append(" AND ").append(_removed.first());
+ }
if (lock != null) {
- sql += lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE;
+ sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
}
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = s_initStmt;
try {
- pstmt = txn.prepareAutoCloseStatement(sql);
+ pstmt = txn.prepareAutoCloseStatement(sql.toString());
if (_idField.getAnnotation(EmbeddedId.class) == null) {
pstmt.setObject(1, id);
@@ -810,9 +822,7 @@ public abstract class GenericDaoBase implements Gene
return rs.next() ? toEntityBean(rs, true) : null;
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e);
- } catch (Throwable e) {
- throw new CloudRuntimeException("Caught: " + pstmt.toString(), e);
- }
+ }
}
@Override @DB(txn=false)