package com.eucalyptus.network; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import com.eucalyptus.auth.UserInfo; import com.eucalyptus.auth.Users; import com.eucalyptus.auth.principal.User; import com.eucalyptus.entities.EntityWrapper; import com.eucalyptus.entities.IpRange; import com.eucalyptus.entities.NetworkPeer; import com.eucalyptus.entities.NetworkRule; import com.eucalyptus.entities.NetworkRulesGroup; import com.eucalyptus.util.EucalyptusCloudException; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import edu.ucsb.eucalyptus.msgs.IpPermissionType; import edu.ucsb.eucalyptus.msgs.SecurityGroupItemType; import edu.ucsb.eucalyptus.msgs.UserIdGroupPairType; public class NetworkGroupUtil { public static EntityWrapper<NetworkRulesGroup> getEntityWrapper( ) { EntityWrapper<NetworkRulesGroup> db = new EntityWrapper<NetworkRulesGroup>( ); return db; } public static List<NetworkRulesGroup> getUserNetworkRulesGroup( String userName ) { EntityWrapper<NetworkRulesGroup> db = NetworkGroupUtil.getEntityWrapper( ); List<NetworkRulesGroup> networkGroups = Lists.newArrayList( ); try { networkGroups = db.query( new NetworkRulesGroup( userName ) ); db.commit( ); } catch ( Throwable e ) { db.rollback( ); } return networkGroups; } public static NetworkRulesGroup getUserNetworkRulesGroup( String userName, String groupName ) throws EucalyptusCloudException { EntityWrapper<NetworkRulesGroup> db = NetworkGroupUtil.getEntityWrapper( ); NetworkRulesGroup group = null; try { group = db.getUnique( new NetworkRulesGroup( userName, groupName ) ); db.commit( ); } catch ( EucalyptusCloudException e ) { db.rollback( ); throw e; } return group; } public static NetworkRulesGroup deleteUserNetworkRulesGroup( String userName, String groupName ) throws EucalyptusCloudException { EntityWrapper<NetworkRulesGroup> db = NetworkGroupUtil.getEntityWrapper( ); NetworkRulesGroup group = null; try { group = db.getUnique( new NetworkRulesGroup( userName, groupName ) ); db.delete( group ); db.commit( ); } catch ( EucalyptusCloudException e ) { db.rollback( ); throw e; } catch ( Throwable e ) { db.rollback( ); throw new EucalyptusCloudException( e ); } return group; } public static NetworkRulesGroup createUserNetworkRulesGroup( String userName, String groupName, String groupDescription ) throws EucalyptusCloudException { EntityWrapper<NetworkRulesGroup> db = NetworkGroupUtil.getEntityWrapper( ); NetworkRulesGroup group = new NetworkRulesGroup( userName, groupName, groupDescription ); try { db.getUnique( NetworkRulesGroup.named( userName, groupName ) ); db.rollback( ); throw new EucalyptusCloudException( "Error adding network group: group named " +groupName+ " already exists" ); } catch ( Throwable e ) { try { db.add( group ); db.commit( ); } catch ( Throwable e1 ) { throw new EucalyptusCloudException( "Error adding network group: group named " +groupName+ " already exists", e ); } } return group; } protected static void makeDefault( String userId ) { try { getUserNetworkRulesGroup( userId, NetworkRulesGroup.NETWORK_DEFAULT_NAME ); } catch ( Exception e ) { try { createUserNetworkRulesGroup( userId, NetworkRulesGroup.NETWORK_DEFAULT_NAME, "default group" ); } catch ( Exception e1 ) {} } } public static List<SecurityGroupItemType> getUserNetworksAdmin( String userId, List<String> groupNames ) throws EucalyptusCloudException { List<SecurityGroupItemType> groupInfoList = Lists.newArrayList( ); if ( groupNames.isEmpty( ) ) { for( User u : Users.listAllUsers( ) ) { groupInfoList.addAll( NetworkGroupUtil.getUserNetworks( u.getName( ), groupNames ) ); } } else { for ( String groupName : groupNames ) { if ( !NetworkGroupUtil.isUserGroupRef( groupName ) ) { groupInfoList.addAll( NetworkGroupUtil.getUserNetworks( userId, Lists.newArrayList( groupName ) ) ); } else { groupInfoList.addAll( NetworkGroupUtil.getUserNetworksAdmin( groupName ) ); } } } return groupInfoList; } public static boolean isUserGroupRef( String adminGroupName ) { return adminGroupName.indexOf( "::" ) != -1; } public static List<SecurityGroupItemType> getUserNetworksAdmin( String adminGroupName ) throws EucalyptusCloudException { return getUserNetworks( adminGroupName.replaceAll("::\\w*",""), Lists.newArrayList( adminGroupName.replaceFirst( "\\w*::", "" ) ) ); } public static List<SecurityGroupItemType> getUserNetworks( String userId, List<String> groupNames ) throws EucalyptusCloudException { List<SecurityGroupItemType> groupInfoList = Lists.newArrayList(); List<NetworkRulesGroup> userGroups = Lists.newArrayList( ); if( groupNames.isEmpty( ) ) { userGroups.addAll( NetworkGroupUtil.getUserNetworkRulesGroup( userId ) ); } else { for( String groupName : groupNames ) { try { userGroups.add( NetworkGroupUtil.getUserNetworkRulesGroup( userId, groupName ) ); } catch ( Exception e ) {} } } for ( NetworkRulesGroup group : NetworkGroupUtil.getUserNetworkRulesGroup( userId ) ) { groupInfoList.add( getAsSecurityGroupItemType( userId, group ) ); } return groupInfoList; } public static SecurityGroupItemType getAsSecurityGroupItemType( String userId, NetworkRulesGroup group ) { SecurityGroupItemType groupInfo = new SecurityGroupItemType(); groupInfo.setGroupName( group.getDisplayName() ); groupInfo.setGroupDescription( group.getDescription() ); groupInfo.setOwnerId( userId ); for ( NetworkRule rule : group.getNetworkRules() ) { IpPermissionType ipPerm = new IpPermissionType( rule.getProtocol(), rule.getLowPort(), rule.getHighPort() ); for ( IpRange ipRange : rule.getIpRanges() ) ipPerm.getIpRanges().add( ipRange.getValue() ); if ( !rule.getNetworkPeers().isEmpty() ) for ( NetworkPeer peer : rule.getNetworkPeers() ) ipPerm.getGroups().add( new UserIdGroupPairType( peer.getUserQueryKey(), peer.getGroupName() ) ); groupInfo.getIpPermissions().add( ipPerm ); } return groupInfo; } static List<NetworkRule> getNetworkRules( final IpPermissionType ipPerm ) { List<NetworkRule> ruleList = new ArrayList<NetworkRule>(); if ( !ipPerm.getGroups().isEmpty() ) { if( ipPerm.getFromPort() == 0 && ipPerm.getToPort() == 0 ) { ipPerm.setToPort( 65535 ); } //:: fixes handling of under-specified named-network rules sent by some clients ::// if( ipPerm.getIpProtocol() == null ) { NetworkRule rule = new NetworkRule( "tcp", ipPerm.getFromPort(), ipPerm.getToPort() ); rule.getNetworkPeers().addAll( getNetworkPeers( ipPerm ) ); ruleList.add( rule ); NetworkRule rule1 = new NetworkRule( "udp", ipPerm.getFromPort(), ipPerm.getToPort() ); rule1.getNetworkPeers().addAll( getNetworkPeers( ipPerm ) ); ruleList.add( rule1 ); NetworkRule rule2 = new NetworkRule( "icmp", -1, -1 ); rule2.getNetworkPeers().addAll( getNetworkPeers( ipPerm ) ); ruleList.add( rule2 ); } else { NetworkRule rule = new NetworkRule( ipPerm.getIpProtocol(), ipPerm.getFromPort(), ipPerm.getToPort() ); rule.getNetworkPeers().addAll( getNetworkPeers( ipPerm ) ); ruleList.add( rule ); } } else if ( !ipPerm.getIpRanges().isEmpty() ) { List<IpRange> ipRanges = new ArrayList<IpRange>(); for ( String range : ipPerm.getIpRanges() ) { String[] rangeParts = range.split( "/" ); try { if( Integer.parseInt( rangeParts[1] ) > 32 || Integer.parseInt( rangeParts[1] ) < 0 ) continue; if( rangeParts.length != 2 ) continue; if( InetAddress.getByName( rangeParts[0] ) != null ) { ipRanges.add( new IpRange( range ) ); } } catch ( NumberFormatException e ) { } catch ( UnknownHostException e ) { } } NetworkRule rule = new NetworkRule( ipPerm.getIpProtocol(), ipPerm.getFromPort(), ipPerm.getToPort(), ipRanges ); ruleList.add( rule ); } return ruleList; } private static List<NetworkPeer> getNetworkPeers( final IpPermissionType ipPerm ) { List<NetworkPeer> networkPeers = new ArrayList<NetworkPeer>(); for ( UserIdGroupPairType peerInfo : ipPerm.getGroups() ) { networkPeers.add( new NetworkPeer( peerInfo.getSourceUserId(), peerInfo.getSourceGroupName() ) ); } return networkPeers; } }