package com.eucalyptus.network; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import com.eucalyptus.bootstrap.Component; import com.eucalyptus.context.ServiceContext; import com.eucalyptus.entities.EntityWrapper; import com.eucalyptus.entities.NetworkRule; import com.eucalyptus.entities.NetworkRulesGroup; import com.eucalyptus.util.EucalyptusCloudException; import com.eucalyptus.ws.util.Messaging; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import edu.ucsb.eucalyptus.cloud.Network; import edu.ucsb.eucalyptus.cloud.VmAllocationInfo; import edu.ucsb.eucalyptus.msgs.AuthorizeSecurityGroupIngressResponseType; import edu.ucsb.eucalyptus.msgs.AuthorizeSecurityGroupIngressType; import edu.ucsb.eucalyptus.msgs.CreateSecurityGroupResponseType; import edu.ucsb.eucalyptus.msgs.CreateSecurityGroupType; import edu.ucsb.eucalyptus.msgs.DeleteSecurityGroupResponseType; import edu.ucsb.eucalyptus.msgs.DeleteSecurityGroupType; import edu.ucsb.eucalyptus.msgs.DescribeSecurityGroupsResponseType; import edu.ucsb.eucalyptus.msgs.DescribeSecurityGroupsType; import edu.ucsb.eucalyptus.msgs.IpPermissionType; import edu.ucsb.eucalyptus.msgs.RevokeSecurityGroupIngressResponseType; import edu.ucsb.eucalyptus.msgs.RevokeSecurityGroupIngressType; import edu.ucsb.eucalyptus.msgs.SecurityGroupItemType; public class NetworkGroupManager { private static Logger LOG = Logger.getLogger( NetworkGroupManager.class ); public VmAllocationInfo verify( VmAllocationInfo vmAllocInfo ) throws EucalyptusCloudException { NetworkGroupUtil.makeDefault( vmAllocInfo.getRequest( ).getUserId( ) );//ensure the default group exists to cover some old broken installs ArrayList<String> networkNames = new ArrayList<String>( vmAllocInfo.getRequest( ).getGroupSet( ) ); if ( networkNames.size( ) < 1 ) { networkNames.add( "default" ); } Map<String, NetworkRulesGroup> networkRuleGroups = new HashMap<String, NetworkRulesGroup>( ); for ( String groupName : networkNames ) { NetworkRulesGroup group = NetworkGroupUtil.getUserNetworkRulesGroup( vmAllocInfo.getRequest( ).getUserId( ), groupName ); networkRuleGroups.put( groupName, group ); vmAllocInfo.getNetworks( ).add( group.getVmNetwork( ) ); } ArrayList<String> userNetworks = new ArrayList<String>( networkRuleGroups.keySet( ) ); if ( !userNetworks.containsAll( networkNames ) ) { networkNames.removeAll( userNetworks ); throw new EucalyptusCloudException( "Failed to find " + networkNames ); } return vmAllocInfo; } public CreateSecurityGroupResponseType create( CreateSecurityGroupType request ) throws EucalyptusCloudException { NetworkGroupUtil.makeDefault( request.getUserId( ) );//ensure the default group exists to cover some old broken installs CreateSecurityGroupResponseType reply = ( CreateSecurityGroupResponseType ) request.getReply( ); NetworkRulesGroup newGroup = NetworkGroupUtil.createUserNetworkRulesGroup( request.getUserId( ), request.getGroupName( ), request.getGroupDescription( ) ); reply.set_return( true ); return reply; } public DeleteSecurityGroupResponseType delete( DeleteSecurityGroupType request ) throws EucalyptusCloudException { NetworkGroupUtil.makeDefault( request.getUserId( ) );//ensure the default group exists to cover some old broken installs DeleteSecurityGroupResponseType reply = ( DeleteSecurityGroupResponseType ) request.getReply( ); if ( request.isAdministrator( ) && request.getGroupName( ).indexOf( "::" ) != -1 ) { NetworkGroupUtil.deleteUserNetworkRulesGroup( request.getGroupName( ).replaceAll( "::.*", "" ), request.getGroupName( ).replaceAll( "\\w*::", "" ) ); } else { NetworkGroupUtil.deleteUserNetworkRulesGroup( request.getUserId( ), request.getGroupName( ) ); } reply.set_return( true ); return reply; } public DescribeSecurityGroupsResponseType describe( DescribeSecurityGroupsType request ) throws EucalyptusCloudException { NetworkGroupUtil.makeDefault( request.getUserId( ) );//ensure the default group exists to cover some old broken installs final List<String> groupNames = request.getSecurityGroupSet( ); DescribeSecurityGroupsResponseType reply = ( DescribeSecurityGroupsResponseType ) request.getReply( ); final List<SecurityGroupItemType> replyList = reply.getSecurityGroupInfo( ); if ( request.isAdministrator( ) ) { try { for ( SecurityGroupItemType group : Iterables.filter( NetworkGroupUtil.getUserNetworksAdmin( request.getUserId( ), request.getSecurityGroupSet( ) ), new Predicate<SecurityGroupItemType>( ) { @Override public boolean apply( SecurityGroupItemType arg0 ) { return groupNames.isEmpty( ) || groupNames.contains( arg0.getGroupName( ) ); } } ) ) { replyList.add( group ); } } catch ( Exception e ) { LOG.debug( e, e ); } } else { try { for ( SecurityGroupItemType group : Iterables.filter( NetworkGroupUtil.getUserNetworks( request.getUserId( ), request.getSecurityGroupSet( ) ), new Predicate<SecurityGroupItemType>( ) { @Override public boolean apply( SecurityGroupItemType arg0 ) { return groupNames.isEmpty( ) || groupNames.contains( arg0.getGroupName( ) ); } } ) ) { replyList.add( group ); } } catch ( Exception e ) { LOG.debug( e, e ); } } return reply; } public RevokeSecurityGroupIngressResponseType revoke( RevokeSecurityGroupIngressType request ) throws EucalyptusCloudException { NetworkGroupUtil.makeDefault( request.getUserId( ) );//ensure the default group exists to cover some old broken installs RevokeSecurityGroupIngressResponseType reply = ( RevokeSecurityGroupIngressResponseType ) request.getReply( ); NetworkRulesGroup ruleGroup = NetworkGroupUtil.getUserNetworkRulesGroup( request.getUserId( ), request.getGroupName( ) ); final List<NetworkRule> ruleList = Lists.newArrayList( ); for ( IpPermissionType ipPerm : request.getIpPermissions( ) ) { ruleList.addAll( NetworkGroupUtil.getNetworkRules( ipPerm ) ); } List<NetworkRule> filtered = Lists.newArrayList( Iterables.filter( ruleGroup.getNetworkRules( ), new Predicate<NetworkRule>( ) { @Override public boolean apply( NetworkRule rule ) { for ( NetworkRule r : ruleList ) { if ( r.equals( rule ) && r.getNetworkPeers( ).equals( rule.getNetworkPeers( ) ) && r.getIpRanges( ).equals( rule.getIpRanges( ) ) ) { return true; } } return false; } } ) ); if ( filtered.size( ) == ruleList.size( ) ) { for ( NetworkRule r : filtered ) { ruleGroup.getNetworkRules( ).remove( r ); } NetworkGroupUtil.getEntityWrapper( ).mergeAndCommit( ruleGroup ); } else if ( request.getIpPermissions( ).size( ) == 1 && request.getIpPermissions( ).get( 0 ).getIpProtocol( ) == null ) { //LAME: this is for the query-based clients which send incomplete named-network requests. for ( NetworkRule rule : ruleList ) { if ( ruleGroup.getNetworkRules( ).remove( rule ) ) { reply.set_return( true ); } } if ( reply.get_return( ) ) { NetworkGroupUtil.getEntityWrapper( ).mergeAndCommit( ruleGroup ); } } else { reply.set_return( false ); return reply; } Network changedNetwork = ruleGroup.getVmNetwork( ); ServiceContext.dispatch( "ClusterSink", changedNetwork ); reply.set_return( true ); return reply; } public AuthorizeSecurityGroupIngressResponseType authorize( AuthorizeSecurityGroupIngressType request ) throws Exception { NetworkGroupUtil.makeDefault( request.getUserId( ) );//ensure the default group exists to cover some old broken installs AuthorizeSecurityGroupIngressResponseType reply = ( AuthorizeSecurityGroupIngressResponseType ) request.getReply( ); EntityWrapper<NetworkRulesGroup> db = NetworkGroupUtil.getEntityWrapper( ); NetworkRulesGroup ruleGroup = NetworkGroupUtil.getUserNetworkRulesGroup( request.getUserId( ), request.getGroupName( ) ); final List<NetworkRule> ruleList = Lists.newArrayList( ); for ( IpPermissionType ipPerm : request.getIpPermissions( ) ) { ruleList.addAll( NetworkGroupUtil.getNetworkRules( ipPerm ) ); } if ( Iterables.any( ruleGroup.getNetworkRules( ), new Predicate<NetworkRule>( ) { @Override public boolean apply( NetworkRule rule ) { for ( NetworkRule r : ruleList ) { if ( r.equals( rule ) && r.getNetworkPeers( ).equals( rule.getNetworkPeers( ) ) && r.getIpRanges( ).equals( rule.getIpRanges( ) ) ) { return true || !r.isValid( ); } } return false; } } ) ) { reply.set_return( false ); db.rollback( ); return reply; } ruleGroup.getNetworkRules( ).addAll( ruleList ); db.merge( ruleGroup ); db.commit( ); Network changedNetwork = ruleGroup.getVmNetwork( ); ServiceContext.dispatch( "ClusterSink", changedNetwork ); reply.set_return( true ); return reply; } }