diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java index 9cb3c3db3ff..2af08e9bf21 100644 --- a/agent/src/com/cloud/agent/AgentShell.java +++ b/agent/src/com/cloud/agent/AgentShell.java @@ -38,10 +38,13 @@ import java.util.UUID; import javax.naming.ConfigurationException; +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.xml.DOMConfigurator; import com.cloud.agent.Agent.ExitStatus; import com.cloud.agent.dao.StorageComponent; @@ -377,6 +380,18 @@ public class AgentShell implements IAgentShell { public void init(String[] args) throws ConfigurationException { + // PropertiesUtil is used both in management server and agent packages, + // it searches path under class path and common J2EE containers + // For KVM agent, do it specially here + + File file = new File("/etc/cloudstack/agent/log4j-cloud.xml"); + if(file == null || !file.exists()) { + file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); + } + DOMConfigurator.configureAndWatch(file.getAbsolutePath()); + + s_logger.info("Agent started"); + final Class c = this.getClass(); _version = c.getPackage().getImplementationVersion(); if (_version == null) { diff --git a/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java index affad1f9b9d..4336b4c32b4 100644 --- a/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java +++ b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java @@ -18,6 +18,7 @@ package com.cloud.agent.api; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.List; import java.util.zip.DeflaterOutputStream; import org.apache.commons.codec.binary.Base64; @@ -80,6 +81,7 @@ public class SecurityGroupRulesCmd extends Command { Long msId; IpPortAndProto [] ingressRuleSet; IpPortAndProto [] egressRuleSet; + private List secIps; public SecurityGroupRulesCmd() { super(); @@ -103,6 +105,23 @@ public class SecurityGroupRulesCmd extends Command { } + public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet, IpPortAndProto[] egressRuleSet, List secIps) { + super(); + this.guestIp = guestIp; + this.vmName = vmName; + this.ingressRuleSet = ingressRuleSet; + this.egressRuleSet = egressRuleSet; + this.guestMac = guestMac; + this.signature = signature; + this.seqNum = seqNum; + this.vmId = vmId; + if (signature == null) { + String stringified = stringifyRules(); + this.signature = DigestUtils.md5Hex(stringified); + } + this.secIps = secIps; + } + @Override public boolean executeInSequence() { return true; @@ -131,6 +150,10 @@ public class SecurityGroupRulesCmd extends Command { return guestIp; } + public List getSecIps() { + return secIps; + } + public String getVmName() { return vmName; @@ -165,6 +188,20 @@ public class SecurityGroupRulesCmd extends Command { } + public String getSecIpsString() { + StringBuilder sb = new StringBuilder(); + List ips = getSecIps(); + if (ips == null) { + return "0:"; + } else { + for (String ip : ips) { + sb.append(ip).append(":"); + } + } + return sb.toString(); + } + + public String stringifyCompressedRules() { StringBuilder ruleBuilder = new StringBuilder(); for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) { diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java index aa2aa19cc19..ccebe115f97 100644 --- a/api/src/com/cloud/agent/api/to/NicTO.java +++ b/api/src/com/cloud/agent/api/to/NicTO.java @@ -16,12 +16,15 @@ // under the License. package com.cloud.agent.api.to; +import java.util.List; + public class NicTO extends NetworkTO { int deviceId; Integer networkRateMbps; Integer networkRateMulticastMbps; boolean defaultNic; String uuid; + List nicSecIps; public NicTO() { super(); @@ -69,4 +72,12 @@ public class NicTO extends NetworkTO { public String toString() { return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString(); } + + public void setNicSecIps(List secIps) { + this.nicSecIps = secIps; + } + + public List getNicSecIps() { + return nicSecIps; + } } diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/com/cloud/network/security/SecurityGroupService.java index c6480323780..397de1ccb46 100644 --- a/api/src/com/cloud/network/security/SecurityGroupService.java +++ b/api/src/com/cloud/network/security/SecurityGroupService.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupC import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd; import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd; +import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -45,5 +46,6 @@ public interface SecurityGroupService { public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd); public List authorizeSecurityGroupEgress(AuthorizeSecurityGroupEgressCmd cmd); - + public boolean securityGroupRulesForVmSecIp(Long nicId, Long networkId, + String secondaryIp, boolean ruleAction); } diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java index cdfe8d38dc5..cedc793c197 100755 --- a/api/src/com/cloud/template/VirtualMachineTemplate.java +++ b/api/src/com/cloud/template/VirtualMachineTemplate.java @@ -37,6 +37,7 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte featured, // returns templates that have been marked as featured and public self, // returns templates that have been registered or created by the calling user selfexecutable, // same as self, but only returns templates that are ready to be deployed with + shared, // including templates that have been granted to the calling user by another user sharedexecutable, // ready templates that have been granted to the calling user by another user executable, // templates that are owned by the calling user, or public templates, that can be used to deploy a community, // returns templates that have been marked as public but not featured diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index bb37d085c8e..5683d58ab30 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -33,7 +33,7 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.UserContext; -@APICommand(name = "deleteUser", description="Creates a user for an account", responseObject=UserResponse.class) +@APICommand(name = "deleteUser", description="Deletes a user for an account", responseObject=SuccessResponse.class) public class DeleteUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteUserCmd.class.getName()); @@ -42,7 +42,7 @@ public class DeleteUserCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, required=true, description="Deletes a user") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, required=true, description="id of the user to be deleted") private Long id; @Inject RegionService _regionService; diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index 0f992743f6d..df6b3999dba 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -28,6 +28,8 @@ import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; import com.cloud.async.AsyncJob; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; @@ -83,6 +85,9 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { public Long getNetworkId() { Nic nic = _entityMgr.findById(Nic.class, nicId); + if (nic == null) { + throw new InvalidParameterValueException("Can't find network id for specified nic"); + } Long networkId = nic.getNetworkId(); return networkId; } @@ -98,6 +103,13 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { return null; } } + + public NetworkType getNetworkType() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.getNetworkType(); + } + @Override public long getEntityOwnerId() { Account caller = UserContext.current().getCaller(); @@ -134,7 +146,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { UserContext.current().setEventDetails("Nic Id: " + getNicId() ); String ip; - String SecondaryIp = null; + String secondaryIp = null; if ((ip = getIpaddress()) != null) { if (!NetUtils.isValidIp(ip)) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); @@ -142,15 +154,24 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { } try { - SecondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress()); + secondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress()); } catch (InsufficientAddressCapacityException e) { throw new InvalidParameterValueException("Allocating guest ip for nic failed"); } - if (SecondaryIp != null) { - s_logger.info("Associated ip address to NIC : " + SecondaryIp); + if (secondaryIp != null) { + if (getNetworkType() == NetworkType.Basic) { + // add security group rules for the secondary ip addresses + boolean success = false; + success = _securityGroupService.securityGroupRulesForVmSecIp(getNicId(), getNetworkId(), secondaryIp, (boolean) true); + if (success == false) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); + } + } + + s_logger.info("Associated ip address to NIC : " + secondaryIp); NicSecondaryIpResponse response = new NicSecondaryIpResponse(); - response = _responseGenerator.createSecondaryIPToNicResponse(ip, getNicId(), getNetworkId()); + response = _responseGenerator.createSecondaryIPToNicResponse(secondaryIp, getNicId(), getNetworkId()); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index cb5e0855f64..21a9a0c96b4 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -27,15 +27,21 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; import org.apache.cloudstack.api.response.SuccessResponse; import com.cloud.async.AsyncJob; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.event.EventTypes; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Network; import com.cloud.user.Account; import com.cloud.user.UserContext; +import com.cloud.vm.Nic; +import com.cloud.vm.NicSecondaryIp; @APICommand(name = "removeIpFromNic", description="Assigns secondary IP to NIC.", responseObject=SuccessResponse.class) public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName()); - private static final String s_name = "unassignsecondaryipaddrtonicresponse"; + private static final String s_name = "removeipfromnicresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -43,7 +49,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.UUID, required = true, entityType = NicSecondaryIpResponse.class, description="the ID of the secondary ip address to nic") - private long id; + private Long id; // unexposed parameter needed for events logging @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, expose=false) @@ -57,7 +63,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return "nic_secondary_ips"; } - public long getIpAddressId() { + public Long getIpAddressId() { return id; } @@ -80,6 +86,11 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return EventTypes.EVENT_NET_IP_ASSIGN; } + public NicSecondaryIp getIpEntry() { + NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId()); + return nicSecIp; + } + @Override public String getEventDescription() { return ("Disassociating ip address with id=" + id); @@ -98,15 +109,53 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return "addressinfo"; } + public Long getNetworkId() { + NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId()); + if (nicSecIp != null) { + Long networkId = nicSecIp.getNetworkId(); + return networkId; + } else { + return null; + } + } + + public NetworkType getNetworkType() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + if (ntwk != null) { + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.getNetworkType(); + } + return null; + } + @Override public void execute() throws InvalidParameterValueException { - UserContext.current().setEventDetails("Ip Id: " + getIpAddressId()); - boolean result = _networkService.releaseSecondaryIpFromNic(getIpAddressId()); - if (result) { - SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary ip address for the nic"); + UserContext.current().setEventDetails("Ip Id: " + id); + NicSecondaryIp nicSecIp = getIpEntry(); + + if (nicSecIp == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed"); + } + + if (getNetworkType() == NetworkType.Basic) { + //remove the security group rules for this secondary ip + boolean success = false; + success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getNetworkId(),nicSecIp.getIp4Address(), false); + if (success == false) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); + } + } + + try { + boolean result = _networkService.releaseSecondaryIpFromNic(id); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary ip address for the nic"); + } + } catch (InvalidParameterValueException e) { + throw new InvalidParameterValueException("Removing guest ip from nic failed"); } } diff --git a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java index 3464a63540e..695468faef2 100644 --- a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java @@ -20,28 +20,38 @@ import java.util.List; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; +import com.cloud.network.rules.FirewallRule; import com.cloud.serializer.Param; +import com.cloud.vm.NicSecondaryIp; import com.google.gson.annotations.SerializedName; +@EntityReference(value=NicSecondaryIp.class) @SuppressWarnings("unused") public class NicSecondaryIpResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the ID of the secondary private IP addr") - private Long id; + private String id; @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="Secondary IP address") private String ipAddr; @SerializedName(ApiConstants.NIC_ID) @Param(description="the ID of the nic") - private Long nicId; + private String nicId; @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the network") - private Long nwId; + private String nwId; @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the ID of the vm") - private Long vmId; + private String vmId; - public Long getId() { + @Override + public String getObjectId() { + return this.getId(); + } + + public String getId() { return id; } @@ -53,32 +63,32 @@ public class NicSecondaryIpResponse extends BaseResponse { this.ipAddr = ipAddr; } - public Long getNicId() { + public String getNicId() { return nicId; } - public void setNicId(Long nicId) { - this.nicId = nicId; + public void setNicId(String string) { + this.nicId = string; } - public Long getNwId() { + public String getNwId() { return nwId; } - public void setNwId(Long nwId) { + public void setNwId(String nwId) { this.nwId = nwId; } - public Long getVmId() { + public String getVmId() { return vmId; } - public void setVmId(Long vmId) { + public void setVmId(String vmId) { this.vmId = vmId; } - public Long setId(Long id) { - return id; + public void setId(String id) { + this.id = id; } diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 23566e204c0..7b64f49ee20 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -107,11 +107,7 @@ - - - - - + - - - - - - - - - - - true - - - diff --git a/client/tomcatconf/components-nonoss.xml.in b/client/tomcatconf/components-nonoss.xml.in deleted file mode 100755 index fbfc5cc2726..00000000000 --- a/client/tomcatconf/components-nonoss.xml.in +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - true - - - - - - diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in deleted file mode 100755 index 1d3faf384dc..00000000000 --- a/client/tomcatconf/components.xml.in +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - true - - - - 1 - 25 - 50000 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in index 20e0c32db57..7e3552db67e 100644 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ b/client/tomcatconf/nonossComponentContext.xml.in @@ -113,11 +113,7 @@ - - - - - +