diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index 3b1c005b1ec..d1166df4065 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -93,12 +93,13 @@ public interface VpcService { * @param restartRequired TODO * @param tags TODO * @param projectId TODO + * @param display TODO * @param vpc * @return */ public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, - Map tags, Long projectId); + Map tags, Long projectId, Boolean display); /** * Starts VPC which includes starting VPC provider and applying all the neworking rules on the backend diff --git a/api/src/com/cloud/projects/ProjectService.java b/api/src/com/cloud/projects/ProjectService.java index 53dd44bd013..dc882ef11b8 100644 --- a/api/src/com/cloud/projects/ProjectService.java +++ b/api/src/com/cloud/projects/ProjectService.java @@ -69,11 +69,11 @@ public interface ProjectService { Project updateProject(long id, String displayText, String newOwnerName) throws ResourceAllocationException; - Project addAccountToProject(long projectId, String accountName, String email); + boolean addAccountToProject(long projectId, String accountName, String email); - Project deleteAccountFromProject(long projectId, String accountName); + boolean deleteAccountFromProject(long projectId, String accountName); - Project updateInvitation(long projectId, String accountName, String token, boolean accept); + boolean updateInvitation(long projectId, String accountName, String token, boolean accept); Project activateProject(long projectId); diff --git a/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java b/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java index 0586117f0c6..63d2b7f7615 100644 --- a/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java @@ -16,6 +16,10 @@ // under the License. package org.apache.cloudstack.api; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.user.Account; + public abstract class BaseListAccountResourcesCmd extends BaseListDomainResourcesCmd { @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "list resources by account. Must be used with the domainId parameter.") @@ -24,4 +28,12 @@ public abstract class BaseListAccountResourcesCmd extends BaseListDomainResource public String getAccountName() { return accountName; } + + public Boolean getDisplay() { + Account caller = CallContext.current().getCallingAccount(); + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + return true; + } + return null; + } } diff --git a/api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java b/api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java index 8372b052a39..ef36038c5c4 100644 --- a/api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java @@ -88,10 +88,9 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd { } CallContext.current().setEventDetails("Project id: " + projectId + "; accountName " + accountName); - Project project = _projectService.addAccountToProject(getProjectId(), getAccountName(), getEmail()); - if (project != null) { - ProjectResponse response = _responseGenerator.createProjectResponse(project); - response.setResponseName(getCommandName()); + boolean result = _projectService.addAccountToProject(getProjectId(), getAccountName(), getEmail()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add account to the project"); diff --git a/api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java b/api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java index 4c6721a2997..5c891733b5a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java @@ -77,10 +77,9 @@ public class DeleteAccountFromProjectCmd extends BaseAsyncCmd { @Override public void execute() { CallContext.current().setEventDetails("Project id: " + projectId + "; accountName " + accountName); - Project project = _projectService.deleteAccountFromProject(projectId, accountName); - if (project != null) { - ProjectResponse response = _responseGenerator.createProjectResponse(project); - response.setResponseName(getCommandName()); + boolean result = _projectService.deleteAccountFromProject(projectId, accountName); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete account from the project"); diff --git a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java index 1f2b4505c83..109dcd0148b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.address; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -33,6 +32,7 @@ import org.apache.cloudstack.api.response.PhysicalNetworkResponse; import org.apache.cloudstack.api.response.VlanIpRangeResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; import com.cloud.network.IpAddress; import com.cloud.utils.Pair; @@ -90,6 +90,9 @@ public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List ips belonging to the VPC") private Long vpcId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -137,6 +140,14 @@ public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { return vpcId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java index 0d5de483615..a5d3cdb0e19 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.autoscale; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -31,6 +30,7 @@ import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.as.AutoScaleVmGroup; @@ -61,6 +61,9 @@ public class ListAutoScaleVmGroupsCmd extends BaseListProjectAndAccountResources @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the availability zone ID") private Long zoneId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -85,6 +88,14 @@ public class ListAutoScaleVmGroupsCmd extends BaseListProjectAndAccountResources return zoneId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java index 5e73053d956..782ccaec6dc 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.autoscale; import java.util.ArrayList; import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -58,6 +59,9 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, since = "4.4", description = "availability zone for the auto deployed virtual machine") private Long zoneId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -81,6 +85,15 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc public Long getZoneId() { return zoneId; } + + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java index 65614629f02..9585256959c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java @@ -20,8 +20,6 @@ package org.apache.cloudstack.api.command.user.firewall; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.Parameter; @@ -29,6 +27,7 @@ import org.apache.cloudstack.api.response.FirewallResponse; import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.log4j.Logger; import com.cloud.network.rules.FirewallRule; import com.cloud.utils.Pair; diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java index e0e1a40f3d8..01fc436f29b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.firewall; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -30,6 +29,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.log4j.Logger; import com.cloud.network.rules.FirewallRule; import com.cloud.utils.Pair; @@ -59,6 +59,9 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { since = "4.3") private Long networkId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -79,6 +82,14 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { return networkId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java index 1bb43ceb037..63b6ea72094 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.firewall; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -29,6 +28,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.log4j.Logger; import com.cloud.network.rules.PortForwardingRule; import com.cloud.utils.Pair; @@ -60,6 +60,9 @@ public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { since = "4.3") private Long networkId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -76,6 +79,14 @@ public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { return networkId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java index 41b9817bce6..f8696d4b3f6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.loadbalancer; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -30,6 +29,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; +import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.LoadBalancerContainer.Scheme; @@ -67,6 +67,9 @@ public class ListApplicationLoadBalancersCmd extends BaseListTaggedResourcesCmd @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "the network id of the Load Balancer") private Long networkId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -91,6 +94,14 @@ public class ListApplicationLoadBalancersCmd extends BaseListTaggedResourcesCmd return sourceIpNetworkId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + @Override public String getCommandName() { return s_name; diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java index c34ea3f09e4..c115fb76165 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.network; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -29,6 +28,7 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.log4j.Logger; import com.cloud.network.vpc.NetworkACL; import com.cloud.utils.Pair; @@ -55,6 +55,9 @@ public class ListNetworkACLListsCmd extends BaseListProjectAndAccountResourcesCm @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list network ACLs by specified name") private String name; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -75,6 +78,13 @@ public class ListNetworkACLListsCmd extends BaseListProjectAndAccountResourcesCm return name; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java index 41f96d31b84..4f9065bf2cd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.network; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -29,6 +28,7 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.log4j.Logger; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.utils.Pair; @@ -62,6 +62,9 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "list network ACL Items by Action") private String action; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,6 +93,14 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { return action; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java index d94c836aab7..2e54a078b74 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.network; import java.util.ArrayList; import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -81,6 +82,9 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "the network belongs to vpc") private Boolean forVpc; + @Parameter(name = ApiConstants.DISPLAY_NETWORK, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -137,6 +141,13 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { return forVpc; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java b/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java index 0ceb4ac877e..79e3f8a9cfd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.project; -import com.cloud.projects.Project; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -95,10 +94,9 @@ public class UpdateProjectInvitationCmd extends BaseAsyncCmd { @Override public void execute() { CallContext.current().setEventDetails("Project id: " + projectId + "; accountName " + accountName + "; accept " + getAccept()); - Project project = _projectService.updateInvitation(projectId, accountName, token, getAccept()); - if (project != null) { - ProjectResponse response = _responseGenerator.createProjectResponse(project); - response.setResponseName(getCommandName()); + boolean result = _projectService.updateInvitation(projectId, accountName, token, getAccept()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to join the project"); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java index 3c66f033494..408497cbc64 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.vm; import java.util.ArrayList; import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -59,6 +60,9 @@ public class ListNicsCmd extends BaseListCmd { @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list nic of the specific vm's network") private Long networkId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -93,6 +97,15 @@ public class ListNicsCmd extends BaseListCmd { return caller.getAccountId(); } + + public Boolean getDisplay() { + Account caller = CallContext.current().getCallingAccount(); + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + return true; + } + return display; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java index 3c0c8b039b3..1a564f60d9a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -115,6 +116,9 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list by the service offering", since = "4.4") private Long serviceOffId; + @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -205,6 +209,13 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { return dv; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java index 92afff4b23f..04c68fecbb7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java @@ -75,6 +75,9 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "list volumes by disk offering") private Long diskOfferingId; + @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -115,6 +118,13 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { return storageId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java index e81bf69d539..69a86930f8f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.vpc; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -29,6 +28,7 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.VpcOfferingResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; import com.cloud.network.vpc.Vpc; @@ -69,6 +69,9 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.RESTART_REQUIRED, type = CommandType.BOOLEAN, description = "list VPCs by restartRequired option") private Boolean restartRequired; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -109,6 +112,14 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd { return restartRequired; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -118,7 +129,7 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd { List vpcs = _vpcService.listVpcs(getId(), getVpcName(), getDisplayText(), getSupportedServices(), getCidr(), getVpcOffId(), getState(), getAccountName(), getDomainId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getZoneId(), this.isRecursive(), this.listAll(), getRestartRequired(), getTags(), - getProjectId()); + getProjectId(), getDisplay()); ListResponse response = new ListResponse(); List offeringResponses = new ArrayList(); for (Vpc vpc : vpcs) { diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java index 56acd41fc04..bcf00d9d4c6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.vpn; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -29,6 +28,7 @@ import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.api.response.RemoteAccessVpnResponse; +import org.apache.log4j.Logger; import com.cloud.network.RemoteAccessVpn; import com.cloud.utils.Pair; @@ -60,6 +60,9 @@ public class ListRemoteAccessVpnsCmd extends BaseListProjectAndAccountResourcesC since = "4.3") private Long networkId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -76,6 +79,14 @@ public class ListRemoteAccessVpnsCmd extends BaseListProjectAndAccountResourcesC return networkId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java index 28ab8b9dfac..1da2166ab0d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.vpn; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -28,6 +27,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.log4j.Logger; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.utils.Pair; @@ -48,6 +48,9 @@ public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "id of vpc") private Long vpcId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -60,6 +63,14 @@ public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd return vpcId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java index d1729d7bc09..359360bdedb 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java @@ -19,8 +19,7 @@ package org.apache.cloudstack.api.command.user.vpn; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; @@ -28,6 +27,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.log4j.Logger; import com.cloud.network.Site2SiteVpnGateway; import com.cloud.utils.Pair; @@ -49,6 +49,9 @@ public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "id of vpc") private Long vpcId; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) + private Boolean display; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -61,6 +64,14 @@ public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { return vpcId; } + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 1e91d38f465..82ac499a85e 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -945,6 +945,7 @@ label.project.view=Project View label.project=Project label.projects=Projects label.protocol=Protocol +label.provider=Provider label.providers=Providers label.public.interface=Public Interface label.public.ip=Public IP Address diff --git a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java index c345bb290cf..2a9a6025071 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java @@ -291,5 +291,4 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { List results = customSearch(sc, null); return results.get(0); } - } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 2be27860f07..b9246aa395d 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -85,12 +85,11 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, private static final ConfigKey JobExpireMinutes = new ConfigKey(Long.class, "job.expire.minutes", "Advanced", "1440", "Time (in minutes) for async-jobs to be kept in system", true, ConfigKey.Scope.Global, 60l); private static final ConfigKey JobCancelThresholdMinutes = new ConfigKey(Long.class, "job.cancel.threshold.minutes", "Advanced", "60", - "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, ConfigKey.Scope.Global, 60l); + "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, ConfigKey.Scope.Global, 240l); private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class); private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; // 3 seconds - private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 60; // 60 seconds private static final int MAX_ONETIME_SCHEDULE_SIZE = 50; private static final int HEARTBEAT_INTERVAL = 2000; @@ -706,14 +705,16 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, try { s_logger.trace("Begin cleanup expired async-jobs"); - Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - JobExpireMinutes.value() * 1000); + Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - JobExpireMinutes.value() * 60000); // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute // hopefully this will be fast enough to balance potential growth of job table //1) Expire unfinished jobs that weren't processed yet List l = _jobDao.getExpiredUnfinishedJobs(cutTime, 100); for (AsyncJobVO job : l) { - s_logger.trace("Expunging unfinished job " + job); + s_logger.info("Expunging unfinished job " + job); + + _jobMonitor.unregisterByJobId(job.getId()); expungeAsyncJob(job); } @@ -721,15 +722,19 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, List completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100); for (AsyncJobVO job : completedJobs) { s_logger.trace("Expunging completed job " + job); + expungeAsyncJob(job); } // forcefully cancel blocking queue items if they've been staying there for too long - List blockItems = _queueMgr.getBlockedQueueItems(JobCancelThresholdMinutes.value() * 1000, false); + List blockItems = _queueMgr.getBlockedQueueItems(JobCancelThresholdMinutes.value() * 60000, false); if (blockItems != null && blockItems.size() > 0) { for (SyncQueueItemVO item : blockItems) { if (item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) { + s_logger.info("Remove Job-" + item.getContentId() + " from Queue-" + item.getId() + " since it has been blocked for too long"); completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long"); + + _jobMonitor.unregisterByJobId(item.getContentId()); } // purge the item and resume queue processing diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java index 671818130f9..0b6f7a582b0 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.framework.jobs.impl; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Timer; import java.util.concurrent.atomic.AtomicInteger; @@ -38,8 +39,7 @@ import com.cloud.utils.component.ManagerBase; public class AsyncJobMonitor extends ManagerBase { public static final Logger s_logger = Logger.getLogger(AsyncJobMonitor.class); - @Inject - private MessageBus _messageBus; + @Inject private MessageBus _messageBus; private final Map _activeTasks = new HashMap(); private final Timer _timer = new Timer(); @@ -86,15 +86,16 @@ public class AsyncJobMonitor extends ManagerBase { synchronized (this) { for (Map.Entry entry : _activeTasks.entrySet()) { if (entry.getValue().millisSinceLastJobHeartbeat() > _inactivityWarningThresholdMs) { - s_logger.warn("Task (job-" + entry.getValue().getJobId() + ") has been pending for " + entry.getValue().millisSinceLastJobHeartbeat() / 1000 + - " seconds"); + s_logger.warn("Task (job-" + entry.getValue().getJobId() + ") has been pending for " + + entry.getValue().millisSinceLastJobHeartbeat() / 1000 + " seconds"); } } } } @Override - public boolean configure(String name, Map params) throws ConfigurationException { + public boolean configure(String name, Map params) + throws ConfigurationException { _messageBus.subscribe(AsyncJob.Topics.JOB_HEARTBEAT, MessageDispatcher.getDispatcher(this)); _timer.scheduleAtFixedRate(new ManagedContextTimerTask() { @@ -141,6 +142,25 @@ public class AsyncJobMonitor extends ManagerBase { } } + public void unregisterByJobId(long jobId) { + synchronized (this) { + Iterator> it = _activeTasks.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + if (entry.getValue().getJobId() == jobId) { + s_logger.info("Remove Job-" + entry.getValue().getJobId() + " from job monitoring due to job cancelling"); + + if (entry.getValue().isPoolThread()) + _activePoolThreads.decrementAndGet(); + else + _activeInplaceThreads.decrementAndGet(); + + it.remove(); + } + } + } + } + public int getActivePoolThreads() { return _activePoolThreads.get(); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 3553b5ca9c9..1056bcf21f2 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3063,7 +3063,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv NicTO[] nics = vm.getNics(); - boolean success = false; + boolean skipDisconnect = false; try { Connect conn = LibvirtConnection.getConnectionByVmName(vm.getName()); @@ -3079,13 +3079,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - _storagePoolMgr.connectPhysicalDisksViaVmSpec(vm); + if (!_storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) { + skipDisconnect = true; + return new PrepareForMigrationAnswer(cmd, "failed to connect physical disks to host"); + } synchronized (_vms) { _vms.put(vm.getName(), State.Migrating); } - success = true; + skipDisconnect = true; return new PrepareForMigrationAnswer(cmd); } catch (LibvirtException e) { @@ -3095,7 +3098,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } catch (URISyntaxException e) { return new PrepareForMigrationAnswer(cmd, e.toString()); } finally { - if (!success) { + if (!skipDisconnect) { _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm); } } @@ -3628,7 +3631,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv createVbd(conn, vmSpec, vmName, vm); - _storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec); + if (!_storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) { + return new StartAnswer(cmd, "Failed to connect physical disks to host"); + } createVifs(vmSpec, vm); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index 0c1d55d6c32..5de8bd26ae2 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -244,13 +244,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePoolDef spd; StoragePool sp = null; + Secret s = null; String[] userInfoTemp = userInfo.split(":"); if (userInfoTemp.length == 2) { LibvirtSecretDef sd = new LibvirtSecretDef(usage.CEPH, uuid); - Secret s = null; - sd.setCephName(userInfoTemp[0] + "@" + host + ":" + port + "/" + path); try { @@ -258,15 +257,16 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { s = conn.secretDefineXML(sd.toString()); s.setValue(Base64.decodeBase64(userInfoTemp[1])); } catch (LibvirtException e) { - s_logger.error(e.toString()); + s_logger.error("Failed to define the libvirt secret: " + e.toString()); if (s != null) { try { s.undefine(); s.free(); } catch (LibvirtException l) { - s_logger.debug("Failed to define secret with: " + l.toString()); + s_logger.debug("Failed to undefine the libvirt secret: " + l.toString()); } } + return null; } spd = new LibvirtStoragePoolDef(poolType.RBD, uuid, uuid, host, port, path, userInfoTemp[0], authType.CEPH, uuid); } else { @@ -278,7 +278,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sp = conn.storagePoolCreateXML(spd.toString(), 0); return sp; } catch (LibvirtException e) { - s_logger.debug(e.toString()); + s_logger.debug("Failed to create RBD storage pool: " + e.toString()); if (sp != null) { try { if (sp.isPersistent() == 1) { @@ -289,9 +289,20 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } sp.free(); } catch (LibvirtException l) { - s_logger.debug("Failed to define RBD storage pool with: " + l.toString()); + s_logger.debug("Failed to undefine RBD storage pool: " + l.toString()); } } + + if (s != null) { + try { + s_logger.debug("Failed to create the RBD storage pool, cleaning up the libvirt secret"); + s.undefine(); + s.free(); + } catch (LibvirtException se) { + s_logger.debug("Failed to remove the libvirt secret: " + se.toString()); + } + } + return null; } } @@ -512,6 +523,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } + if (sp == null) { + throw new CloudRuntimeException("Failed to create storage pool: " + name); + } + try { if (sp.isActive() == 0) { s_logger.debug("attempting to activate pool " + name); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index 37394816d24..6fe9b40fa64 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -87,6 +87,7 @@ import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetNetworkACLCommand; @@ -97,6 +98,7 @@ import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticRouteCommand; import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; @@ -365,7 +367,9 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage } else if (cmd instanceof PvlanSetupCommand) { return _mockNetworkMgr.setupPVLAN((PvlanSetupCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return this.storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); + } else if (cmd instanceof VpnUsersCfgCommand || cmd instanceof RemoteAccessVpnCfgCommand) { + return new Answer(cmd); } else { s_logger.error("Simulator does not implement command of type " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java b/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java index ff5c3a6fc6d..4497448af09 100644 --- a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java +++ b/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java @@ -23,6 +23,7 @@ import java.util.UUID; import javax.inject.Inject; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.log4j.Logger; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -78,6 +79,11 @@ public class SimulatorImageStoreDriverImpl extends BaseImageStoreDriverImpl { } } + @Override + public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback callback) { + callback.complete(new CommandResult()); + } + protected void createTemplate(DataObject data, AsyncCompletionCallback callback) { CreateContext context = new CreateContext(callback, data); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); diff --git a/plugins/network-elements/juniper-contrail/test/resources/log4j.properties b/plugins/network-elements/juniper-contrail/test/resources/log4j.properties index 138a9610873..2e724f4e902 100644 --- a/plugins/network-elements/juniper-contrail/test/resources/log4j.properties +++ b/plugins/network-elements/juniper-contrail/test/resources/log4j.properties @@ -25,7 +25,7 @@ log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender log4j.appender.rolling.layout=org.apache.log4j.PatternLayout log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%c{3}] (%t:%x) %m%n log4j.appender.rolling.file.threshold=DEBUG -log4j.appender.rolling.File=./logs/testclient.log +log4j.appender.rolling.File=./target/logs/testclient.log log4j.appender.rolling.DatePattern='.'yyy-MM-dd log4j.appender.rolling.file.append=false log4j.category.org.apache=INFO, rolling, stdout diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 6e2b36cb0db..69c25ee3bf3 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -712,6 +712,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { boolean listAll = cmd.listAll(); Long id = cmd.getId(); Map tags = cmd.getTags(); + Boolean display = cmd.getDisplay(); Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); @@ -736,6 +737,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { c.addCriteria(Criteria.VPC_ID, cmd.getVpcId()); c.addCriteria(Criteria.AFFINITY_GROUP_ID, cmd.getAffinityGroupId()); c.addCriteria(Criteria.SERVICE_OFFERING_ID, cmd.getServiceOfferingId()); + c.addCriteria(Criteria.DISPLAY, cmd.getDisplay()); if (domainId != null) { c.addCriteria(Criteria.DOMAINID, domainId); @@ -793,6 +795,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Object vpcId = c.getCriteria(Criteria.VPC_ID); Object affinityGroupId = c.getCriteria(Criteria.AFFINITY_GROUP_ID); Object serviceOffId = c.getCriteria(Criteria.SERVICE_OFFERING_ID); + Object display = c.getCriteria(Criteria.DISPLAY); sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -812,7 +815,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (serviceOffId != null) { sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); } - + if (display != null) { + sb.and("display", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ); + } if (groupId != null && (Long)groupId != -1) { sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ); } @@ -872,6 +877,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("serviceOfferingId", serviceOffId); } + if (display != null) { + sc.setParameters("display", display); + } + if (id != null) { sc.setParameters("id", id); } @@ -1623,6 +1632,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { boolean isRootAdmin = _accountMgr.isRootAdmin(caller.getType()); Long storageId = cmd.getStorageId(); Long diskOffId = cmd.getDiskOfferingId(); + Boolean display = cmd.getDisplay(); Long zoneId = cmd.getZoneId(); Long podId = null; @@ -1657,6 +1667,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("storageId", sb.entity().getPoolId(), SearchCriteria.Op.EQ); sb.and("diskOfferingId", sb.entity().getDiskOfferingId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ); // Only return volumes that are not destroyed sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); sb.and("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ); @@ -1684,6 +1695,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("name", name); } + if (display != null) { + sc.setParameters("display", display); + } + sc.setParameters("systemUse", 1); if (tags != null && !tags.isEmpty()) { diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index c42d4214f40..ebeb31a6f88 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1383,6 +1383,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Boolean canUseForDeploy = cmd.canUseForDeploy(); Map tags = cmd.getTags(); Boolean forVpc = cmd.getForVpc(); + Boolean display = cmd.getDisplay(); // 1) default is system to false if not specified // 2) reset parameter to false if it's specified by the regular user @@ -1515,33 +1516,33 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { //get account level networks networksToReturn.addAll(listAccountSpecificNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter, permittedAccounts)); + specifyIpRanges, vpcId, tags, display), searchFilter, permittedAccounts)); //get domain level networks if (domainId != null) { networksToReturn.addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter, domainId, false)); + specifyIpRanges, vpcId, tags, display), searchFilter, domainId, false)); } } else { //add account specific networks networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); + specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive)); //add domain specific networks of domain + parent domains networksToReturn.addAll(listDomainSpecificNetworksByDomainPath( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); + specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive)); //add networks of subdomains if (domainId == null) { networksToReturn.addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter, caller.getDomainId(), true)); + specifyIpRanges, vpcId, tags, display), searchFilter, caller.getDomainId(), true)); } } } else { networksToReturn = _networksDao.search( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, - specifyIpRanges, vpcId, tags), searchFilter); + specifyIpRanges, vpcId, tags, display), searchFilter); } if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) { @@ -1608,7 +1609,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, - Map tags) { + Map tags, Boolean display) { SearchCriteria sc = sb.create(); @@ -1622,6 +1623,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { sc.addAnd("name", SearchCriteria.Op.SC, ssc); } + if (display != null) { + sc.addAnd("displayNetwork", SearchCriteria.Op.EQ, display); + } + if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); } @@ -4007,14 +4012,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Long nicId = cmd.getNicId(); long vmId = cmd.getVmId(); Long networkId = cmd.getNetworkId(); - UserVmVO userVm = _userVmDao.findById(vmId); - if (userVm == null) { + if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) { InvalidParameterValueException ex = new InvalidParameterValueException("Virtual mahine id does not exist"); ex.addProxyObject(Long.valueOf(vmId).toString(), "vmId"); throw ex; } + _accountMgr.checkAccess(caller, null, true, userVm); return _networkMgr.listVmNics(vmId, nicId, networkId); } diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index ff2b2eabd31..208b4a42cfd 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -454,6 +454,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale String otherDeployParams = cmd.getOtherDeployParams(); Long serviceOffId = cmd.getServiceOfferingId(); Long zoneId = cmd.getZoneId(); + Boolean display = cmd.getDisplay(); SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); @@ -463,6 +464,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); SearchCriteria sc = searchWrapper.buildSearchCriteria(); if (id != null) { @@ -483,6 +485,10 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sc.setParameters("zoneId", zoneId); } + if (display != null) { + sc.setParameters("display", display); + } + return searchWrapper.search(); } @@ -864,6 +870,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale Long loadBalancerId = cmd.getLoadBalancerId(); Long profileId = cmd.getProfileId(); Long zoneId = cmd.getZoneId(); + Boolean forDisplay = cmd.getDisplay(); SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); @@ -872,6 +879,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sb.and("loadBalancerId", sb.entity().getLoadBalancerId(), SearchCriteria.Op.EQ); sb.and("profileId", sb.entity().getProfileId(), SearchCriteria.Op.EQ); sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); if (policyId != null) { SearchBuilder asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder(); @@ -895,6 +903,9 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale if (policyId != null) { sc.setJoinParameters("asVmGroupPolicySearch", "policyId", policyId); } + if (forDisplay != null) { + sc.setParameters("display", forDisplay); + } return searchWrapper.search(); } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index 853de4495c3..ca474d6b91f 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -259,6 +259,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, Long networkId = cmd.getNetworkId(); Map tags = cmd.getTags(); FirewallRule.TrafficType trafficType = cmd.getTrafficType(); + Boolean display = cmd.getDisplay(); Account caller = CallContext.current().getCallingAccount(); List permittedAccounts = new ArrayList(); @@ -287,6 +288,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, sb.and("networkId", sb.entity().getNetworkId(), Op.EQ); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); + sb.and("display", sb.entity().isDisplay(), Op.EQ); if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); @@ -317,6 +319,10 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, } } + if (display != null) { + sc.setParameters("display", display); + } + if (ipId != null) { sc.setParameters("ip", ipId); } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 06c478cf9b2..ad977a2b5f4 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -779,6 +779,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules Long id = cmd.getId(); Map tags = cmd.getTags(); Long networkId = cmd.getNetworkId(); + Boolean display = cmd.getDisplay(); Account caller = CallContext.current().getCallingAccount(); List permittedAccounts = new ArrayList(); @@ -806,6 +807,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); sb.and("networkId", sb.entity().getNetworkId(), Op.EQ); + sb.and("display", sb.entity().isDisplay(), Op.EQ); if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); @@ -826,6 +828,10 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules sc.setParameters("id", id); } + if (display != null) { + sc.setParameters("display", display); + } + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PortForwardingRule.toString()); diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index b043381ad6c..1bec06de32f 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -118,10 +118,13 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ Long networkId = cmd.getNetworkId(); Long vpcId = cmd.getVpcId(); String keyword = cmd.getKeyword(); + Boolean display = cmd.getDisplay(); + SearchBuilder sb = _networkACLDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), Op.EQ); sb.and("name", sb.entity().getName(), Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), Op.IN); + sb.and("display", sb.entity().isDisplay(), Op.EQ); Account caller = CallContext.current().getCallingAccount(); @@ -140,6 +143,10 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ sc.addAnd("name", SearchCriteria.Op.SC, ssc); } + if (display != null) { + sc.setParameters("display", display); + } + if(id != null){ sc.setParameters("id", id); } @@ -477,6 +484,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ String action = cmd.getAction(); Map tags = cmd.getTags(); Account caller = CallContext.current().getCallingAccount(); + Boolean display = cmd.getDisplay(); Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _networkACLItemDao.createSearchBuilder(); @@ -486,6 +494,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); sb.and("protocol", sb.entity().getProtocol(), Op.EQ); sb.and("action", sb.entity().getAction(), Op.EQ); + sb.and("display", sb.entity().isDisplay(), Op.EQ); if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); @@ -508,6 +517,10 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ SearchCriteria sc = sb.create(); + if (display != null) { + sc.setParameters("display", display); + } + if (id != null) { sc.setParameters("id", id); } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 2157eacf986..403b95e3a1b 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -813,7 +813,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Override public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, - Map tags, Long projectId) { + Map tags, Long projectId, Boolean display) { Account caller = CallContext.current().getCallingAccount(); List permittedAccounts = new ArrayList(); @@ -836,6 +836,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ); sb.and("cidr", sb.entity().getCidr(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); @@ -878,6 +879,10 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } } + if (display != null) { + sc.setParameters("display", display); + } + if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index b61e7b16ab9..0306fad1733 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -618,6 +618,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc Long vpnId = cmd.getId(); Long networkId = cmd.getNetworkId(); List permittedAccounts = new ArrayList(); + Boolean display = cmd.getDisplay(); if (ipAddressId != null) { PublicIpAddress publicIp = _networkMgr.getPublicIpAddress(ipAddressId); @@ -648,6 +649,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc sb.and("id", sb.entity().getId(), Op.EQ); sb.and("networkId", sb.entity().getNetworkId(), Op.EQ); sb.and("state", sb.entity().getState(), Op.EQ); + sb.and("display", sb.entity().isDisplay(), Op.EQ); SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 05fec85f7d7..66a2b580aab 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -611,6 +611,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn public Pair, Integer> searchForVpnGateways(ListVpnGatewaysCmd cmd) { Long id = cmd.getId(); Long vpcId = cmd.getVpcId(); + Boolean display = cmd.getDisplay(); Long domainId = cmd.getDomainId(); boolean isRecursive = cmd.isRecursive(); @@ -635,6 +636,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -643,6 +645,10 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn sc.addAnd("id", SearchCriteria.Op.EQ, id); } + if (display != null) { + sc.setParameters("display", display); + } + if (vpcId != null) { sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); } @@ -655,6 +661,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn public Pair, Integer> searchForVpnConnections(ListVpnConnectionsCmd cmd) { Long id = cmd.getId(); Long vpcId = cmd.getVpcId(); + Boolean display = cmd.getDisplay(); Long domainId = cmd.getDomainId(); boolean isRecursive = cmd.isRecursive(); @@ -678,6 +685,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); if (vpcId != null) { SearchBuilder gwSearch = _vpnGatewayDao.createSearchBuilder(); @@ -688,6 +696,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + if (display != null) { + sc.setParameters("display", display); + } if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); } diff --git a/server/src/com/cloud/projects/ProjectManager.java b/server/src/com/cloud/projects/ProjectManager.java index 538104b8776..f5681464615 100644 --- a/server/src/com/cloud/projects/ProjectManager.java +++ b/server/src/com/cloud/projects/ProjectManager.java @@ -25,7 +25,7 @@ public interface ProjectManager extends ProjectService { boolean canModifyProjectAccount(Account caller, long accountId); - Project deleteAccountFromProject(long projectId, long accountId); + boolean deleteAccountFromProject(long projectId, long accountId); List listPermittedProjectAccounts(long accountId); diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index a3c7eda7f2d..5a0ed1cf64c 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -373,10 +373,10 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @DB - public Project deleteAccountFromProject(final long projectId, final long accountId) { - return Transaction.execute(new TransactionCallback() { + public boolean deleteAccountFromProject(final long projectId, final long accountId) { + return Transaction.execute(new TransactionCallback() { @Override - public Project doInTransaction(TransactionStatus status) { + public Boolean doInTransaction(TransactionStatus status) { boolean success = true; //remove account @@ -392,7 +392,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } } - return success ? getProject(projectAccount.getProjectId()) : null; + return success; } }); } @@ -514,7 +514,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true) - public Project addAccountToProject(long projectId, String accountName, String email) { + public boolean addAccountToProject(long projectId, String accountName, String email) { Account caller = CallContext.current().getCallingAccount(); //check that the project exists @@ -556,7 +556,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId()); if (projectAccount != null) { s_logger.debug("Account " + accountName + " already added to the project id=" + projectId); - return project; + return true; } } @@ -567,21 +567,21 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { throw new InvalidParameterValueException("Account information is required for assigning account to the project"); } if (assignAccountToProject(project, account.getId(), ProjectAccount.Role.Regular) != null) { - return project; + return true; } else { s_logger.warn("Failed to add account " + accountName + " to project id=" + projectId); - return null; + return false; } } } - private Project inviteAccountToProject(Project project, Account account, String email) { + private boolean inviteAccountToProject(Project project, Account account, String email) { if (account != null) { if (createAccountInvitation(project, account.getId()) != null) { - return project; + return true; } else { s_logger.warn("Failed to generate invitation for account " + account.getAccountName() + " to project id=" + project); - return null; + return false; } } @@ -589,19 +589,19 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { //generate the token String token = generateToken(10); if (generateTokenBasedInvitation(project, email, token) != null) { - return project; + return true; } else { s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project); - return null; + return false; } } - return null; + return false; } @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async = true) - public Project deleteAccountFromProject(long projectId, String accountName) { + public boolean deleteAccountFromProject(long projectId, String accountName) { Account caller = CallContext.current().getCallingAccount(); //check that the project exists @@ -725,7 +725,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async = true) - public Project updateInvitation(final long projectId, String accountName, String token, final boolean accept) { + public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) { Account caller = CallContext.current().getCallingAccount(); Long accountId = null; boolean result = true; @@ -806,7 +806,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId); } - return result ? project : null; + return result; } @Override diff --git a/server/src/com/cloud/server/Criteria.java b/server/src/com/cloud/server/Criteria.java index de29e3ee5e0..02bafa7b56f 100755 --- a/server/src/com/cloud/server/Criteria.java +++ b/server/src/com/cloud/server/Criteria.java @@ -85,6 +85,7 @@ public class Criteria { public static final String VPC_ID = "vpcId"; public static final String AFFINITY_GROUP_ID = "affinitygroupid"; public static final String SERVICE_OFFERING_ID = "serviceofferingid"; + public static final String DISPLAY = "display"; public Criteria(String orderBy, Boolean ascending, Long offset, Long limit) { this.offset = offset; diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 2a08ddc4abb..62faafc68b3 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1900,6 +1900,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Boolean sourceNat = cmd.getIsSourceNat(); Boolean staticNat = cmd.getIsStaticNat(); Long vpcId = cmd.getVpcId(); + Boolean forDisplay = cmd.getDisplay(); Map tags = cmd.getTags(); Boolean isAllocated = cmd.isAllocatedOnly(); @@ -1935,6 +1936,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.and("isSourceNat", sb.entity().isSourceNat(), SearchCriteria.Op.EQ); sb.and("isStaticNat", sb.entity().isOneToOneNat(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); if (forLoadBalancing != null && forLoadBalancing) { SearchBuilder lbSearch = _loadbalancerDao.createSearchBuilder(); @@ -2032,6 +2034,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.setParameters("associatedNetworkIdEq", associatedNetworkId); } + if (forDisplay != null) { + sc.setParameters("display", forDisplay); + } + Pair, Integer> result = _publicIpAddressDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java index ab5a0dde324..cafdb273952 100644 --- a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java +++ b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -383,6 +383,7 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A String keyword = cmd.getKeyword(); Scheme scheme = cmd.getScheme(); Long networkId = cmd.getNetworkId(); + Boolean display = cmd.getDisplay(); Map tags = cmd.getTags(); @@ -406,6 +407,7 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A sb.and("sourceIpAddressNetworkId", sb.entity().getSourceIpNetworkId(), SearchCriteria.Op.EQ); sb.and("scheme", sb.entity().getScheme(), SearchCriteria.Op.EQ); sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ); + sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ); //list only load balancers having not null sourceIp/sourceIpNtwkId sb.and("sourceIpAddress", sb.entity().getSourceIp(), SearchCriteria.Op.NNULL); @@ -467,6 +469,10 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A } } + if (display != null) { + sc.setParameters("display", display); + } + Pair, Integer> result = _lbDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } diff --git a/server/test/com/cloud/projects/MockProjectManagerImpl.java b/server/test/com/cloud/projects/MockProjectManagerImpl.java index 7afd671d097..dc377ff6f42 100644 --- a/server/test/com/cloud/projects/MockProjectManagerImpl.java +++ b/server/test/com/cloud/projects/MockProjectManagerImpl.java @@ -87,21 +87,21 @@ public class MockProjectManagerImpl extends ManagerBase implements ProjectManage } @Override - public Project addAccountToProject(long projectId, String accountName, String email) { + public boolean addAccountToProject(long projectId, String accountName, String email) { // TODO Auto-generated method stub - return null; + return false; } @Override - public Project deleteAccountFromProject(long projectId, String accountName) { + public boolean deleteAccountFromProject(long projectId, String accountName) { // TODO Auto-generated method stub - return null; + return false; } @Override - public Project updateInvitation(long projectId, String accountName, String token, boolean accept) { + public boolean updateInvitation(long projectId, String accountName, String token, boolean accept) { // TODO Auto-generated method stub - return null; + return false; } @Override @@ -165,9 +165,9 @@ public class MockProjectManagerImpl extends ManagerBase implements ProjectManage } @Override - public Project deleteAccountFromProject(long projectId, long accountId) { + public boolean deleteAccountFromProject(long projectId, long accountId) { // TODO Auto-generated method stub - return null; + return false; } @Override diff --git a/test/integration/component/test_multiple_ips_per_nic.py b/test/integration/component/test_multiple_ips_per_nic.py index 7d7e9f1ade2..dcbb453e7eb 100644 --- a/test/integration/component/test_multiple_ips_per_nic.py +++ b/test/integration/component/test_multiple_ips_per_nic.py @@ -34,7 +34,10 @@ from marvin.integration.lib.base import (Account, VPC, NIC, Domain, - PublicIPAddress) + PublicIPAddress, + StaticNATRule, + FireWallRule, + NATRule) from marvin.integration.lib.common import (get_domain, get_zone, get_template, @@ -44,7 +47,7 @@ from marvin.integration.lib.common import (get_domain, shouldTestBeSkipped) from nose.plugins.attrib import attr -from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, SHARED_NETWORK +from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, SHARED_NETWORK, FAIL from ddt import ddt, data def createNetwork(self, networkType): @@ -102,6 +105,31 @@ def CreateEnabledNetworkOffering(apiclient, networkServices): assert result[0] == PASS, "Network offering creation/enabling failed due to %s" % result[2] return result[1] +def createNetworkRules(self, virtual_machine, network, vmguestip, networktype, ruletype): + """ Acquire public ip in the given network, open firewall if required and + create NAT rule for the public ip to the given guest vm ip address""" + + try: + public_ip = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if networktype == VPC_NETWORK else None) + + if networktype != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + if ruletype == "nat": + NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip.ipaddress.id, + networkid=network.id, vmguestip = vmguestip) + elif ruletype == "staticnat": + StaticNATRule.enable(self.apiclient, public_ip.ipaddress.id, virtual_machine.id, network.id, vmguestip=vmguestip) + except Exception: + return FAIL + + return PASS + @ddt class TestBasicOperations(cloudstackTestCase): """Test Basic operations (add/remove/list) IP to/from NIC @@ -450,3 +478,376 @@ class TestBasicOperations(cloudstackTestCase): self.fail("Removing seondary IP %s from NIC failed as expected with Exception %s" % (ipaddress_1.id,e)) return + +@ddt +class TestNetworkRules(cloudstackTestCase): + """Test PF/NAT/static nat rules with the secondary IPs + """ + + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestNetworkRules,cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + + # Fill services from the external config file + cls.services = cloudstackTestClient.getConfigParser().parsedDict + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.mode = str(cls.zone.networktype).lower() + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [cls.service_offering] + cls.services["shared_network_offering"]["specifyVlan"] = "True" + cls.services["shared_network_offering"]["specifyIpRanges"] = "True" + + cls.shared_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["shared_network_offering"]) + cls._cleanup.append(cls.shared_network_offering) + + if cls.mode == "advanced": + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, cls.services["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_network_offering_vpc = CreateEnabledNetworkOffering(cls.api_client, cls.services["nw_offering_isolated_vpc"]) + cls._cleanup.append(cls.isolated_network_offering_vpc) + cls.vpc_off = VpcOffering.create(cls.api_client, cls.services["vpc_offering"]) + cls.vpc_off.update(cls.api_client, state='Enabled') + cls._cleanup.append(cls.vpc_off) + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [ ] + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + self.cleanup[:] = [] + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def VerifyStaticNatForPublicIp(self, ipaddressid, natrulestatus): + """ List public IP and verify that NAT rule status for the IP is as desired """ + + publiciplist = PublicIPAddress.list(self.apiclient, id=ipaddressid, listall=True) + self.assertEqual(validateList(publiciplist)[0], PASS, "Public IP list validation failed") + self.assertEqual(publiciplist[0].isstaticnat, natrulestatus, "isstaticnat should be %s, it is %s" % + (natrulestatus, publiciplist[0].isstaticnat)) + + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_add_PF_rule(self, value): + """ Add secondary IP to NIC of a VM""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire public IP, open firewall for it, and + # create NAT rule for this public IP to the 1st secondary IP + # 5. Repeat step 4 for another public IP + # 6. Repeat step 4 for 2nd secondary IP + # 7. Repeat step 4 for invalid secondary IP + + # Validations: + # 1. Step 4 should succeed + # 2. Step 5 should succeed + # 3. Step 6 should succeed + # 4. Step 7 should fail + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_1.ipaddress, value, ruletype="nat"), + PASS, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_1.ipaddress, value, ruletype="nat"), + PASS, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_2.ipaddress, value, ruletype="nat"), + PASS, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, "255.255.255.300", value, ruletype="nat"), + FAIL, "Failure in NAT rule creation") + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_delete_PF_nat_rule(self, value): + """ Add secondary IP to NIC of a VM""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add secondary IP to the default nic of VM + # 4. Acquire public IP, open firewall for it, and + # create NAT rule for this public IP to the 1st secondary IP + # 5. Try to delete secondary IP when NAT rule exists for it + # 6. Delete firewall rule and NAT rule + + # Validations: + # 1. Step 5 should fail + # 2. Step 6 should succeed + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + firewallrule = None + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + public_ip = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + if value != VPC_NETWORK: + firewallrule = FireWallRule.create(self.apiclient,ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + # Create NAT rule + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + try: + NIC.removeIp(self.apiclient, ipaddressid=ipaddress_1.id) + self.fail("Removing secondary IP succeeded while it had active NAT rule on it, should have failed") + except Exception as e: + self.debug("Removing secondary IP with active NAT rule failed as expected") + + if firewallrule: + try: + firewallrule.delete(self.apiclient) + except Exception as e: + self.fail("Exception while deleting firewall rule %s: %s" % (firewallrule.id, e)) + + try: + natrule.delete(self.apiclient) + except Exception as e: + self.fail("Exception while deleting nat rule %s: %s" % (natrule.id, e)) + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_disassociate_ip_mapped_to_secondary_ip_through_PF_rule(self, value): + """ Add secondary IP to NIC of a VM""" + + ## Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add secondary IP to the default nic of VM + # 4. Acquire public IP, open firewall for it, and + # create NAT rule for this public IP to the 1st secondary IP + # 5. Try to delete the public IP used for NAT rule + + # Validations: + # 1. Step 5 should succeed + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + public_ip = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + # Create NAT rule + natrule = NATRule.create(self.api_client, virtual_machine, + self.services["natrule"],ipaddressid=public_ip.ipaddress.id, + networkid=network.id, vmguestip = ipaddress_1.ipaddress) + + try: + public_ip.delete(self.apiclient) + except Exception as e: + self.fail("Exception while deleting nat rule %s: %s" % (natrule.id, e)) + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_add_static_nat_rule(self, value): + """ Add secondary IP to NIC of a VM""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire public IP, open firewall for it, and + # create static NAT rule for this public IP to the 1st secondary IP + # 5. Repeat step 4 for another public IP + # 6. Repeat step 4 for 2nd secondary IP + # 7. Repeat step 4 for invalid secondary IP + # 8. Try to remove 1st secondary IP (with active static nat rule) + + # Validations: + # 1. Step 4 should succeed + # 2. Step 5 should succeed + # 3. Step 6 should succeed + # 4. Step 7 should fail + # 5. Step 8 should succeed + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + try: + ipaddress_2 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_1.ipaddress, value, ruletype="staticnat"), + PASS, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_1.ipaddress, value, ruletype="staticnat"), + FAIL, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, ipaddress_2.ipaddress, value, ruletype="staticnat"), + PASS, "Failure in creating NAT rule") + self.assertEqual(createNetworkRules(self, virtual_machine, network, "255.255.255.300", value, ruletype="staticnat"), + FAIL, "Failure in NAT rule creation") + + try: + NIC.removeIp(self.apiclient, ipaddress_1.id) + self.fail("Ip address should not get removed when active static NAT rule is defined for it") + except Exception as e: + self.debug("Exception while removing secondary ip address as expected because static nat rule is present for it") + return + + @data(ISOLATED_NETWORK, SHARED_NETWORK, VPC_NETWORK) + @attr(tags=["advanced"]) + def test_disable_static_nat(self, value): + """ Add secondary IP to NIC of a VM""" + + # Steps: + # 1. Create Account and create network in it (isoalted/ shared/ vpc) + # 2. Deploy a VM in this network and account + # 3. Add 2 secondary IPs to the default nic of VM + # 4. Acquire public IP, open firewall for it, and + # enable static NAT rule for this public IP to the 1st secondary IP + # 5. Disable the static nat rule and enable it again + + # Validations: + # 1. Verify step 5 by listing seconday IP and checking the appropriate flag + + self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id) + self.cleanup.append(self.account) + + network = createNetwork(self, value) + + try: + virtual_machine = VirtualMachine.create(self.apiclient,self.services["virtual_machine"], + networkids=[network.id],serviceofferingid=self.service_offering.id, + accountid=self.account.name,domainid=self.account.domainid) + except Exception as e: + self.fail("vm creation failed: %s" % e) + + try: + ipaddress_1 = NIC.addIp(self.apiclient, id=virtual_machine.nic[0].id) + except Exception as e: + self.fail("Failed while adding secondary IP to NIC of vm %s" % virtual_machine.id) + + public_ip = PublicIPAddress.create(self.api_client,accountid=self.account.name, + zoneid=self.zone.id,domainid=self.account.domainid, + networkid=network.id, vpcid = network.vpcid if value == VPC_NETWORK else None) + + if value != VPC_NETWORK: + FireWallRule.create(self.apiclient,ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[self.services["fwrule"]["cidr"]], + startport=self.services["fwrule"]["startport"],endport=self.services["fwrule"]["endport"]) + + StaticNATRule.enable(self.apiclient, public_ip.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_1.ipaddress) + + self.VerifyStaticNatForPublicIp(public_ip.ipaddress.id, True) + + # Disabling static NAT + StaticNATRule.disable(self.apiclient, public_ip.ipaddress.id) + + self.VerifyStaticNatForPublicIp(public_ip.ipaddress.id, False) + + StaticNATRule.enable(self.apiclient, public_ip.ipaddress.id, virtual_machine.id, + network.id, vmguestip=ipaddress_1.ipaddress) + + self.VerifyStaticNatForPublicIp(public_ip.ipaddress.id, True) + + public_ip.delete(self.apiclient) + return diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 2d49c044c8a..77c548792f1 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -2338,6 +2338,11 @@ div.detail-group.actions td { position: relative; top: 5px; left: 7px; + /*+text-shadow:0px -1px 1px #464646;*/ + -moz-text-shadow: 0px -1px 1px #464646; + -webkit-text-shadow: 0px -1px 1px #464646; + -o-text-shadow: 0px -1px 1px #464646; + text-shadow: 0px -1px 1px #464646; } #header div.notifications:hover { @@ -2594,10 +2599,9 @@ div.detail-group.actions td { position: relative; left: 14px; top: 13px; - font-size: 11px; + font-size: 12px; color: #515151; padding-left: 19px; - font-weight: bold; /*+text-shadow:0px 1px #FFFFFF;*/ -moz-text-shadow: 0px 1px #FFFFFF; -webkit-text-shadow: 0px 1px #FFFFFF; @@ -3375,7 +3379,7 @@ div.toolbar div.filters select { #breadcrumbs .home { height: 21px; float: left; - font-size: 11px; + font-size: 13px; color: #FFFFFF; padding: 9px 5px 0px 8px; cursor: pointer; @@ -3440,6 +3444,7 @@ div.toolbar div.filters select { top: 0px; margin-left: -10px; text-indent: 13px; + font-size: 13px; } #breadcrumbs div.active-project { @@ -3682,6 +3687,13 @@ Dialogs*/ margin: 18px 0 0; } +.ui-dialog .ui-widget-content .nothing-to-select .specify-ip { + margin-top: 28px; + padding-top: 21px; + font-size: 12px; + border-top: 1px solid #DFDFDF; +} + .ui-dialog-buttonset { width: 285px; margin: 0; @@ -4461,6 +4473,9 @@ Dialogs*/ } .dashboard.admin .dashboard-container.sub.alerts ul li { + border: 1px solid #FF7070; + border-left-width: 20px; + background: #FFEFEF; } .dashboard.admin .dashboard-container.sub.alerts ul li span.title { @@ -9260,8 +9275,7 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal .project-switcher label { top: 29px; color: #FFFFFF; - font-size: 12px; - font-weight: bold; + font-size: 13px; float: left; margin-right: 7px; margin-top: 5px; @@ -9270,7 +9284,7 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal .project-switcher select { width: 70%; float: left; - margin-top: -1px; + margin-top: 0px; border: 1px solid #393939; /*+text-shadow:0px -1px 1px #373737;*/ -moz-text-shadow: 0px -1px 1px #373737; @@ -9278,7 +9292,7 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal -o-text-shadow: 0px -1px 1px #373737; text-shadow: 0px -1px 1px #373737; background: #515151; - font-size: 15px; + font-size: 13px; font-weight: 100; color: #FFFFFF; } @@ -11912,10 +11926,10 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it .region-switcher .title { display: inline-block; float: right; - padding: 10px 9px 0 34px; + padding: 9px 9px 0 34px; color: #FFFFFF; - font-size: 12px; - font-weight: bold; + font-size: 13px; + font-weight: 100; max-width: 285px; overflow: hidden; white-space: nowrap; diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index bf48417cd47..11dbeb5179c 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -933,6 +933,7 @@ dictionary = { 'label.projects': '', 'label.project.view': '', 'label.protocol': '', +'label.provider': '', 'label.providers': '', 'label.provider': '', 'label.public': '', @@ -1251,7 +1252,7 @@ dictionary = { 'label.network.addVM': '', 'label.set.default.NIC': '', 'label.Xenserver.Tools.Version61plus': '', -'label.dynamically.scalabel': '', +'label.dynamically.scalable': '', 'label.instance.scaled.up': '', 'label.tag.value': '', 'label.tag.key': '', diff --git a/ui/images/infrastructure-icons.png b/ui/images/infrastructure-icons.png index a589fc42dc2..188afb13159 100644 Binary files a/ui/images/infrastructure-icons.png and b/ui/images/infrastructure-icons.png differ diff --git a/ui/images/sprites.png b/ui/images/sprites.png index 84d354606cc..ca03abcb72e 100644 Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ diff --git a/ui/index.jsp b/ui/index.jsp index c638f93789a..4daa9eb096d 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -265,7 +265,17 @@

