/*
* Copyright 2011 Cloud.com, Inc.
*
* Licensed 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.bridge.service.core.ec2;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.cloud.bridge.service.exception.EC2ServiceException;
public class EC2GroupFilterSet {
protected List<EC2Filter> filterSet = new ArrayList<EC2Filter>();
private Map<String,String> filterTypes = new HashMap<String,String>();
public EC2GroupFilterSet()
{
// -> use these values to check that the proper filter is passed to this type of filter set
filterTypes.put( "description", "string" );
filterTypes.put( "group-id", "string" );
filterTypes.put( "group-name", "string" );
filterTypes.put( "ip-permission.cidr", "string" );
filterTypes.put( "ip-permission.from-port", "string" );
filterTypes.put( "ip-permission.to-port", "string" );
filterTypes.put( "ip-permission.protocol", "string" );
filterTypes.put( "owner-id", "string" );
}
public void addFilter( EC2Filter param )
{
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}
public EC2Filter[] getFilterSet() {
return filterSet.toArray(new EC2Filter[0]);
}
/**
* For a filter to match a snapshot just one of its values has to match the volume.
* For a snapshot to be included in the instance response it must pass all the defined filters.
*
* @param sampleList - list of snapshots to test against the defined filters
* @return EC2DescribeSnapshotsResponse
* @throws ParseException
*/
public EC2DescribeSecurityGroupsResponse evaluate( EC2DescribeSecurityGroupsResponse sampleList ) throws ParseException
{
EC2DescribeSecurityGroupsResponse resultList = new EC2DescribeSecurityGroupsResponse();
boolean matched;
EC2SecurityGroup[] groupSet = sampleList.getGroupSet();
EC2Filter[] filterSet = getFilterSet();
for (EC2SecurityGroup group : groupSet) {
List<EC2Filter> ipPermissionFilterSet = new ArrayList<EC2Filter>();
matched = true;
for (EC2Filter filter : filterSet) {
if (filter.getName().startsWith("ip-permission"))
ipPermissionFilterSet.add(filter);
else {
if (!filterMatched( group, filter)) {
matched = false;
break;
}
}
}
if (matched) {
if (ipPermissionFilterSet.isEmpty() || ipPermissionFilterMatched(group, ipPermissionFilterSet))
resultList.addGroup( group );
}
}
return resultList;
}
private boolean filterMatched( EC2SecurityGroup sg, EC2Filter filter ) throws ParseException
{
String filterName = filter.getName();
String[] valueSet = filter.getValueSet();
if ( filterName.equalsIgnoreCase( "description" ))
return containsString( sg.getDescription(), valueSet );
else if (filterName.equalsIgnoreCase( "group-id" ))
return containsString( sg.getId(), valueSet );
else if (filterName.equalsIgnoreCase( "group-name" ))
return containsString( sg.getName(), valueSet );
else if (filterName.equalsIgnoreCase( "owner-id" )) {
String owner = new String( sg.getDomainId() + ":" + sg.getAccountName());
return containsString( owner, valueSet );
}
else return false;
}
private boolean ipPermissionFilterMatched( EC2SecurityGroup sg, List<EC2Filter> ipPermissionFilterSet ) throws ParseException
{
EC2IpPermission[] permissionSet = sg.getIpPermissionSet();
for (EC2IpPermission perm : permissionSet) {
boolean matched = true;
for (EC2Filter filter : ipPermissionFilterSet) {
String filterName = filter.getName();
String[] valueSet = filter.getValueSet();
if (filterName.equalsIgnoreCase( "ip-permission.cidr" ))
matched = containsString(perm.getCIDR(), valueSet);
else if (filterName.equalsIgnoreCase( "ip-permission.from-port" )) {
if (perm.getProtocol().equalsIgnoreCase("icmp"))
matched = containsString(perm.getIcmpType(), valueSet);
else
matched = containsString(perm.getFromPort().toString(), valueSet);
} else if (filterName.equalsIgnoreCase( "ip-permission.to-port" )) {
if (perm.getProtocol().equalsIgnoreCase("icmp"))
matched = containsString(perm.getIcmpCode(), valueSet);
else
matched = containsString( perm.getToPort().toString(), valueSet );
} else if (filterName.equalsIgnoreCase( "ip-permission.protocol" ))
matched = containsString( perm.getProtocol(), valueSet );
if (!matched) break;
}
if (matched) return true;
}
return false;
}
private boolean containsString( String lookingFor, String[] set )
{
if (null == lookingFor) return false;
for (String s : set) {
//System.out.println( "contsinsString: " + lookingFor + " " + set[i] );
if (lookingFor.matches( s )) return true;
}
return false;
}
}