diff --git a/api/src/com/cloud/api/response/SecurityGroupResponse.java b/api/src/com/cloud/api/response/SecurityGroupResponse.java index e9931167499..c4a9b0f520f 100644 --- a/api/src/com/cloud/api/response/SecurityGroupResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupResponse.java @@ -16,7 +16,10 @@ // under the License. package com.cloud.api.response; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.Entity; @@ -27,9 +30,10 @@ import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @Entity(value = SecurityGroup.class) -public class SecurityGroupResponse extends BaseResponse implements ControlledEntityResponse{ +public class SecurityGroupResponse extends BaseResponse implements ControlledViewEntityResponse{ + @SerializedName(ApiConstants.ID) @Param(description="the ID of the security group") - private IdentityProxy id = new IdentityProxy("security_group"); + private String id; @SerializedName(ApiConstants.NAME) @Param(description="the name of the security group") private String name; @@ -41,34 +45,46 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt private String accountName; @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the group") - private IdentityProxy projectId = new IdentityProxy("projects"); + private String projectId; @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the group") private String projectName; @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID of the security group") - private IdentityProxy domainId = new IdentityProxy("domain"); + private String domainId; @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the security group") private String domainName; @SerializedName("ingressrule") @Param(description="the list of ingress rules associated with the security group", responseObject = SecurityGroupRuleResponse.class) - private List ingressRules; + private Set ingressRules; @SerializedName("egressrule") @Param(description="the list of egress rules associated with the security group", responseObject = SecurityGroupRuleResponse.class) - private List egressRules; + private Set egressRules; @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class) - private List tags; + private Set tags; - public void setId(Long id) { - this.id.setValue(id); + public SecurityGroupResponse(){ + this.ingressRules = new HashSet(); + this.egressRules = new HashSet(); + this.tags = new HashSet(); } - public Long getId() { - return id.getValue(); + @Override + public String getObjectUuid() { + return this.getId(); } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { this.name = name; } @@ -81,25 +97,29 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt this.accountName = accountName; } - public void setDomainId(Long domainId) { - this.domainId.setValue(domainId); + @Override + public void setDomainId(String domainId) { + this.domainId = domainId; } public void setDomainName(String domainName) { this.domainName = domainName; } - public void setSecurityGroupIngressRules(List securityGroupRules) { + public void setSecurityGroupIngressRules(Set securityGroupRules) { this.ingressRules = securityGroupRules; } - public void setSecurityGroupEgressRules(List securityGroupRules) { + public void addSecurityGroupIngressRule(SecurityGroupRuleResponse rule){ + this.ingressRules.add(rule); + } + + public void setSecurityGroupEgressRules(Set securityGroupRules) { this.egressRules = securityGroupRules; } - @Override - public Long getObjectId() { - return getId(); + public void addSecurityGroupEgressRule(SecurityGroupRuleResponse rule){ + this.egressRules.add(rule); } @Override @@ -128,8 +148,8 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt } @Override - public void setProjectId(Long projectId) { - this.projectId.setValue(projectId); + public void setProjectId(String projectId) { + this.projectId = projectId; } @Override @@ -137,7 +157,11 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt this.projectName = projectName; } - public void setTags(List tags) { + public void setTags(Set tags) { this.tags = tags; } + + public void addTag(ResourceTagResponse tag){ + this.tags.add(tag); + } } diff --git a/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java b/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java index abc3dea200d..8ef39b0260f 100644 --- a/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java @@ -23,7 +23,7 @@ import com.google.gson.annotations.SerializedName; public class SecurityGroupRuleResponse extends BaseResponse { @SerializedName("ruleid") @Param(description="the id of the security group rule") - private IdentityProxy ruleId = new IdentityProxy("security_group_rule"); + private String ruleId; @SerializedName("protocol") @Param(description="the protocol of the security group rule") private String protocol; @@ -49,12 +49,12 @@ public class SecurityGroupRuleResponse extends BaseResponse { @SerializedName(ApiConstants.CIDR) @Param(description="the CIDR notation for the base IP address of the security group rule") private String cidr; - public Long getRuleId() { - return ruleId.getValue(); + public String getRuleId() { + return ruleId; } - public void setRuleId(Long ruleId) { - this.ruleId.setValue(ruleId); + public void setRuleId(String ruleId) { + this.ruleId = ruleId; } public String getProtocol() { @@ -120,4 +120,31 @@ public class SecurityGroupRuleResponse extends BaseResponse { public void setCidr(String cidr) { this.cidr = cidr; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + String oid = this.getRuleId(); + result = prime * result + ((oid== null) ? 0 : oid.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SecurityGroupRuleResponse other = (SecurityGroupRuleResponse) obj; + String oid = this.getRuleId(); + if (oid == null) { + if (other.getRuleId() != null) + return false; + } else if (!oid.equals(other.getRuleId())) + return false; + return true; + } } diff --git a/api/src/com/cloud/api/view/vo/SecurityGroupJoinVO.java b/api/src/com/cloud/api/view/vo/SecurityGroupJoinVO.java new file mode 100644 index 00000000000..c679d3d99b2 --- /dev/null +++ b/api/src/com/cloud/api/view/vo/SecurityGroupJoinVO.java @@ -0,0 +1,466 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.api.view.vo; + +import java.net.URI; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; + +import com.cloud.network.Network.GuestType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.utils.db.GenericDao; +import com.cloud.vm.VirtualMachine.State; + +@Entity +@Table(name="security_group_view") +public class SecurityGroupJoinVO implements ControlledViewEntity { + + @Column(name="id", updatable=false, nullable = false) + private long id; + + @Column(name="name") + private String name; + + @Column(name = "description") + private String description; + + @Column(name = "uuid") + private String uuid; + + @Column(name="account_id") + private long accountId; + + @Column(name="account_uuid") + private String accountUuid; + + @Column(name="account_name") + private String accountName = null; + + @Column(name="account_type") + private short accountType; + + @Column(name="domain_id") + private long domainId; + + @Column(name="domain_uuid") + private String domainUuid; + + @Column(name="domain_name") + private String domainName = null; + + @Column(name="domain_path") + private String domainPath = null; + + @Column(name="project_id") + private long projectId; + + @Column(name="project_uuid") + private String projectUuid; + + @Column(name="project_name") + private String projectName; + + @Column(name="job_id") + private long jobId; + + @Column(name="job_uuid") + private String jobUuid; + + @Column(name="job_status") + private int jobStatus; + + @Column(name = "rule_id") + private Long ruleId; + + @Column(name = "rule_uuid") + private String ruleUuid; + + @Column(name = "rule_start_port") + private int ruleStartPort; + + @Column(name = "rule_end_port") + private int ruleEndPort; + + @Column(name = "rule_protocol") + private String ruleProtocol; + + @Column(name = "rule_type") + private String ruleType; + + @Column(name = "rule_allowed_network_id") + private Long ruleAllowedNetworkId = null; + + @Column(name = "rule_allowed_ip_cidr") + private String ruleAllowedSourceIpCidr = null; + + @Column(name="tag_id") + private long tagId; + + @Column(name="tag_uuid") + private String tagUuid; + + @Column(name="tag_key") + private String tagKey; + + @Column(name="tag_value") + private String tagValue; + + @Column(name="tag_domain_id") + private long tagDomainId; + + @Column(name="tag_account_id") + private long tagAccountId; + + @Column(name="tag_resource_id") + private long tagResourceId; + + @Column(name="tag_resource_uuid") + private String tagResourceUuid; + + @Column(name="tag_resource_type") + @Enumerated(value=EnumType.STRING) + private TaggedResourceType tagResourceType; + + @Column(name="tag_customer") + private String tagCustomer; + + public SecurityGroupJoinVO() { + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public short getAccountType() { + return accountType; + } + + public void setAccountType(short accountType) { + this.accountType = accountType; + } + + public long getDomainId() { + return domainId; + } + + public void setDomainId(long domainId) { + this.domainId = domainId; + } + + @Override + public String getDomainUuid() { + return domainUuid; + } + + public void setDomainUuid(String domainUuid) { + this.domainUuid = domainUuid; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public String getDomainPath() { + return domainPath; + } + + public void setDomainPath(String domainPath) { + this.domainPath = domainPath; + } + + public long getProjectId() { + return projectId; + } + + public void setProjectId(long projectId) { + this.projectId = projectId; + } + + public String getProjectUuid() { + return projectUuid; + } + + public void setProjectUuid(String projectUuid) { + this.projectUuid = projectUuid; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public long getJobId() { + return jobId; + } + + public void setJobId(long jobId) { + this.jobId = jobId; + } + + public String getJobUuid() { + return jobUuid; + } + + public void setJobUuid(String jobUuid) { + this.jobUuid = jobUuid; + } + + public int getJobStatus() { + return jobStatus; + } + + public void setJobStatus(int jobStatus) { + this.jobStatus = jobStatus; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public String getRuleUuid() { + return ruleUuid; + } + + public void setRuleUuid(String ruleUuid) { + this.ruleUuid = ruleUuid; + } + + public int getRuleStartPort() { + return ruleStartPort; + } + + public void setRuleStartPort(int ruleStartPort) { + this.ruleStartPort = ruleStartPort; + } + + public int getRuleEndPort() { + return ruleEndPort; + } + + public void setRuleEndPort(int ruleEndPort) { + this.ruleEndPort = ruleEndPort; + } + + public String getRuleProtocol() { + return ruleProtocol; + } + + public void setRuleProtocol(String ruleProtocol) { + this.ruleProtocol = ruleProtocol; + } + + public SecurityRuleType getRuleType() { + if ("ingress".equalsIgnoreCase(ruleType)) { + return SecurityRuleType.IngressRule; + } else { + return SecurityRuleType.EgressRule; + } + } + + public void setRuleType(String ruleType) { + this.ruleType = ruleType; + } + + public Long getRuleAllowedNetworkId() { + return ruleAllowedNetworkId; + } + + public void setRuleAllowedNetworkId(Long ruleAllowedNetworkId) { + this.ruleAllowedNetworkId = ruleAllowedNetworkId; + } + + public String getRuleAllowedSourceIpCidr() { + return ruleAllowedSourceIpCidr; + } + + public void setRuleAllowedSourceIpCidr(String ruleAllowedSourceIpCidr) { + this.ruleAllowedSourceIpCidr = ruleAllowedSourceIpCidr; + } + + public long getTagId() { + return tagId; + } + + public void setTagId(long tagId) { + this.tagId = tagId; + } + + public String getTagUuid() { + return tagUuid; + } + + public void setTagUuid(String tagUuid) { + this.tagUuid = tagUuid; + } + + public String getTagKey() { + return tagKey; + } + + public void setTagKey(String tagKey) { + this.tagKey = tagKey; + } + + public String getTagValue() { + return tagValue; + } + + public void setTagValue(String tagValue) { + this.tagValue = tagValue; + } + + public long getTagDomainId() { + return tagDomainId; + } + + public void setTagDomainId(long tagDomainId) { + this.tagDomainId = tagDomainId; + } + + public long getTagAccountId() { + return tagAccountId; + } + + public void setTagAccountId(long tagAccountId) { + this.tagAccountId = tagAccountId; + } + + public long getTagResourceId() { + return tagResourceId; + } + + public void setTagResourceId(long tagResourceId) { + this.tagResourceId = tagResourceId; + } + + public String getTagResourceUuid() { + return tagResourceUuid; + } + + public void setTagResourceUuid(String tagResourceUuid) { + this.tagResourceUuid = tagResourceUuid; + } + + public TaggedResourceType getTagResourceType() { + return tagResourceType; + } + + public void setTagResourceType(TaggedResourceType tagResourceType) { + this.tagResourceType = tagResourceType; + } + + public String getTagCustomer() { + return tagCustomer; + } + + public void setTagCustomer(String tagCustomer) { + this.tagCustomer = tagCustomer; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SecurityGroupJoinVO other = (SecurityGroupJoinVO) obj; + if (id != other.id) + return false; + return true; + } +} diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/com/cloud/network/security/SecurityGroupService.java index 51d26829667..640b9accd8a 100644 --- a/api/src/com/cloud/network/security/SecurityGroupService.java +++ b/api/src/com/cloud/network/security/SecurityGroupService.java @@ -24,6 +24,8 @@ import org.apache.cloudstack.api.user.securitygroup.command.CreateSecurityGroupC import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceInUseException; +import com.cloud.api.view.vo.SecurityGroupJoinVO; +import com.cloud.utils.Pair; public interface SecurityGroupService { /** @@ -42,7 +44,7 @@ public interface SecurityGroupService { * The search terms are specified in the search criteria. * @return the list of security groups and associated ingress rules */ - public List searchForSecurityGroupRules(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException; + public Pair, Integer> searchForSecurityGroupRules(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException; public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd); diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index aeafe6a665c..96df77e53a0 100755 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -153,6 +153,7 @@ import com.cloud.user.UserAccount; import com.cloud.uservm.UserVm; import com.cloud.vm.InstanceGroup; import com.cloud.api.view.vo.DomainRouterJoinVO; +import com.cloud.api.view.vo.SecurityGroupJoinVO; import com.cloud.api.view.vo.UserVmJoinVO; import com.cloud.vm.VirtualMachine; @@ -243,7 +244,10 @@ public interface ResponseGenerator { List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly); - ListResponse createSecurityGroupResponses(List networkGroups); + //ListResponse createSecurityGroupResponses(List networkGroups); + + List createSecurityGroupResponses(List securityGroups); + SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List SecurityRules); diff --git a/api/src/org/apache/cloudstack/api/user/securitygroup/command/ListSecurityGroupsCmd.java b/api/src/org/apache/cloudstack/api/user/securitygroup/command/ListSecurityGroupsCmd.java index 7b1be825f93..c2df28bf7dc 100644 --- a/api/src/org/apache/cloudstack/api/user/securitygroup/command/ListSecurityGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/user/securitygroup/command/ListSecurityGroupsCmd.java @@ -25,11 +25,14 @@ import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; import org.apache.cloudstack.api.IdentityMapper; import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; +import com.cloud.api.response.DomainRouterResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.api.view.vo.DomainRouterJoinVO; +import com.cloud.api.view.vo.SecurityGroupJoinVO; import com.cloud.async.AsyncJob; import com.cloud.network.security.SecurityGroupRules; - +import com.cloud.utils.Pair; @Implementation(description="Lists security groups", responseObject=SecurityGroupResponse.class) public class ListSecurityGroupsCmd extends BaseListTaggedResourcesCmd { @@ -78,11 +81,12 @@ public class ListSecurityGroupsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List securityGroups = _securityGroupService.searchForSecurityGroupRules(this); + Pair, Integer> result = _securityGroupService.searchForSecurityGroupRules(this); + ListResponse response = new ListResponse(); + List routerResponses = _responseGenerator.createSecurityGroupResponses(result.first()); + response.setResponses(routerResponses, result.second()); - ListResponse response = _responseGenerator.createSecurityGroupResponses(securityGroups); response.setResponseName(getCommandName()); - this.setResponseObject(response); } @Override diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index a98c5d3557a..b48cbe6a264 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -24,8 +24,10 @@ import java.util.Set; import org.apache.cloudstack.api.ApiConstants.VMDetails; import com.cloud.api.response.DomainRouterResponse; +import com.cloud.api.response.SecurityGroupResponse; import com.cloud.api.response.UserVmResponse; import com.cloud.api.view.vo.DomainRouterJoinVO; +import com.cloud.api.view.vo.SecurityGroupJoinVO; import com.cloud.api.view.vo.UserVmJoinVO; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -94,6 +96,7 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.security.dao.SecurityGroupJoinDao; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -196,6 +199,7 @@ public class ApiDBUtils { private static IPAddressDao _ipAddressDao; private static LoadBalancerDao _loadBalancerDao; private static SecurityGroupDao _securityGroupDao; + private static SecurityGroupJoinDao _securityGroupJoinDao; private static NetworkRuleConfigDao _networkRuleConfigDao; private static HostPodDao _podDao; private static ServiceOfferingDao _serviceOfferingDao; @@ -283,6 +287,7 @@ public class ApiDBUtils { _volumeHostDao = locator.getDao(VolumeHostDao.class); _zoneDao = locator.getDao(DataCenterDao.class); _securityGroupDao = locator.getDao(SecurityGroupDao.class); + _securityGroupJoinDao = locator.getDao(SecurityGroupJoinDao.class); _networkOfferingDao = locator.getDao(NetworkOfferingDao.class); _networkDao = locator.getDao(NetworkDao.class); _configDao = locator.getDao(ConfigurationDao.class); @@ -925,4 +930,20 @@ public class ApiDBUtils { public static List newUserVmView(UserVm... userVms){ return _userVmJoinDao.newUserVmView(userVms); } + + public static SecurityGroupResponse newSecurityGroupResponse(SecurityGroupJoinVO vsg, Account caller) { + return _securityGroupJoinDao.newSecurityGroupResponse(vsg, caller); + } + + public static SecurityGroupResponse fillSecurityGroupDetails(SecurityGroupResponse vsgData, SecurityGroupJoinVO sg){ + return _securityGroupJoinDao.setSecurityGroupResponse(vsgData, sg); + } + + public static List newSecurityGroupView(SecurityGroup sg){ + return _securityGroupJoinDao.newSecurityGroupView(sg); + } + + public static List findSecurityGroupViewById(Long sgId){ + return _securityGroupJoinDao.searchByIds(sgId); + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 84950d3b155..ca39e8da189 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -118,6 +118,7 @@ import com.cloud.api.response.VpnUsersResponse; import com.cloud.api.response.ZoneResponse; import com.cloud.api.view.vo.DomainRouterJoinVO; import com.cloud.api.view.vo.ControlledViewEntity; +import com.cloud.api.view.vo.SecurityGroupJoinVO; import com.cloud.api.view.vo.UserVmJoinVO; import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; @@ -2029,91 +2030,31 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public ListResponse createSecurityGroupResponses( - List networkGroups) { - List groupResultObjs = SecurityGroupResultObject - .transposeNetworkGroups(networkGroups); + public List createSecurityGroupResponses(List securityGroups) { + Account caller = UserContext.current().getCaller(); + Hashtable vrDataList = new Hashtable(); + // Initialise the vrdatalist with the input data + for (SecurityGroupJoinVO vr : securityGroups) { + SecurityGroupResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ) { + // first time encountering this sg + vrData = ApiDBUtils.newSecurityGroupResponse(vr, caller); - ListResponse response = new ListResponse(); - List netGrpResponses = new ArrayList(); - for (SecurityGroupResultObject networkGroup : groupResultObjs) { - SecurityGroupResponse netGrpResponse = new SecurityGroupResponse(); - netGrpResponse.setId(networkGroup.getId()); - netGrpResponse.setName(networkGroup.getName()); - netGrpResponse.setDescription(networkGroup.getDescription()); - - populateOwner(netGrpResponse, networkGroup); - - List securityGroupRules = networkGroup - .getSecurityGroupRules(); - if ((securityGroupRules != null) && !securityGroupRules.isEmpty()) { - List ingressRulesResponse = new ArrayList(); - List egressRulesResponse = new ArrayList(); - for (SecurityGroupRuleResultObject securityGroupRule : securityGroupRules) { - SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); - ruleData.setRuleId(securityGroupRule.getId()); - ruleData.setProtocol(securityGroupRule.getProtocol()); - - if ("icmp".equalsIgnoreCase(securityGroupRule.getProtocol())) { - ruleData.setIcmpType(securityGroupRule.getStartPort()); - ruleData.setIcmpCode(securityGroupRule.getEndPort()); - } else { - ruleData.setStartPort(securityGroupRule.getStartPort()); - ruleData.setEndPort(securityGroupRule.getEndPort()); - } - - if (securityGroupRule.getAllowedSecurityGroup() != null) { - ruleData.setSecurityGroupName(securityGroupRule - .getAllowedSecurityGroup()); - ruleData.setAccountName(securityGroupRule - .getAllowedSecGroupAcct()); - } else { - ruleData.setCidr(securityGroupRule - .getAllowedSourceIpCidr()); - } - - if (securityGroupRule.getRuleType() == SecurityRuleType.IngressRule) { - ruleData.setObjectName("ingressrule"); - ingressRulesResponse.add(ruleData); - } else { - ruleData.setObjectName("egressrule"); - egressRulesResponse.add(ruleData); - } - } - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, networkGroup.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - netGrpResponse.setTags(tagResponses); - - netGrpResponse - .setSecurityGroupIngressRules(ingressRulesResponse); - netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); + } else { + // update rules for 1 to many mapping fields + vrData = ApiDBUtils.fillSecurityGroupDetails(vrData, vr); } - netGrpResponse.setObjectName("securitygroup"); - netGrpResponses.add(netGrpResponse); + vrDataList.put(vr.getId(), vrData); } - - response.setResponses(netGrpResponses); - return response; + return new ArrayList(vrDataList.values()); } @Override public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) { - SecurityGroupResponse response = new SecurityGroupResponse(); - - populateOwner(response, group); - - response.setDescription(group.getDescription()); - response.setId(group.getId()); - response.setName(group.getName()); - - response.setObjectName("securitygroup"); - return response; - + List viewSgs = ApiDBUtils.newSecurityGroupView(group); + List listSgs = createSecurityGroupResponses(viewSgs); + assert listSgs != null && listSgs.size() == 1 : "There should be one security group returned"; + return listSgs.get(0); } @Override @@ -2471,27 +2412,27 @@ public class ApiResponseHelper implements ResponseGenerator { Map allowedSecuriytGroupAccounts = new HashMap(); if ((securityRules != null) && !securityRules.isEmpty()) { - SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(securityRules.get(0).getSecurityGroupId()); - response.setId(securityGroup.getId()); + SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0); + response.setId(securityGroup.getUuid()); response.setName(securityGroup.getName()); response.setDescription(securityGroup.getDescription()); Account account = securiytGroupAccounts.get(securityGroup.getAccountId()); - if (account == null) { - account = ApiDBUtils.findAccountById(securityGroup.getAccountId()); - securiytGroupAccounts.put(securityGroup.getAccountId(), account); + if (securityGroup.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { + response.setProjectId(securityGroup.getProjectUuid()); + response.setProjectName(securityGroup.getProjectName()); + } else { + response.setAccountName(securityGroup.getAccountName()); } - populateAccount(response, account.getId()); - populateDomain(response, account.getDomainId()); + response.setDomainId(securityGroup.getDomainUuid()); + response.setDomainName(securityGroup.getDomainName()); - List egressResponses = new ArrayList(); - List ingressResponses = new ArrayList(); for (SecurityRule securityRule : securityRules) { SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse(); - securityGroupData.setRuleId(securityRule.getId()); + securityGroupData.setRuleId(securityRule.getUuid()); securityGroupData.setProtocol(securityRule.getProtocol()); if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) { securityGroupData.setIcmpType(securityRule.getStartPort()); @@ -2503,35 +2444,24 @@ public class ApiResponseHelper implements ResponseGenerator { Long allowedSecurityGroupId = securityRule.getAllowedNetworkId(); if (allowedSecurityGroupId != null) { - SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); - if (allowedSecurityGroup == null) { - allowedSecurityGroup = ApiDBUtils.findSecurityGroupById(allowedSecurityGroupId); - allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); + List sgs = ApiDBUtils.findSecurityGroupViewById(allowedSecurityGroupId); + if (sgs != null && sgs.size() > 0) { + SecurityGroupJoinVO sg = sgs.get(0); + securityGroupData.setSecurityGroupName(sg.getName()); + securityGroupData.setAccountName(sg.getAccountName()); } - - securityGroupData.setSecurityGroupName(allowedSecurityGroup.getName()); - - Account allowedAccount = allowedSecuriytGroupAccounts.get(allowedSecurityGroup.getAccountId()); - if (allowedAccount == null) { - allowedAccount = ApiDBUtils.findAccountById(allowedSecurityGroup.getAccountId()); - allowedSecuriytGroupAccounts.put(allowedAccount.getId(), allowedAccount); - } - - securityGroupData.setAccountName(allowedAccount.getAccountName()); } else { securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr()); } if (securityRule.getRuleType() == SecurityRuleType.IngressRule) { securityGroupData.setObjectName("ingressrule"); - ingressResponses.add(securityGroupData); + response.addSecurityGroupIngressRule(securityGroupData); } else { securityGroupData.setObjectName("egressrule"); - egressResponses.add(securityGroupData); + response.addSecurityGroupEgressRule(securityGroupData); } } - response.setSecurityGroupIngressRules(ingressResponses); - response.setSecurityGroupEgressRules(egressResponses); response.setObjectName("securitygroup"); } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index d75c8e169ad..bacec720bd4 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -79,6 +79,7 @@ import org.apache.http.protocol.ResponseServer; import org.apache.log4j.Logger; import org.apache.cloudstack.api.admin.router.command.ListRoutersCmd; +import org.apache.cloudstack.api.user.securitygroup.command.ListSecurityGroupsCmd; import org.apache.cloudstack.api.user.vm.command.ListVMsCmd; import com.cloud.acl.ControlledEntity; import com.cloud.api.response.ApiResponseSerializer; @@ -437,7 +438,8 @@ public class ApiServer implements HttpRequestHandler { // if the command is of the listXXXCommand, we will need to also return the // the job id and status if possible - if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd)) { + if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd) + && !(cmdObj instanceof ListSecurityGroupsCmd)) { buildAsyncListResponse((BaseListCmd) cmdObj, caller); } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index ec543ed20fc..1e292c45510 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -117,6 +117,7 @@ import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; import com.cloud.network.security.dao.SecurityGroupDaoImpl; +import com.cloud.network.security.dao.SecurityGroupJoinDaoImpl; import com.cloud.network.security.dao.SecurityGroupRuleDaoImpl; import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; @@ -220,6 +221,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("UserVmDao", UserVmDaoImpl.class); addDao("UserVmJoinDao", UserVmJoinDaoImpl.class); addDao("DomainRouterJoinDao", DomainRouterJoinDaoImpl.class); + addDao("SecurityGroupJoinDao", SecurityGroupJoinDaoImpl.class); ComponentInfo> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class); info.addParameter("cache.size", "50"); info.addParameter("cache.time.to.live", "600"); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index be8635c63e1..8421a80cb04 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -46,6 +46,8 @@ import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.manager.Commands; import org.apache.cloudstack.api.user.securitygroup.command.RevokeSecurityGroupEgressCmd; +import com.cloud.api.view.vo.SecurityGroupJoinVO; +import com.cloud.api.view.vo.UserVmJoinVO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.dao.DomainDao; @@ -64,6 +66,7 @@ import com.cloud.network.NetworkManager; import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.network.security.SecurityRule.SecurityRuleType; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.security.dao.SecurityGroupJoinDao; import com.cloud.network.security.dao.SecurityGroupRuleDao; import com.cloud.network.security.dao.SecurityGroupRulesDao; import com.cloud.network.security.dao.SecurityGroupVMMapDao; @@ -95,6 +98,7 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.net.NetUtils; @@ -119,6 +123,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG @Inject SecurityGroupDao _securityGroupDao; @Inject + SecurityGroupJoinDao _securityGroupJoinDao; + @Inject SecurityGroupRuleDao _securityGroupRuleDao; @Inject SecurityGroupVMMapDao _securityGroupVMMapDao; @@ -1087,7 +1093,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG } @Override - public List searchForSecurityGroupRules(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException { + public Pair, Integer> searchForSecurityGroupRules(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException { Account caller = UserContext.current().getCaller(); Long instanceId = cmd.getVirtualMachineId(); String securityGroup = cmd.getSecurityGroupName(); @@ -1102,38 +1108,33 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG throw new InvalidParameterValueException("Unable to list network groups for virtual machine instance " + instanceId + "; instance not found."); } _accountMgr.checkAccess(caller, null, true, userVM); - return listSecurityGroupRulesByVM(instanceId.longValue()); + return listSecurityGroupRulesByVM(instanceId.longValue(), cmd.getStartIndex(), cmd.getPageSizeVal()); } - List securityRulesList = new ArrayList(); - Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - - Filter searchFilter = new Filter(SecurityGroupVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchBuilder sb = _securityGroupDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + Filter searchFilter = new Filter(SecurityGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _securityGroupJoinDao.createSearchBuilder(); + sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids + _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); for (int count=0; count < tags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); + sb.or().op("key" + String.valueOf(count), sb.entity().getTagKey(), SearchCriteria.Op.EQ); + sb.and("value" + String.valueOf(count), sb.entity().getTagValue(), SearchCriteria.Op.EQ); + sb.cp(); } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + SearchCriteria sc = sb.create(); + _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); if (id != null) { sc.setParameters("id", id); @@ -1141,12 +1142,11 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.SecurityGroup.toString()); for (String key : tags.keySet()) { - sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); - sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); - count++; - } + sc.setParameters("key" + String.valueOf(count), key); + sc.setParameters("value" + String.valueOf(count), tags.get(key)); + count++; + } } if (securityGroup != null) { @@ -1154,33 +1154,46 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG } if (keyword != null) { - SearchCriteria ssc = _securityGroupRulesDao.createSearchCriteria(); + SearchCriteria ssc = _securityGroupJoinDao.createSearchCriteria(); ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%"); sc.addAnd("name", SearchCriteria.Op.SC, ssc); } - List securityGroups = _securityGroupDao.search(sc, searchFilter); - for (SecurityGroupVO group : securityGroups) { - securityRulesList.addAll(_securityGroupRulesDao.listSecurityRulesByGroupId(group.getId())); + // search security group together with rules + Pair, Integer> uniqueSgPair = _securityGroupJoinDao.searchAndCount(sc, searchFilter); + Integer count = uniqueSgPair.second(); + if ( count.intValue() == 0 ){ + // handle empty result cases + return uniqueSgPair; } - return securityRulesList; + List uniqueSgs = uniqueSgPair.first(); + Long[] sgIds = new Long[uniqueSgs.size()]; + int i = 0; + for (SecurityGroupJoinVO v : uniqueSgs ){ + sgIds[i++] = v.getId(); + } + List sgs = _securityGroupJoinDao.searchByIds(sgIds); + return new Pair, Integer>(sgs, count); } - private List listSecurityGroupRulesByVM(long vmId) { - List results = new ArrayList(); - List networkGroupMappings = _securityGroupVMMapDao.listByInstanceId(vmId); - if (networkGroupMappings != null) { - for (SecurityGroupVMMapVO networkGroupMapping : networkGroupMappings) { - SecurityGroupVO group = _securityGroupDao.findById(networkGroupMapping.getSecurityGroupId()); - List rules = _securityGroupRulesDao.listSecurityGroupRules(group.getAccountId(), networkGroupMapping.getGroupName()); - if (rules != null) { - results.addAll(rules); - } - } + private Pair, Integer> listSecurityGroupRulesByVM(long vmId, long pageInd, long pageSize) { + Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize); + Pair, Integer> sgVmMappingPair = _securityGroupVMMapDao.listByInstanceId(vmId, sf); + Integer count = sgVmMappingPair.second(); + if (count.intValue() == 0) { + // handle empty result cases + return new Pair, Integer>(new ArrayList(), count); } - return results; + List sgVmMappings = sgVmMappingPair.first(); + Long[] sgIds = new Long[sgVmMappings.size()]; + int i = 0; + for (SecurityGroupVMMapVO sgVm : sgVmMappings) { + sgIds[i++] = sgVm.getSecurityGroupId(); + } + List sgs = _securityGroupJoinDao.searchByIds(sgIds); + return new Pair, Integer>(sgs, count); } @Override diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupJoinDao.java b/server/src/com/cloud/network/security/dao/SecurityGroupJoinDao.java new file mode 100644 index 00000000000..cc79cdaff14 --- /dev/null +++ b/server/src/com/cloud/network/security/dao/SecurityGroupJoinDao.java @@ -0,0 +1,37 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.security.dao; + +import java.util.List; + +import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.api.view.vo.SecurityGroupJoinVO; +import com.cloud.network.security.SecurityGroup; +import com.cloud.user.Account; +import com.cloud.utils.db.GenericDao; + +public interface SecurityGroupJoinDao extends GenericDao { + + SecurityGroupResponse newSecurityGroupResponse(SecurityGroupJoinVO vsg, Account caller); + + SecurityGroupResponse setSecurityGroupResponse(SecurityGroupResponse vsgData, SecurityGroupJoinVO vsg); + + List newSecurityGroupView(SecurityGroup sg); + + List searchByIds(Long... ids); +} + diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupJoinDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupJoinDaoImpl.java new file mode 100644 index 00000000000..2237112150c --- /dev/null +++ b/server/src/com/cloud/network/security/dao/SecurityGroupJoinDaoImpl.java @@ -0,0 +1,244 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.security.dao; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.response.DomainRouterResponse; +import com.cloud.api.response.NicResponse; +import com.cloud.api.response.ResourceTagResponse; +import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.api.response.SecurityGroupRuleResponse; +import com.cloud.api.response.UserVmResponse; +import com.cloud.api.view.vo.DomainRouterJoinVO; +import com.cloud.api.view.vo.SecurityGroupJoinVO; +import com.cloud.dc.DataCenter; +import com.cloud.network.Network; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.security.SecurityGroup; +import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.offering.ServiceOffering; +import com.cloud.user.Account; +import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Attribute; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicProfile; + +@Local(value={SecurityGroupJoinDao.class}) +public class SecurityGroupJoinDaoImpl extends GenericDaoBase implements SecurityGroupJoinDao { + public static final Logger s_logger = Logger.getLogger(SecurityGroupJoinDaoImpl.class); + + private SearchBuilder sgSearch; + + private SearchBuilder sgIdSearch; + + protected SecurityGroupJoinDaoImpl() { + + sgSearch = createSearchBuilder(); + sgSearch.and("idIN", sgSearch.entity().getId(), SearchCriteria.Op.IN); + sgSearch.done(); + + sgIdSearch = createSearchBuilder(); + sgIdSearch.and("id", sgIdSearch.entity().getId(), SearchCriteria.Op.EQ); + sgIdSearch.done(); + + this._count = "select count(distinct id) from security_group_view WHERE "; + } + + @Override + public SecurityGroupResponse newSecurityGroupResponse(SecurityGroupJoinVO vsg, Account caller) { + SecurityGroupResponse sgResponse = new SecurityGroupResponse(); + sgResponse.setId(vsg.getUuid()); + sgResponse.setName(vsg.getName()); + sgResponse.setDescription(vsg.getDescription()); + + ApiResponseHelper.populateOwner(sgResponse, vsg); + + Long rule_id = vsg.getRuleId(); + if (rule_id != null && rule_id.longValue() > 0) { + SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); + ruleData.setRuleId(vsg.getRuleUuid()); + ruleData.setProtocol(vsg.getRuleProtocol()); + + if ("icmp".equalsIgnoreCase(vsg.getRuleProtocol())) { + ruleData.setIcmpType(vsg.getRuleStartPort()); + ruleData.setIcmpCode(vsg.getRuleEndPort()); + } else { + ruleData.setStartPort(vsg.getRuleStartPort()); + ruleData.setEndPort(vsg.getRuleEndPort()); + } + + if (vsg.getRuleAllowedNetworkId() != null) { + List sgs = this.searchByIds(vsg.getRuleAllowedNetworkId()); + if (sgs != null && sgs.size() > 0) { + SecurityGroupJoinVO sg = sgs.get(0); + ruleData.setSecurityGroupName(sg.getName()); + ruleData.setAccountName(sg.getAccountName()); + } + } else { + ruleData.setCidr(vsg.getRuleAllowedSourceIpCidr()); + } + + if (vsg.getRuleType() == SecurityRuleType.IngressRule) { + ruleData.setObjectName("ingressrule"); + sgResponse.addSecurityGroupIngressRule(ruleData); + } else { + ruleData.setObjectName("egressrule"); + sgResponse.addSecurityGroupEgressRule(ruleData); + } + } + + // update tag information + Long tag_id = vsg.getTagId(); + if (tag_id != null && tag_id.longValue() > 0) { + ResourceTagResponse tag = new ResourceTagResponse(); + tag.setKey(vsg.getTagKey()); + tag.setValue(vsg.getTagValue()); + if (vsg.getTagResourceType() != null) { + tag.setResourceType(vsg.getTagResourceType().toString()); + } + tag.setId(vsg.getTagResourceUuid()); // tag resource uuid + tag.setCustomer(vsg.getTagCustomer()); + // TODO: assuming tagAccountId and tagDomainId are the same as VM + // accountId and domainId + tag.setDomainId(vsg.getTagDomainId()); + if (vsg.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { + tag.setProjectId(vsg.getProjectId()); + tag.setProjectName(vsg.getProjectName()); + } else { + tag.setAccountName(vsg.getAccountName()); + } + tag.setDomainId(vsg.getDomainId()); // TODO: pending tag resource + // response uuid change + tag.setDomainName(vsg.getDomainName()); + + tag.setObjectName("tag"); + sgResponse.addTag(tag); + } + sgResponse.setObjectName("securitygroup"); + + return sgResponse; + } + + @Override + public SecurityGroupResponse setSecurityGroupResponse(SecurityGroupResponse vsgData, SecurityGroupJoinVO vsg) { + Long rule_id = vsg.getRuleId(); + if (rule_id != null && rule_id.longValue() > 0) { + SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); + ruleData.setRuleId(vsg.getRuleUuid()); + ruleData.setProtocol(vsg.getRuleProtocol()); + + if ("icmp".equalsIgnoreCase(vsg.getRuleProtocol())) { + ruleData.setIcmpType(vsg.getRuleStartPort()); + ruleData.setIcmpCode(vsg.getRuleEndPort()); + } else { + ruleData.setStartPort(vsg.getRuleStartPort()); + ruleData.setEndPort(vsg.getRuleEndPort()); + } + + if (vsg.getRuleAllowedNetworkId() != null) { + List sgs = this.searchByIds(vsg.getRuleAllowedNetworkId()); + if (sgs != null && sgs.size() > 0) { + SecurityGroupJoinVO sg = sgs.get(0); + ruleData.setSecurityGroupName(sg.getName()); + ruleData.setAccountName(sg.getAccountName()); + } + } else { + ruleData.setCidr(vsg.getRuleAllowedSourceIpCidr()); + } + + if (vsg.getRuleType() == SecurityRuleType.IngressRule) { + ruleData.setObjectName("ingressrule"); + vsgData.addSecurityGroupIngressRule(ruleData); + } else { + ruleData.setObjectName("egressrule"); + vsgData.addSecurityGroupEgressRule(ruleData); + } + } + + // update tag information + Long tag_id = vsg.getTagId(); + if (tag_id != null && tag_id.longValue() > 0 ) { + ResourceTagResponse tag = new ResourceTagResponse(); + tag.setKey(vsg.getTagKey()); + tag.setValue(vsg.getTagValue()); + if (vsg.getTagResourceType() != null) { + tag.setResourceType(vsg.getTagResourceType().toString()); + } + tag.setId(vsg.getTagResourceUuid()); // tag resource uuid + tag.setCustomer(vsg.getTagCustomer()); + // TODO: assuming tagAccountId and tagDomainId are the same as VM + // accountId and domainId + tag.setDomainId(vsg.getTagDomainId()); + if (vsg.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { + tag.setProjectId(vsg.getProjectId()); + tag.setProjectName(vsg.getProjectName()); + } else { + tag.setAccountName(vsg.getAccountName()); + } + tag.setDomainId(vsg.getDomainId()); // TODO: pending tag resource + // response uuid change + tag.setDomainName(vsg.getDomainName()); + + tag.setObjectName("tag"); + vsgData.addTag(tag); + } + return vsgData; + } + + @Override + public List newSecurityGroupView(SecurityGroup sg) { + List uvList = new ArrayList(); + SearchCriteria sc = sgIdSearch.create(); + sc.setParameters("id", sg.getId()); + List sgs = searchIncludingRemoved(sc, null, null, false); + if (sgs != null) { + for (SecurityGroupJoinVO uvm : sgs) { + uvList.add(uvm); + } + } + return uvList; + } + + @Override + public List searchByIds(Long... ids) { + SearchCriteria sc = sgSearch.create(); + sc.setParameters("idIN", ids); + return searchIncludingRemoved(sc, null, null, false); + } +} diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java b/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java index cc842df7d64..cbeae4f1483 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java @@ -19,12 +19,15 @@ package com.cloud.network.security.dao; import java.util.List; import com.cloud.network.security.SecurityGroupVMMapVO; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDao; import com.cloud.vm.VirtualMachine.State; public interface SecurityGroupVMMapDao extends GenericDao { List listByIpAndInstanceId(String ipAddress, long instanceId); List listByInstanceId(long instanceId); + Pair, Integer> listByInstanceId(long instanceId, Filter filter); List listByIp(String ipAddress); List listBySecurityGroup(long securityGroupId); List listBySecurityGroup(long securityGroupId, State ... vmStates); diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java index db6c0029447..95dd7f3aca2 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java @@ -24,6 +24,8 @@ import com.cloud.dc.VlanVO; import com.cloud.dc.Vlan.VlanType; import com.cloud.network.IPAddressVO; import com.cloud.network.security.SecurityGroupVMMapVO; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; @@ -114,6 +116,13 @@ public class SecurityGroupVMMapDaoImpl extends GenericDaoBase, Integer> listByInstanceId(long instanceId, Filter filter) { + SearchCriteria sc = ListByVmId.create(); + sc.setParameters("instanceId", instanceId); + return this.searchAndCount(sc, filter); + } + @Override public int deleteVM(long instanceId) { SearchCriteria sc = ListByVmId.create(); diff --git a/server/src/com/cloud/vm/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/vm/dao/UserVmJoinDaoImpl.java index 4df9f88e8eb..63ebb26510a 100644 --- a/server/src/com/cloud/vm/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/vm/dao/UserVmJoinDaoImpl.java @@ -164,16 +164,12 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem Long securityGroupId = userVm.getSecurityGroupId(); if (securityGroupId != null && securityGroupId.longValue() != 0) { SecurityGroupResponse resp = new SecurityGroupResponse(); - resp.setId(userVm.getSecurityGroupId()); // TODO: change - // SecurityGroupResponse - // IdentityProxy + resp.setId(userVm.getSecurityGroupUuid()); resp.setName(userVm.getSecurityGroupName()); resp.setDescription(userVm.getSecurityGroupDescription()); resp.setObjectName("securitygroup"); if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { - resp.setProjectId(userVm.getProjectId()); // TODO: pending - // SecurityGroupResponse - // uuid change + resp.setProjectId(userVm.getProjectUuid()); resp.setProjectName(userVm.getProjectName()); } else { resp.setAccountName(userVm.getAccountName()); @@ -246,16 +242,12 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem Long securityGroupId = uvo.getSecurityGroupId(); if (securityGroupId != null && securityGroupId.longValue() != 0) { SecurityGroupResponse resp = new SecurityGroupResponse(); - resp.setId(uvo.getSecurityGroupId()); // TODO: change - // SecurityGroupResponse - // IdentityProxy + resp.setId(uvo.getSecurityGroupUuid()); resp.setName(uvo.getSecurityGroupName()); resp.setDescription(uvo.getSecurityGroupDescription()); resp.setObjectName("securitygroup"); if (uvo.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { - resp.setProjectId(uvo.getProjectId()); // TODO: pending - // SecurityGroupResponse - // uuid change + resp.setProjectId(uvo.getProjectUuid()); resp.setProjectName(uvo.getProjectName()); } else { resp.setAccountName(uvo.getAccountName());