-

+

+

+
+ + +
+
+

diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index e9296a97eef..3ee9af1b9e4 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -381,7 +381,7 @@ step6ContainerType = 'nothing-to-select'; $networkStep.find("#from_instance_page_1").hide(); $networkStep.find("#from_instance_page_2").hide(); - $networkStep.find("#from_vpc_tier").text("tier " + args.context.networks[0].name); + $networkStep.find("#from_vpc_tier").prepend("tier " + _s(args.context.networks[0].name)); $networkStep.find("#from_vpc_tier").show(); } else { //from Instance page if (selectedZoneObj.securitygroupsenabled != true) { // Advanced SG-disabled zone @@ -817,10 +817,12 @@ }); } } else if (step6ContainerType == 'nothing-to-select') { - if (args.context.networks != null) { //from VPC tier - $.extend(deployVmData, { - networkids : args.context.networks[0].id - }); + if ("vpc" in args.context) { //from VPC tier + deployVmData["iptonetworklist[0].networkid"] = args.context.networks[0].id; + if (args.data["vpc-specify-ip"] != undefined && args.data["vpc-specify-ip"].length > 0) { + deployVmData["iptonetworklist[0].ip"] = args.data["vpc-specify-ip"]; + } + $.extend(deployVmData, { domainid : args.context.vpc[0].domainid }); diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 26915868749..1de36469297 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1872,7 +1872,7 @@ secondaryStorage: { fields: { provider: { - label: 'Provider', + label: 'label.provider', select: function(args) { var storageproviders = []; storageproviders.push({ id: '', description: ''});