Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'team/clc-dev/services' into testing

  • Loading branch information...
commit dadb8ff413f8175abb02b78a86de579a8a2336a7 2 parents d3e7334 + 293d7c4
@viglesiasce viglesiasce authored
Showing with 6,834 additions and 668 deletions.
  1. +0 −1  .gitignore
  2. +3 −1 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/CloudMetadata.java
  3. +74 −10 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/CloudMetadatas.java
  4. +4 −0 clc/modules/cloud/src/main/resources/eucalyptus-model.xml
  5. +2 −1  clc/modules/cloud/src/main/resources/eucalyptus-services.xml
  6. +12 −0 clc/modules/cloud/src/main/resources/eucalyptus-userdata.xml
  7. +10 −4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/address/AddressManager.java
  8. +30 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/address/Addresses.java
  9. +8 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshot.java
  10. +28 −20 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotManager.java
  11. +125 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotTag.java
  12. +82 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshots.java
  13. +8 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volume.java
  14. +18 −17 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeManager.java
  15. +125 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeTag.java
  16. +119 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volumes.java
  17. +2 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/AccountMetadata.java
  18. +14 −8 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Cluster.java
  19. +101 −24 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/ClusterEndpoint.java
  20. +6 −1 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageInfo.java
  21. +127 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageInfoTag.java
  22. +17 −7 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageManager.java
  23. +8 −1 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/Images.java
  24. +16 −7 clc/modules/cluster-manager/src/main/java/com/eucalyptus/keys/KeyPairManager.java
  25. +46 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/keys/KeyPairs.java
  26. +28 −1 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroup.java
  27. +104 −44 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupManager.java
  28. +125 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupTag.java
  29. +130 −6 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroups.java
  30. +111 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/Filter.java
  31. +50 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/FilterDiscovery.java
  32. +1,060 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/FilterSupport.java
  33. +78 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/Filters.java
  34. +34 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/InvalidFilterException.java
  35. +146 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/Tag.java
  36. +281 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/TagManager.java
  37. +123 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/TagSupport.java
  38. +51 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/TagSupportDiscovery.java
  39. +181 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/tags/Tags.java
  40. +4 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/Bundling.groovy
  41. +20 −16 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmBundleTask.java
  42. +32 −41 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmControl.java
  43. +10 −1 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstance.java
  44. +166 −0 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstanceTag.java
  45. +176 −21 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstances.java
  46. +2 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmVolumeAttachment.java
  47. +58 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/address/AddressFilterSupportTest.groovy
  48. +84 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/blockstorage/SnapshotFilterSupportTest.groovy
  49. +63 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/blockstorage/VolumeFilterSupportTest.groovy
  50. +55 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/cluster/AvailabilityZoneFilterSupportTest.groovy
  51. +56 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/cluster/RegionFilterSupportTest.groovy
  52. +34 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/images/ImageInfoFilterSupportTest.groovy
  53. +53 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/keys/KeyPairFilterSupportTest.groovy
  54. +78 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/network/NetworkGroupFilterSupportTest.groovy
  55. +160 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/tags/FilterSupportTest.groovy
  56. +60 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/tags/TagFilterSupportTest.groovy
  57. +72 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/vm/VmBundleTaskFilterSupportTask.groovy
  58. +34 −0 clc/modules/cluster-manager/src/test/java/com/eucalyptus/vm/VmInstanceFilterSupportTest.groovy
  59. +33 −0 clc/modules/core/src/main/java/edu/ucsb/eucalyptus/cloud/InvalidParameterValueException.java
  60. +3 −1 clc/modules/euare/src/main/java/com/eucalyptus/auth/ws/EuareQueryPipeline.java
  61. +55 −21 clc/modules/msgs/src/main/java/com/eucalyptus/auth/login/HmacCredentials.java
  62. +23 −6 clc/modules/msgs/src/main/java/com/eucalyptus/auth/login/HmacLoginModuleSupport.java
  63. +12 −3 clc/modules/msgs/src/main/java/com/eucalyptus/auth/login/Hmacv1LoginModule.java
  64. +15 −14 clc/modules/msgs/src/main/java/com/eucalyptus/auth/login/Hmacv2LoginModule.java
  65. +182 −0 clc/modules/msgs/src/main/java/com/eucalyptus/auth/login/Hmacv4LoginModule.java
  66. +5 −0 clc/modules/msgs/src/main/java/com/eucalyptus/auth/policy/PolicySpec.java
  67. +97 −0 clc/modules/msgs/src/main/java/com/eucalyptus/crypto/util/SecurityHeader.java
  68. +31 −1 clc/modules/msgs/src/main/java/com/eucalyptus/crypto/util/SecurityParameter.java
  69. +130 −19 clc/modules/msgs/src/main/java/com/eucalyptus/crypto/util/Timestamps.java
  70. +52 −0 clc/modules/msgs/src/main/java/com/eucalyptus/entities/Entities.java
  71. +51 −7 clc/modules/msgs/src/main/java/com/eucalyptus/entities/Transactions.java
  72. +23 −7 clc/modules/msgs/src/main/java/com/eucalyptus/http/MappingHttpRequest.java
  73. +10 −0 clc/modules/msgs/src/main/java/com/eucalyptus/util/Classes.java
  74. +57 −0 clc/modules/msgs/src/main/java/com/eucalyptus/util/CollectionUtils.java
  75. +85 −0 clc/modules/msgs/src/main/java/com/eucalyptus/util/Strings.java
  76. +52 −29 clc/modules/msgs/src/main/java/com/eucalyptus/ws/handlers/HmacHandler.java
  77. +43 −30 clc/modules/msgs/src/main/java/com/eucalyptus/ws/handlers/QueryTimestampHandler.java
  78. +51 −0 clc/modules/msgs/src/main/java/com/eucalyptus/ws/handlers/SignatureHandlerUtils.java
  79. +34 −8 clc/modules/msgs/src/main/java/com/eucalyptus/ws/protocol/BaseQueryBinding.java
  80. +650 −0 clc/modules/msgs/src/main/java/com/eucalyptus/ws/util/HmacUtils.java
  81. +9 −5 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/Messages.groovy
  82. +68 −0 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/Tags.groovy
  83. +0 −54 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/Unimplemented.groovy
  84. +3 −5 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmAddresses.groovy
  85. +6 −5 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmBlockDevice.groovy
  86. +2 −15 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmControl.groovy
  87. +2 −3 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmImages.groovy
  88. +3 −3 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmKeys.groovy
  89. +7 −4 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmLocation.groovy
  90. +9 −4 clc/modules/msgs/src/main/java/edu/ucsb/eucalyptus/msgs/VmSecurity.groovy
  91. +78 −34 clc/modules/msgs/src/main/resources/aws-filters-tags-10-06-15.xml
  92. +3 −1 clc/modules/msgs/src/main/resources/aws-security-11-01-01.xml
  93. +236 −7 clc/modules/msgs/src/test/java/com/eucalyptus/auth/login/HmacLoginModuleTest.java
  94. BIN  clc/modules/msgs/src/test/resources/com/eucalyptus/auth/login/aws4_testsuite.zip
  95. +6 −1 clc/modules/tokens/src/main/java/com/eucalyptus/tokens/ws/TokensQueryPipeline.java
  96. +4 −0 clc/modules/wsstack/src/main/java/com/eucalyptus/ws/server/QueryPipeline.java
  97. +0 −139 clc/modules/wsstack/src/main/java/com/eucalyptus/ws/util/HmacUtils.java
View
1  .gitignore
@@ -87,6 +87,5 @@ node/nc-client-policy.xml
node/test
node/test_hooks
node/test_nc
-tags
util/euca-generate-fault
/.settings
View
4 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/CloudMetadata.java
@@ -73,7 +73,6 @@
* specific types which should /not/ be references.
*
* @see PolicyResourceType
- * @see PolicyResourceType#NO_VALUE_SPECIFED
* @see PolicyVendor
**/
@PolicyVendor( "ec2" )
@@ -109,4 +108,7 @@
public abstract Integer getDisk( );
}
+
+ @PolicyResourceType( "tag" )
+ public interface TagMetadata extends CloudMetadata {}
}
View
84 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/CloudMetadatas.java
@@ -63,10 +63,12 @@
package com.eucalyptus.cloud;
import java.util.Collection;
+import java.util.List;
import com.eucalyptus.util.RestrictedTypes;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.collect.Lists;
public class CloudMetadatas {
public static <T extends CloudMetadata> Function<T, String> toDisplayName( ) {
@@ -80,34 +82,96 @@ public String apply( T arg0 ) {
}
public static <T extends CloudMetadata> Predicate<T> filterById( final Collection<String> requestedIdentifiers ) {
- return new Predicate<T>( ) {
-
+ return filterByProperty( requestedIdentifiers, toDisplayName() );
+ }
+
+ public static <T extends CloudMetadata> Predicate<T> filterByProperty( final Collection<String> requestedValues,
+ final Function<? super T,String> extractor ) {
+
+ return new Predicate<T>( ) {
@Override
public boolean apply( T input ) {
- return requestedIdentifiers == null || requestedIdentifiers.isEmpty( ) || requestedIdentifiers.contains( input.getDisplayName( ) );
+ return requestedValues == null || requestedValues.isEmpty( ) || requestedValues.contains( extractor.apply( input ) );
}
};
-
}
public static <T extends CloudMetadata> Predicate<T> filterPrivilegesById( final Collection<String> requestedIdentifiers ) {
return Predicates.and( filterById( requestedIdentifiers ), RestrictedTypes.filterPrivileged( ) );
-
}
public static <T extends CloudMetadata> Predicate<T> filterByOwningAccount( final Collection<String> requestedIdentifiers ) {
return new Predicate<T>( ) {
-
@Override
public boolean apply( T input ) {
return requestedIdentifiers == null || requestedIdentifiers.isEmpty( ) || requestedIdentifiers.contains( input.getOwner( ).getAccountNumber( ) );
}
};
-
}
- public static <T extends CloudMetadata> Predicate<T> filterPrivilegesByOwningAccount( final Collection<String> requestedIdentifiers ) {
- return Predicates.and( filterByOwningAccount( requestedIdentifiers ), RestrictedTypes.filterPrivileged( ) );
-
+ public static <T extends CloudMetadata> FilterBuilder<T> filteringFor( final Class<T> metadataClass ) {
+ return new FilterBuilder<T>(metadataClass );
+ }
+
+ public static class FilterBuilder<T extends CloudMetadata> {
+ private final Class<T> metadataClass;
+ private final List<Predicate<? super T>> predicates = Lists.newArrayList();
+
+ private FilterBuilder( final Class<T> metadataClass ) {
+ this.metadataClass = metadataClass;
+ }
+
+ public FilterBuilder<T> byId( final Collection<String> requestedIdentifiers ) {
+ predicates.add( filterById( requestedIdentifiers ) );
+ return this;
+ }
+
+ public <T extends CloudMetadata> Predicate<T> filterByProperty( final Collection<String> requestedValues,
+ final Function<? super T,String> extractor ) {
+ return new Predicate<T>( ) {
+ @Override
+ public boolean apply( T input ) {
+ return requestedValues == null || requestedValues.isEmpty() || requestedValues.contains( extractor.apply(input) );
+ }
+ };
+ }
+
+ public FilterBuilder<T> byProperty(final Collection<String> requestedValues, final Function<? super T, String> extractor) {
+ predicates.add(filterByProperty(requestedValues, extractor));
+ return this;
+
+ }
+ public FilterBuilder<T> byPrivileges() {
+ predicates.add( RestrictedTypes.filterPrivileged() );
+ return this;
+ }
+
+ public FilterBuilder<T> byPrivilegesWithoutOwner() {
+ predicates.add( RestrictedTypes.filterPrivilegedWithoutOwner() );
+ return this;
+ }
+
+ public FilterBuilder<T> byOwningAccount( final Collection<String> requestedIdentifiers ) {
+ predicates.add( filterByOwningAccount( requestedIdentifiers ) );
+ return this;
+ }
+
+ public FilterBuilder<T> byPredicate( final Predicate<? super T> predicate ) {
+ predicates.add( predicate );
+ return this;
+ }
+
+//TODO:JDK7:Restore the original code for this (does not compile with OpenJDK 1.6.0_24)
+// public Predicate<? super T> buildPredicate() {
+// return Predicates.and( predicates );
+// }
+
+ public Predicate<? super T> buildPredicate() {
+ return buildPredicate( predicates );
+ }
+
+ private static <ST> Predicate<ST> buildPredicate( final List<Predicate<? super ST>> predicates ) {
+ return Predicates.and( predicates );
+ }
}
}
View
4 clc/modules/cloud/src/main/resources/eucalyptus-model.xml
@@ -128,6 +128,10 @@
<payload-type-filter expectedType="edu.ucsb.eucalyptus.msgs.VmSecurityMessage" />
</filtering-router>
<filtering-router>
+ <outbound-endpoint ref="TagsWS" />
+ <payload-type-filter expectedType="edu.ucsb.eucalyptus.msgs.ResourceTagMessage" />
+ </filtering-router>
+ <filtering-router>
<outbound-endpoint ref="ShortBusWS" />
<payload-type-filter expectedType="edu.ucsb.eucalyptus.msgs.EucalyptusMessage" />
</filtering-router>
View
3  clc/modules/cloud/src/main/resources/eucalyptus-services.xml
@@ -79,8 +79,9 @@
<endpoint name="SnapshotWS" address="vm://Snapshot" synchronous="false" />
<endpoint name="KeyPairWS" address="vm://KeyPair" synchronous="false" />
<endpoint name="GroupsWS" address="vm://Groups" synchronous="false" />
+ <endpoint name="TagsWS" address="vm://Tags" synchronous="false" />
- <!--run-time system state services-->
+ <!--run-time system state services-->
<endpoint name="ClusterEndpointWS" address="vm://ClusterEndpoint" synchronous="false" />
<endpoint name="ClusterSinkWS" address="vm://ClusterSink" synchronous="false" />
<endpoint name="VmMetadataWS" address="vm://VmMetadata" synchronous="true" />
View
12 clc/modules/cloud/src/main/resources/eucalyptus-userdata.xml
@@ -101,6 +101,18 @@
</outbound>
</service>
+ <service name="Tags">
+ <inbound>
+ <inbound-endpoint ref="TagsWS"/>
+ </inbound>
+ <component class="com.eucalyptus.tags.TagManager"/>
+ <outbound>
+ <outbound-pass-through-router>
+ <outbound-endpoint ref="ReplyQueueEndpoint"/>
+ </outbound-pass-through-router>
+ </outbound>
+ </service>
+
</model>
</mule>
View
14 clc/modules/cluster-manager/src/main/java/com/eucalyptus/address/AddressManager.java
@@ -74,6 +74,7 @@
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.records.Logs;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.Callback;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.RestrictedTypes;
@@ -81,6 +82,7 @@
import com.eucalyptus.util.async.UnconditionalCallback;
import com.eucalyptus.vm.VmInstance;
import com.eucalyptus.vm.VmInstances;
+import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import edu.ucsb.eucalyptus.msgs.AddressInfoType;
import edu.ucsb.eucalyptus.msgs.AllocateAddressResponseType;
@@ -130,10 +132,14 @@ public ReleaseAddressResponseType release( ReleaseAddressType request ) throws E
public DescribeAddressesResponseType describe( DescribeAddressesType request ) throws EucalyptusCloudException {
DescribeAddressesResponseType reply = ( DescribeAddressesResponseType ) request.getReply( );
Context ctx = Contexts.lookup( );
- boolean isAdmin = ctx.hasAdministrativePrivileges( );
- User requestUser = ctx.getUser( );
+ boolean isAdmin = ctx.hasAdministrativePrivileges();
+ User requestUser = ctx.getUser();
String action = PolicySpec.requestToAction( request );
- for ( Address address : Iterables.filter( Addresses.getInstance( ).listValues( ), CloudMetadatas.filterById( request.getPublicIpsSet( ) ) ) ) {
+ final Predicate<? super Address> filter = CloudMetadatas.filteringFor( Address.class )
+ .byId( request.getPublicIpsSet() )
+ .byPredicate( Filters.generate( request.getFilterSet(), Address.class ).asPredicate() )
+ .buildPredicate();
+ for ( Address address : Iterables.filter( Addresses.getInstance( ).listValues( ), filter ) ) {
//TODO:GRZE:FIXME this is not going to last this way.
Account addrAccount = null;
String addrAccountNumber = address.getOwnerAccountNumber( );
@@ -154,7 +160,7 @@ public DescribeAddressesResponseType describe( DescribeAddressesType request ) t
}
}
if ( isAdmin ) {
- for ( Address address : Iterables.filter( Addresses.getInstance( ).listDisabledValues( ), CloudMetadatas.filterById( request.getPublicIpsSet( ) ) ) ) {
+ for ( Address address : Iterables.filter( Addresses.getInstance( ).listDisabledValues( ), filter ) ) {
reply.getAddressesSet( ).add( new AddressInfoType( address.getName( ), Principals.nobodyFullName( ).getUserName( ) ) );
}
}
View
30 clc/modules/cluster-manager/src/main/java/com/eucalyptus/address/Addresses.java
@@ -85,6 +85,7 @@
import com.eucalyptus.event.Listeners;
import com.eucalyptus.event.SystemConfigurationEvent;
import com.eucalyptus.reporting.event.ResourceAvailabilityEvent;
+import com.eucalyptus.tags.FilterSupport;
import com.eucalyptus.util.Classes;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.LogUtil;
@@ -344,4 +345,33 @@ public boolean apply( final Address address ) {
}
}
}
+
+ public static class AddressFilterSupport extends FilterSupport<Address> {
+ public AddressFilterSupport() {
+ super( builderFor( Address.class )
+ .withConstantProperty( "domain", "standard" )
+ .withStringProperty( "instance-id", FilterFunctions.INSTANCE_ID )
+ .withStringProperty( "public-ip", FilterFunctions.PUBLIC_IP )
+ .withUnsupportedProperty( "allocation-id" )
+ .withUnsupportedProperty( "association-id" )
+ .withUnsupportedProperty( "network-interface-id" )
+ .withUnsupportedProperty( "network-interface-owner-id" )
+ .withUnsupportedProperty( "private-ip-address" ) );
+ }
+ }
+
+ private enum FilterFunctions implements Function<Address,String> {
+ INSTANCE_ID {
+ @Override
+ public String apply( final Address address ) {
+ return address.getInstanceId();
+ }
+ },
+ PUBLIC_IP {
+ @Override
+ public String apply( final Address address ) {
+ return address.getDisplayName();
+ }
+ }
+ }
}
View
10 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshot.java
@@ -62,10 +62,14 @@
package com.eucalyptus.blockstorage;
+import java.util.Collection;
import java.util.List;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EntityTransaction;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
import javax.persistence.PersistenceContext;
import javax.persistence.Table;
@@ -111,8 +115,10 @@
private String progress;
@Column( name = "metadata_snapshot_description", updatable = false )
private String description;
-
- private Snapshot( ) {
+ @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "snapshot" )
+ private Collection<SnapshotTag> tags;
+
+ protected Snapshot( ) {
super( );
}
View
48 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotManager.java
@@ -76,6 +76,7 @@
import org.apache.log4j.Logger;
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.auth.principal.AccountFullName;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.cloud.util.DuplicateMetadataException;
import com.eucalyptus.component.NoSuchComponentException;
import com.eucalyptus.component.Partitions;
@@ -95,6 +96,8 @@
import com.eucalyptus.reporting.event.EventActionInfo;
import com.eucalyptus.reporting.event.SnapShotEvent;
import com.eucalyptus.system.Threads;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.RestrictedTypes;
@@ -227,29 +230,34 @@ public boolean apply( ServiceConfiguration arg0 ) {
return reply;
}
- public DescribeSnapshotsResponseType describe( DescribeSnapshotsType request ) throws EucalyptusCloudException {
- DescribeSnapshotsResponseType reply = ( DescribeSnapshotsResponseType ) request.getReply( );
- Context ctx = Contexts.lookup( );
- boolean showAll = request.getSnapshotSet( ).remove( "verbose" );
- AccountFullName ownerFullName = ( ctx.hasAdministrativePrivileges( ) && showAll ) ? null : AccountFullName.getInstance( ctx.getAccount( ) );
- EntityTransaction db = Entities.get( Snapshot.class );
+ public DescribeSnapshotsResponseType describe( final DescribeSnapshotsType request ) throws EucalyptusCloudException {
+ final DescribeSnapshotsResponseType reply = ( DescribeSnapshotsResponseType ) request.getReply( );
+ final Context ctx = Contexts.lookup( );
+ final boolean showAll = request.getSnapshotSet( ).remove( "verbose" );
+ final AccountFullName ownerFullName = ( ctx.hasAdministrativePrivileges( ) && showAll ) ?
+ null :
+ AccountFullName.getInstance( ctx.getAccount( ) );
+ final Filter filter = Filters.generate( request.getFilterSet(), Snapshot.class );
+ final EntityTransaction db = Entities.get( Snapshot.class );
try {
- List<Snapshot> snapshots = Entities.query( Snapshot.named( ownerFullName, null ) );
- for ( Snapshot snap : Iterables.filter( snapshots, RestrictedTypes.filterPrivileged( ) ) ) {
- if ( request.getSnapshotSet( ).isEmpty( ) || request.getSnapshotSet( ).contains( snap.getDisplayName( ) ) ) {
- try {
- edu.ucsb.eucalyptus.msgs.Snapshot snapReply = snap.morph( new edu.ucsb.eucalyptus.msgs.Snapshot( ) );
- snapReply.setVolumeId( snap.getParentVolume( ) );
- snapReply.setOwnerId( snap.getOwnerAccountNumber( ) );
- reply.getSnapshotSet( ).add( snapReply );
- } catch ( NoSuchElementException e ) {
- LOG.warn( "Error getting snapshot information from the Storage Controller: " + e );
- LOG.debug( e, e );
- }
+ final List<Snapshot> snapshots = Entities.query( Snapshot.named( ownerFullName, null ), true, filter.asCriterion(), filter.getAliases() );
+ final Predicate<? super Snapshot> requestedAndAccessible = CloudMetadatas.filteringFor(Snapshot.class)
+ .byId( request.getSnapshotSet() )
+ .byPredicate( filter.asPredicate() )
+ .byPrivileges()
+ .buildPredicate();
+ for ( final Snapshot snap : Iterables.filter( snapshots, requestedAndAccessible ) ) {
+ try {
+ final edu.ucsb.eucalyptus.msgs.Snapshot snapReply = snap.morph( new edu.ucsb.eucalyptus.msgs.Snapshot( ) );
+ snapReply.setVolumeId( snap.getParentVolume( ) );
+ snapReply.setOwnerId( snap.getOwnerAccountNumber( ) );
+ reply.getSnapshotSet( ).add( snapReply );
+ } catch ( NoSuchElementException e ) {
+ LOG.warn( "Error getting snapshot information from the Storage Controller: " + e );
+ LOG.debug( e, e );
}
}
- db.rollback( );
- } catch ( Exception e ) {
+ } finally {
db.rollback( );
}
return reply;
View
125 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotTag.java
@@ -0,0 +1,125 @@
+/*************************************************************************
+ * Copyright 2009-2012 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
+ * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
+ * additional information or have any questions.
+ ************************************************************************/
+package com.eucalyptus.blockstorage;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Table;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Entity;
+import com.eucalyptus.cloud.CloudMetadata;
+import com.eucalyptus.entities.Entities;
+import com.eucalyptus.entities.TransactionException;
+import com.eucalyptus.tags.Tag;
+import com.eucalyptus.tags.TagSupport;
+import com.eucalyptus.tags.Tags;
+import com.eucalyptus.util.OwnerFullName;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ */
+@Entity
+@javax.persistence.Entity
+@PersistenceContext( name = "eucalyptus_cloud" )
+@Table( name = "metadata_tags_snapshots" )
+@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
+@DiscriminatorValue( "snapshot" )
+public class SnapshotTag extends Tag<SnapshotTag> {
+ private static final long serialVersionUID = 1L;
+
+ @JoinColumn( name = "metadata_tag_resource_id", updatable = false, nullable = false )
+ @ManyToOne( fetch = FetchType.LAZY )
+ private Snapshot snapshot;
+
+ protected SnapshotTag() {
+ super( "snapshot", ResourceIdFunction.INSTANCE );
+ }
+
+ public SnapshotTag( @Nonnull final Snapshot snapshot,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ super( "snapshot", ResourceIdFunction.INSTANCE, ownerFullName, key, value );
+ setSnapshot( snapshot );
+ }
+
+ public Snapshot getSnapshot() {
+ return snapshot;
+ }
+
+ public void setSnapshot( final Snapshot snapshot ) {
+ this.snapshot = snapshot;
+ }
+
+ @Nonnull
+ public static Tag named( @Nonnull final Snapshot snapshot,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key ) {
+ return namedWithValue( snapshot, ownerFullName, key, null );
+ }
+
+ @Nonnull
+ public static Tag namedWithValue( @Nonnull final Snapshot snapshot,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ Preconditions.checkNotNull( snapshot, "snapshot" );
+ Preconditions.checkNotNull( ownerFullName, "ownerFullName" );
+ return new SnapshotTag( snapshot, ownerFullName, key, value );
+ }
+
+ private enum ResourceIdFunction implements Function<SnapshotTag,String> {
+ INSTANCE {
+ @Override
+ public String apply( final SnapshotTag snapshotTag ) {
+ return snapshotTag.getSnapshot().getDisplayName();
+ }
+ }
+ }
+
+ public static final class SnapshotTagSupport extends TagSupport {
+ public SnapshotTagSupport() {
+ super( SnapshotMetadata.class, "snap" );
+ }
+
+ @Override
+ public Tag createOrUpdate( final CloudMetadata metadata, final OwnerFullName ownerFullName, final String key, final String value ) {
+ return Tags.createOrUpdate( new SnapshotTag( (Snapshot) metadata, ownerFullName, key, value ) );
+ }
+
+ @Override
+ public Tag example( @Nonnull final CloudMetadata metadata, @Nonnull final OwnerFullName ownerFullName, final String key, final String value ) {
+ return SnapshotTag.namedWithValue( (Snapshot) metadata, ownerFullName, key, value );
+ }
+
+ @Override
+ public CloudMetadata lookup( final String identifier ) throws TransactionException {
+ return Entities.uniqueResult( Snapshot.named( null, identifier ) );
+ }
+ }
+}
View
82 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshots.java
@@ -64,6 +64,7 @@
import static java.util.Collections.unmodifiableSet;
import static java.util.EnumSet.of;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
@@ -78,6 +79,7 @@
import com.eucalyptus.auth.principal.UserFullName;
import com.eucalyptus.bootstrap.Hosts;
import com.eucalyptus.cloud.CloudMetadata.SnapshotMetadata;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.cloud.util.DuplicateMetadataException;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
@@ -93,6 +95,7 @@
import com.eucalyptus.event.Listeners;
import com.eucalyptus.records.Logs;
import com.eucalyptus.system.Threads;
+import com.eucalyptus.tags.FilterSupport;
import com.eucalyptus.util.Callback;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
@@ -302,4 +305,83 @@ public static Snapshot lookup( OwnerFullName accountFullName, String snapshotId
return Transactions.findAll( Snapshot.named( null, null ) );
}
+ public static class SnapshotFilterSupport extends FilterSupport<Snapshot> {
+ public SnapshotFilterSupport() {
+ super( builderFor( Snapshot.class )
+ .withTagFiltering( SnapshotTag.class, "snapshot" )
+ .withStringProperty( "description", FilterFunctions.DESCRIPTION )
+ .withStringProperty( "owner-alias", FilterFunctions.ACCOUNT_NAME ) //TODO:STEVE: won't work, this field isn't populated
+ .withStringProperty( "owner-id", FilterFunctions.ACCOUNT_ID )
+ .withStringProperty( "progress", FilterFunctions.PROGRESS )
+ .withStringProperty( "snapshot-id", CloudMetadatas.toDisplayName() )
+ .withStringProperty( "status", FilterFunctions.STATUS )
+ .withDateProperty( "start-time", FilterDateFunctions.START_TIME )
+ .withStringProperty( "volume-id", FilterFunctions.VOLUME_ID )
+ .withStringProperty( "volume-size", FilterFunctions.VOLUME_SIZE )
+ .withPersistenceFilter( "description" )
+ .withPersistenceFilter( "owner-alias", "ownerAccountName" ) //TODO:STEVE: won't work, this field isn't populated
+ .withPersistenceFilter( "owner-id", "ownerAccountNumber" )
+ //.withPersistenceFilter( "progress" ) //TODO:STEVE: Not working, problem with % escaping?
+ .withPersistenceFilter( "snapshot-id", "displayName" )
+ //.withPersistenceFilter( "start-time", "creationTimestamp", PersistenceFilter.Type.Date ) //TODO:STEVE: Not working, fails to match due to dropped millis? (lost by timestamps parser)
+ .withPersistenceFilter( "volume-id", "parentVolume" )
+ .withPersistenceFilter( "volume-size", "volumeSize", PersistenceFilter.Type.Integer )
+ );
+ }
+ }
+
+ private enum FilterFunctions implements Function<Snapshot,String> {
+ DESCRIPTION {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.getDescription();
+ }
+ },
+ ACCOUNT_NAME {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.getOwnerAccountName();
+ }
+ },
+ ACCOUNT_ID {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.getOwnerAccountNumber();
+ }
+ },
+ PROGRESS {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.getProgress();
+ }
+ },
+ STATUS {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.mapState();
+ }
+ },
+ VOLUME_ID {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ return snapshot.getParentVolume();
+ }
+ },
+ VOLUME_SIZE {
+ @Override
+ public String apply( final Snapshot snapshot ) {
+ Integer size = snapshot.getVolumeSize();
+ return size == null ? null : String.valueOf( size );
+ }
+ }
+ }
+
+ private enum FilterDateFunctions implements Function<Snapshot,Date> {
+ START_TIME {
+ @Override
+ public Date apply( final Snapshot snapshot ) {
+ return snapshot.getCreationTimestamp();
+ }
+ }
+ }
}
View
10 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volume.java
@@ -62,9 +62,13 @@
package com.eucalyptus.blockstorage;
+import java.util.Collection;
import java.util.Date;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
+import javax.persistence.FetchType;
import javax.persistence.Lob;
+import javax.persistence.OneToMany;
import javax.persistence.PersistenceContext;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -105,8 +109,10 @@
private String localDevice;
@Transient
private FullName fullName;
-
- private Volume( ) {
+ @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "volume" )
+ private Collection<VolumeTag> tags;
+
+ protected Volume( ) {
super( );
}
View
35 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeManager.java
@@ -62,6 +62,7 @@
package com.eucalyptus.blockstorage;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -69,6 +70,7 @@
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.auth.principal.AccountFullName;
import com.eucalyptus.auth.principal.UserFullName;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.cluster.Cluster;
import com.eucalyptus.cluster.Clusters;
import com.eucalyptus.cluster.Nodes;
@@ -90,6 +92,8 @@
import com.eucalyptus.records.EventType;
import com.eucalyptus.records.Logs;
import com.eucalyptus.reporting.event.VolumeEvent;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.RestrictedTypes;
@@ -99,7 +103,9 @@
import com.eucalyptus.vm.VmInstances;
import com.eucalyptus.vm.VmVolumeAttachment;
import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import edu.ucsb.eucalyptus.msgs.AttachStorageVolumeResponseType;
@@ -249,34 +255,29 @@ public Volume apply( final String input ) {
public DescribeVolumesResponseType DescribeVolumes( DescribeVolumesType request ) throws Exception {
final DescribeVolumesResponseType reply = ( DescribeVolumesResponseType ) request.getReply( );
final Context ctx = Contexts.lookup( );
+
final boolean showAll = request.getVolumeSet( ).remove( "verbose" );
final AccountFullName ownerFullName = ( ctx.hasAdministrativePrivileges( ) && showAll ) ? null : ctx.getUserFullName( ).asAccountFullName( );
final Set<String> volumeIds = Sets.newHashSet( );
if ( !request.getVolumeSet( ).isEmpty( ) ) {
volumeIds.addAll( request.getVolumeSet( ) );
}
+ final Filter filter = Filters.generate( request.getFilterSet(), Volume.class );
+ final Predicate<? super Volume> requestedAndAccessible = CloudMetadatas.filteringFor( Volume.class )
+ .byId(volumeIds )
+ .byPredicate( filter.asPredicate() )
+ .byPrivileges()
+ .buildPredicate();
+
final Function<Set<String>, Set<String>> lookupVolumeIds = new Function<Set<String>, Set<String>>( ) {
public Set<String> apply( final Set<String> input ) {
- Set<String> res = Sets.newHashSet( );
- if ( input.isEmpty( ) ) {
- for ( Volume foundVol : Collections2.filter( Entities.query( Volume.named( ownerFullName, null ) ), RestrictedTypes.filterPrivileged( ) ) ) {
+ final List<Volume> volumes = Entities.query( Volume.named( ownerFullName, null ), true, filter.asCriterion(), filter.getAliases() );
+ Set<String> res = Sets.newHashSet( );
+ for ( final Volume foundVol : Iterables.filter(volumes, requestedAndAccessible )) {
res.add( foundVol.getDisplayName( ) );
}
- } else {
- for ( String s : input ) {
- try {
- Volume foundVol = Entities.uniqueResult( Volume.named( ownerFullName, s ) );
- if ( RestrictedTypes.filterPrivileged( ).apply( foundVol ) ) {
- res.add( foundVol.getDisplayName( ) );
- }
- } catch ( NoSuchElementException ex ) {
- } catch ( TransactionException ex ) {
- throw Exceptions.toUndeclared( ex );
- }
- }
+ return res;
}
- return res;
- }
};
Set<String> allowedVolumeIds = Entities.asTransaction( Volume.class, lookupVolumeIds ).apply( volumeIds );
final Function<String, Volume> lookupVolume = new Function<String, Volume>( ) {
View
125 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeTag.java
@@ -0,0 +1,125 @@
+/*************************************************************************
+ * Copyright 2009-2012 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
+ * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
+ * additional information or have any questions.
+ ************************************************************************/
+package com.eucalyptus.blockstorage;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Table;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Entity;
+import com.eucalyptus.cloud.CloudMetadata;
+import com.eucalyptus.entities.Entities;
+import com.eucalyptus.entities.TransactionException;
+import com.eucalyptus.tags.Tag;
+import com.eucalyptus.tags.TagSupport;
+import com.eucalyptus.tags.Tags;
+import com.eucalyptus.util.OwnerFullName;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ */
+@Entity
+@javax.persistence.Entity
+@PersistenceContext( name = "eucalyptus_cloud" )
+@Table( name = "metadata_tags_volumes" )
+@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
+@DiscriminatorValue( "volume" )
+public class VolumeTag extends Tag<VolumeTag> {
+ private static final long serialVersionUID = 1L;
+
+ @JoinColumn( name = "metadata_tag_resource_id", updatable = false, nullable = false )
+ @ManyToOne( fetch = FetchType.LAZY )
+ private Volume volume;
+
+ protected VolumeTag() {
+ super( "volume", ResourceIdFunction.INSTANCE );
+ }
+
+ public VolumeTag( @Nonnull final Volume volume,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ super( "volume", ResourceIdFunction.INSTANCE, ownerFullName, key, value );
+ setVolume( volume );
+ }
+
+ public Volume getVolume() {
+ return volume;
+ }
+
+ public void setVolume( final Volume volume ) {
+ this.volume = volume;
+ }
+
+ @Nonnull
+ public static Tag named( @Nonnull final Volume volume,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key ) {
+ return namedWithValue( volume, ownerFullName, key, null );
+ }
+
+ @Nonnull
+ public static Tag namedWithValue( @Nonnull final Volume volume,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ Preconditions.checkNotNull( volume, "volume" );
+ Preconditions.checkNotNull( ownerFullName, "ownerFullName" );
+ return new VolumeTag( volume, ownerFullName, key, value );
+ }
+
+ private enum ResourceIdFunction implements Function<VolumeTag,String> {
+ INSTANCE {
+ @Override
+ public String apply( final VolumeTag volumeTag ) {
+ return volumeTag.getVolume().getDisplayName();
+ }
+ }
+ }
+
+ public static final class VolumeTagSupport extends TagSupport {
+ public VolumeTagSupport() {
+ super( VolumeMetadata.class, "vol" );
+ }
+
+ @Override
+ public Tag createOrUpdate( final CloudMetadata metadata, final OwnerFullName ownerFullName, final String key, final String value ) {
+ return Tags.createOrUpdate( new VolumeTag( (Volume) metadata, ownerFullName, key, value ) );
+ }
+
+ @Override
+ public Tag example( @Nonnull final CloudMetadata metadata, @Nonnull final OwnerFullName ownerFullName, final String key, final String value ) {
+ return VolumeTag.namedWithValue( (Volume) metadata, ownerFullName, key, value );
+ }
+
+ @Override
+ public CloudMetadata lookup( final String identifier ) throws TransactionException {
+ return Entities.uniqueResult( Volume.named( null, identifier ) );
+ }
+ }
+}
View
119 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volumes.java
@@ -70,6 +70,7 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Date;
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Example;
@@ -103,6 +104,7 @@
import com.eucalyptus.util.async.AsyncRequests;
import com.eucalyptus.vm.VmInstances;
import com.eucalyptus.vm.VmVolumeAttachment;
+import com.eucalyptus.tags.FilterSupport;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
@@ -452,5 +454,122 @@ static void fireUsageEvent( final Volume volume,
LOG.error(e, e);
}
}
+
+ public static class VolumeFilterSupport extends FilterSupport<Volume>{
+ public VolumeFilterSupport(){
+ super( builderFor(Volume.class)
+ .withTagFiltering( VolumeTag.class, "volume" )
+ .withDateProperty("attachment.attach-time", FilterDateFunctions.ATTACHMENT_ATTACH_TIME)
+ .withBooleanProperty("attachment.delete-on-termination", FilterBooleanFunctions.ATTACHMENT_DELETE_ON_TERMINATION)
+ .withStringProperty("attachment.device", FilterStringFunctions.ATTACHMENT_DEVICE)
+ .withStringProperty("attachment.instance-id", FilterStringFunctions.ATTACHMENT_INSTANCE_ID)
+ .withStringProperty("attachment.status", FilterStringFunctions.ATTACHMENT_STATUS)
+ .withStringProperty("availability-zone", FilterStringFunctions.AVAILABILITY_ZONE)
+ .withDateProperty("create-time", FilterDateFunctions.CREATE_TIME)
+ .withStringProperty("size", FilterStringFunctions.SIZE)
+ .withStringProperty("snapshot-id", FilterStringFunctions.SNAPSHOT_ID)
+ .withStringProperty("status", FilterStringFunctions.STATUS)
+ .withStringProperty("volume-id", FilterStringFunctions.VOLUME_ID)
+ .withConstantProperty("volume-type", "standard")
+ .withPersistenceFilter( "availability-zone", "partition" )
+ //.withPersistenceFilter( "create-time", "creationTimestamp", PersistenceFilter.Type.Date ) //TODO:STEVE: Not working, fails to match due to dropped millis? (lost by timestamps parser)
+ .withPersistenceFilter( "size", "size", PersistenceFilter.Type.Integer )
+ .withPersistenceFilter( "snapshot-id", "parentSnapshot" )
+ .withPersistenceFilter( "volume-id", "displayName" ) );
+ }
+ }
+
+ private enum FilterStringFunctions implements Function<Volume,String> {
+ ATTACHMENT_DEVICE {
+ @Override
+ public String apply(final Volume vol){
+ return vol.getLocalDevice();
+ }
+ },
+ ATTACHMENT_INSTANCE_ID {
+ @Override
+ public String apply(final Volume vol){
+ try{
+ VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment( vol.getDisplayName() );
+ return attachment.getVmInstance().getInstanceId();
+ }catch (final Throwable e) {
+ return null;
+ }
+ }
+ },
+ ATTACHMENT_STATUS {
+ @Override
+ public String apply(final Volume vol){
+ try{
+ VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment(vol.getDisplayName());
+ return attachment.getStatus();
+ }catch (final Throwable e){
+ return null;
+ }
+ }
+ },
+ AVAILABILITY_ZONE {
+ @Override
+ public String apply(final Volume vol){
+ return vol.getPartition();
+ }
+ },
+ SIZE {
+ @Override
+ public String apply(final Volume vol){
+ return vol.getSize().toString();
+ }
+ },
+ SNAPSHOT_ID {
+ @Override
+ public String apply(final Volume vol){
+ return vol.getParentSnapshot();
+ }
+ },
+ STATUS {
+ @Override
+ public String apply(final Volume vol){
+ return vol.mapState();
+ }
+ },
+ VOLUME_ID {
+ @Override
+ public String apply (final Volume vol){
+ return vol.getDisplayName();
+ }
+ },
+ }
+ private enum FilterDateFunctions implements Function<Volume, Date>{
+ ATTACHMENT_ATTACH_TIME {
+ @Override
+ public Date apply(final Volume vol){
+ try{
+ VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment(vol.getDisplayName());
+ return attachment.getAttachTime();
+ }catch(final Throwable e){
+ return null;
+ }
+ }
+ },
+ CREATE_TIME {
+ @Override
+ public Date apply(final Volume vol){
+ return vol.getCreationTimestamp();
+ }
+ }
+ }
+ private enum FilterBooleanFunctions implements Function<Volume, Boolean> {
+ ATTACHMENT_DELETE_ON_TERMINATION {
+ @Override
+ public Boolean apply(final Volume vol){
+ try{
+ VmVolumeAttachment attachment = VmInstances.lookupVolumeAttachment(vol.getDisplayName());
+ return attachment.getDeleteOnTerminate();
+ }catch (final Throwable e){
+ return false;
+ }
+ }
+ }
+ }
}
View
4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/AccountMetadata.java
@@ -68,7 +68,6 @@
import javax.persistence.Transient;
import com.eucalyptus.auth.principal.AccountFullName;
import com.eucalyptus.auth.principal.Principals;
-import com.eucalyptus.cloud.CloudMetadata.KeyPairMetadata;
import com.eucalyptus.entities.AbstractStatefulPersistent;
import com.eucalyptus.util.HasFullName;
import com.eucalyptus.util.OwnerFullName;
@@ -151,6 +150,7 @@ protected void setOwner( OwnerFullName owner ) {
: null );
}
+ @Override
public String getOwnerAccountName( ) {
return this.ownerAccountName;
}
@@ -177,7 +177,7 @@ private void generateOnCommit( ) {
this.uniqueName = createUniqueName( );
}
- private String createUniqueName( ) {
+ protected String createUniqueName( ) {
return ( this.ownerAccountNumber != null && this.getDisplayName( ) != null )
? this.ownerAccountNumber + ":" + this.getDisplayName( )
: null;
View
22 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Cluster.java
@@ -153,13 +153,9 @@
import com.eucalyptus.ws.WebServicesException;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.ObjectArrays;
-import com.google.common.collect.Table;
-import com.google.common.collect.Tables;
import edu.ucsb.eucalyptus.cloud.NodeInfo;
import edu.ucsb.eucalyptus.msgs.BaseMessage;
import edu.ucsb.eucalyptus.msgs.NodeCertInfo;
@@ -542,11 +538,21 @@ public void fire( final Cluster t ) {
LOG.debug( "Clearing error logs for: " + t );
t.clearExceptions( );
}
- };
- };
-
+ }
+ }
+
+ /**
+ * Constructor for test use
+ */
+ protected Cluster( final ClusterConfiguration configuration, final Void nothing ) {
+ this.configuration = configuration;
+ this.state = null;
+ this.nodeState = null;
+ this.nodeMap = null;
+ this.stateMachine = null;
+ }
+
public Cluster( final ClusterConfiguration configuration ) {
- super( );
this.configuration = configuration;
this.state = new ClusterState( configuration.getName( ) );
this.nodeState = new ResourceState( configuration.getName( ) );
View
125 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/ClusterEndpoint.java
@@ -64,7 +64,6 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -74,6 +73,7 @@
import org.apache.log4j.Logger;
import org.mule.api.MuleException;
import org.mule.api.lifecycle.Startable;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.cluster.ResourceState.VmTypeAvailability;
import com.eucalyptus.component.Component;
import com.eucalyptus.component.ComponentId;
@@ -83,11 +83,15 @@
import com.eucalyptus.component.id.Eucalyptus;
import com.eucalyptus.component.id.Walrus;
import com.eucalyptus.context.Contexts;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.FilterSupport;
+import com.eucalyptus.tags.Filters;
+import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.vm.VmType;
import com.eucalyptus.vm.VmTypes;
import com.google.common.base.Function;
-import com.google.common.base.Objects;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -126,10 +130,11 @@ public void start( ) throws MuleException {
Clusters.getInstance( );
}
- public DescribeAvailabilityZonesResponseType DescribeAvailabilityZones( DescribeAvailabilityZonesType request ) {
- DescribeAvailabilityZonesResponseType reply = ( DescribeAvailabilityZonesResponseType ) request.getReply( );
- List<String> args = request.getAvailabilityZoneSet( );
-
+ public DescribeAvailabilityZonesResponseType DescribeAvailabilityZones( DescribeAvailabilityZonesType request ) throws EucalyptusCloudException {
+ final DescribeAvailabilityZonesResponseType reply = ( DescribeAvailabilityZonesResponseType ) request.getReply( );
+ final List<String> args = request.getAvailabilityZoneSet( );
+ final Filter filter = Filters.generate( request.getFilterSet(), Cluster.class );
+
if ( Contexts.lookup( ).hasAdministrativePrivileges( ) ) {
for ( String keyword : describeKeywords.keySet( ) ) {
if ( args.remove( keyword ) ) {
@@ -142,33 +147,36 @@ public DescribeAvailabilityZonesResponseType DescribeAvailabilityZones( Describe
args.remove( keyword );
}
}
-
+
+ final List<Cluster> clusters;
if ( args.isEmpty( ) ) {
- for ( Cluster c : Clusters.getInstance( ).listValues( ) ) {
- reply.getAvailabilityZoneInfo( ).addAll( this.getDescriptionEntry( c, args ) );
- }
+ clusters = Clusters.getInstance( ).listValues( );
} else {
+ clusters = Lists.newArrayList();
for ( final String partitionName : request.getAvailabilityZoneSet( ) ) {
try {
- Cluster c = Iterables.find( Clusters.getInstance( ).listValues( ), new Predicate<Cluster>( ) {
+ clusters.add( Iterables.find( Clusters.getInstance( ).listValues( ), new Predicate<Cluster>( ) {
@Override
public boolean apply( Cluster input ) {
return partitionName.equals( input.getConfiguration( ).getPartition( ) );
}
- } );
- reply.getAvailabilityZoneInfo( ).addAll( this.getDescriptionEntry( c, args ) );
+ } ) );
} catch ( NoSuchElementException e ) {
try {
- Cluster c = Clusters.getInstance( ).lookup( partitionName );
- reply.getAvailabilityZoneInfo( ).addAll( this.getDescriptionEntry( c, args ) );
+ clusters.add( Clusters.getInstance( ).lookup( partitionName ) );
} catch ( NoSuchElementException ex ) {}
}
}
}
+
+ for ( final Cluster c : Iterables.filter( clusters, filter.asPredicate() ) ) {
+ reply.getAvailabilityZoneInfo( ).addAll( this.getDescriptionEntry( c ) );
+ }
+
return reply;
}
- private List<ClusterInfoType> getDescriptionEntry( Cluster c, List<String> args ) {
+ private List<ClusterInfoType> getDescriptionEntry( Cluster c ) {
List<ClusterInfoType> ret = Lists.newArrayList( );
String clusterName = c.getName( );
ret.add( new ClusterInfoType( c.getConfiguration( ).getPartition( ), c.getConfiguration( ).getHostName( ) + " "
@@ -282,18 +290,24 @@ private static ClusterInfoType s( String left, String right ) {
}
};
- public DescribeRegionsResponseType DescribeRegions( final DescribeRegionsType request ) {//TODO:GRZE:URGENT fix the behaviour here.
+ public DescribeRegionsResponseType DescribeRegions( final DescribeRegionsType request ) throws EucalyptusCloudException {//TODO:GRZE:URGENT fix the behaviour here.
final DescribeRegionsResponseType reply = ( DescribeRegionsResponseType ) request.getReply( );
- final Collection<String> regions = Objects.firstNonNull(request.getRegions(), Collections.<String>emptyList());
for ( final Class<? extends ComponentId> componentIdClass : ImmutableList.of(Eucalyptus.class, Walrus.class) ) {
try {
final Component component = Components.lookup( componentIdClass );
- final String region = component.getComponentId( ).name();
- if ( regions.isEmpty() || regions.contains( region ) ) {
- final NavigableSet<ServiceConfiguration> configs = component.services( );
- if ( !configs.isEmpty( ) && Component.State.ENABLED.equals( configs.first( ).lookupState( ) ) ) {
- reply.getRegionInfo( ).add( new RegionInfoType( region, ServiceUris.remotePublicify( configs.first( ) ).toASCIIString( ) ) );
- }
+ final String region = component.getComponentId( ).name();
+ final List<Region> regions = Lists.newArrayList();
+ final NavigableSet<ServiceConfiguration> configs = component.services( );
+ if ( !configs.isEmpty( ) && Component.State.ENABLED.equals( configs.first( ).lookupState( ) ) ) {
+ regions.add( new Region( region, ServiceUris.remotePublicify( configs.first() ).toASCIIString() ) );
+ }
+
+ final Filter filter = Filters.generate( request.getFilterSet(), Region.class );
+ final Predicate<Object> requested = Predicates.and(
+ filterByName( request.getRegions() ),
+ filter.asPredicate() );
+ for ( final Region item : Iterables.filter( regions, requested ) ) {
+ reply.getRegionInfo( ).add( new RegionInfoType( item.getDisplayName(), item.getEndpointUrl() ) );
}
} catch ( NoSuchElementException ex ) {
LOG.error( ex, ex );
@@ -301,4 +315,67 @@ public DescribeRegionsResponseType DescribeRegions( final DescribeRegionsType re
}
return reply;
}
+
+ /**
+ * This should be Predicate<Region> but JDK6 can't handle the resulting Predicate<? super Region>
+ */
+ private static Predicate<Object> filterByName( final Collection<String> requestedIdentifiers ) {
+ return new Predicate<Object>( ) {
+ @Override
+ public boolean apply( Object region ) {
+ return requestedIdentifiers == null || requestedIdentifiers.isEmpty( ) || requestedIdentifiers.contains( ((Region)region).getDisplayName() );
+ }
+ };
+ }
+
+ protected static class Region {
+ private final String displayName;
+ private final String endpointUrl;
+
+ protected Region( final String displayName, final String endpointUrl ) {
+ this.displayName = displayName;
+ this.endpointUrl = endpointUrl;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getEndpointUrl() {
+ return endpointUrl;
+ }
+ }
+
+ private enum RegionFunctions implements Function<Region,String> {
+ REGION_NAME {
+ @Override
+ public String apply( final Region region ) {
+ return region.getDisplayName();
+ }
+ },
+ ENDPOINT_URL {
+ @Override
+ public String apply( final Region region ) {
+ return region.getEndpointUrl();
+ }
+ }
+ }
+
+ public static class RegionFilterSupport extends FilterSupport<Region> {
+ public RegionFilterSupport() {
+ super( builderFor( Region.class )
+ .withStringProperty( "endpoint", RegionFunctions.ENDPOINT_URL )
+ .withStringProperty( "region-name", RegionFunctions.REGION_NAME ) );
+ }
+ }
+
+ public static class AvailabilityZoneFilterSupport extends FilterSupport<Cluster> {
+ public AvailabilityZoneFilterSupport() {
+ super( builderFor( Cluster.class )
+ .withUnsupportedProperty( "message" )
+ .withUnsupportedProperty( "region-name" )
+ .withUnsupportedProperty( "state" )
+ .withStringProperty( "zone-name", CloudMetadatas.toDisplayName() ) );
+ }
+ }
}
View
7 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageInfo.java
@@ -64,6 +64,7 @@
import static com.eucalyptus.util.Parameters.checkParam;
import static org.hamcrest.Matchers.notNullValue;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -78,6 +79,7 @@
import javax.persistence.EntityTransaction;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
@@ -165,7 +167,10 @@
@Column( name = "metadata_image_size_bytes", nullable = false )
private Long imageSizeBytes;
-
+
+ @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "image" )
+ private Collection<ImageInfoTag> tags;
+
@Transient
private FullName fullName;
View
127 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageInfoTag.java
@@ -0,0 +1,127 @@
+/*************************************************************************
+ * Copyright 2009-2012 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
+ * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
+ * additional information or have any questions.
+ ************************************************************************/
+package com.eucalyptus.images;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Table;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Entity;
+import com.eucalyptus.cloud.CloudMetadata;
+import com.eucalyptus.cloud.ImageMetadata;
+import com.eucalyptus.entities.Entities;
+import com.eucalyptus.entities.TransactionException;
+import com.eucalyptus.tags.Tag;
+import com.eucalyptus.tags.TagSupport;
+import com.eucalyptus.tags.Tags;
+import com.eucalyptus.util.OwnerFullName;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+/**
+ *
+ */
+@Entity
+@javax.persistence.Entity
+@PersistenceContext( name = "eucalyptus_cloud" )
+@Table( name = "metadata_tags_images" )
+@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
+@DiscriminatorValue( "image" )
+public class ImageInfoTag extends Tag<ImageInfoTag> {
+ private static final long serialVersionUID = 1L;
+
+ @JoinColumn( name = "metadata_tag_resource_id", updatable = false, nullable = false )
+ @ManyToOne( fetch = FetchType.LAZY )
+ private ImageInfo image;
+
+ protected ImageInfoTag() {
+ super( "image", ResourceIdFunction.INSTANCE );
+ }
+
+ public ImageInfoTag( @Nonnull final ImageInfo image,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ super( "image", ResourceIdFunction.INSTANCE, ownerFullName, key, value );
+ setImage( image );
+ }
+
+ public ImageInfo getImage() {
+ return image;
+ }
+
+ public void setImage(final ImageInfo image) {
+ this.image = image;
+ }
+
+ @Nonnull
+ public static Tag named( @Nonnull final ImageInfo image,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key ) {
+ return namedWithValue( image, ownerFullName, key, null );
+ }
+
+ @Nonnull
+ public static Tag namedWithValue( @Nonnull final ImageInfo image,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ Preconditions.checkNotNull( image, "image" );
+ Preconditions.checkNotNull( ownerFullName, "ownerFullName" );
+ return new ImageInfoTag( image, ownerFullName, key, value );
+ }
+
+ private enum ResourceIdFunction implements Function<ImageInfoTag,String> {
+ INSTANCE {
+ @Override
+ public String apply( final ImageInfoTag imageInfoTag ) {
+ return imageInfoTag.getImage().getDisplayName();
+ }
+ }
+ }
+
+ public static final class ImageInfoTagSupport extends TagSupport {
+ public ImageInfoTagSupport() {
+ super( ImageMetadata.class, Sets.newHashSet( "emi", "eri", "eki" ) );
+ }
+
+ @Override
+ public Tag createOrUpdate( final CloudMetadata metadata, final OwnerFullName ownerFullName, final String key, final String value ) {
+ return Tags.createOrUpdate( new ImageInfoTag( (ImageInfo) metadata, ownerFullName, key, value ) );
+ }
+
+ @Override
+ public Tag example( @Nonnull final CloudMetadata metadata, @Nonnull final OwnerFullName ownerFullName, final String key, final String value ) {
+ return ImageInfoTag.namedWithValue( (ImageInfo) metadata, ownerFullName, key, value );
+ }
+
+ @Override
+ public CloudMetadata lookup( final String identifier ) throws TransactionException {
+ return Entities.uniqueResult( ImageInfo.named( identifier ) );
+ }
+ }
+}
View
24 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageManager.java
@@ -93,13 +93,14 @@
import com.eucalyptus.entities.Transactions;
import com.eucalyptus.images.ImageManifests.ImageManifest;
import com.eucalyptus.records.Logs;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.RestrictedTypes;
import com.eucalyptus.vm.VmInstance;
import com.eucalyptus.vm.VmInstance.VmState;
import com.eucalyptus.vm.VmInstances;
-import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
@@ -138,12 +139,21 @@ public DescribeImagesResponseType describe( final DescribeImagesType request ) t
if ( ownersSet.remove( Images.SELF ) ) {
ownersSet.add( requestAccountId );
}
- Predicate<ImageInfo> rangeFilter = Predicates.and( CloudMetadatas.filterById( request.getImagesSet( ) ),
- CloudMetadatas.filterByOwningAccount( request.getOwnersSet( ) ),
- Images.filterExecutableBy( request.getExecutableBySet( ) ) );
- Predicate<ImageInfo> privilegesFilter = Predicates.and( Images.FilterPermissions.INSTANCE, RestrictedTypes.filterPrivilegedWithoutOwner( ) );
- Predicate<ImageInfo> filter = Predicates.and( privilegesFilter, rangeFilter );
- List<ImageDetails> imageDetailsList = Transactions.filteredTransform( new ImageInfo( ), filter, Images.TO_IMAGE_DETAILS );
+ final Filter filter = Filters.generate( request.getFilterSet(), ImageInfo.class );
+ final Predicate<? super ImageInfo> requestedAndAccessible = CloudMetadatas.filteringFor( ImageInfo.class )
+ .byId( request.getImagesSet() )
+ .byOwningAccount( request.getOwnersSet() )
+ .byPredicate( Images.filterExecutableBy( request.getExecutableBySet() ) )
+ .byPredicate( filter.asPredicate() )
+ .byPredicate( Images.FilterPermissions.INSTANCE )
+ .byPrivilegesWithoutOwner()
+ .buildPredicate();
+ final List<ImageDetails> imageDetailsList = Transactions.filteredTransform(
+ new ImageInfo(),
+ filter.asCriterion(),
+ filter.getAliases(),
+ requestedAndAccessible,
+ Images.TO_IMAGE_DETAILS );
reply.getImagesSet( ).addAll( imageDetailsList );
ImageUtil.cleanDeregistered( );
return reply;
View
9 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/Images.java
@@ -84,6 +84,7 @@
import com.eucalyptus.entities.TransactionExecutionException;
import com.eucalyptus.entities.Transactions;
import com.eucalyptus.images.ImageManifests.ImageManifest;
+import com.eucalyptus.tags.FilterSupport;
import com.eucalyptus.util.Callback;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.OwnerFullName;
@@ -656,5 +657,11 @@ public static String lookupDefaultKernelId( ) {
public static String lookupDefaultRamdiskId( ) {
return ImageConfiguration.getInstance( ).getDefaultRamdiskId( );
}
-
+
+ public static class ImageInfoFilterSupport extends FilterSupport<ImageInfo> {
+ public ImageInfoFilterSupport() {
+ super( builderFor( ImageInfo.class )
+ .withTagFiltering( ImageInfoTag.class, "image" ) );
+ }
+ }
}
View
23 clc/modules/cluster-manager/src/main/java/com/eucalyptus/keys/KeyPairManager.java
@@ -76,6 +76,7 @@
import org.apache.log4j.Logger;
import org.bouncycastle.openssl.PEMWriter;
import com.eucalyptus.auth.AuthException;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.context.IllegalContextAccessException;
@@ -83,7 +84,10 @@
import com.eucalyptus.crypto.util.B64;
import com.eucalyptus.entities.TransactionException;
import com.eucalyptus.entities.Transactions;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.EucalyptusCloudException;
+import com.eucalyptus.util.OwnerFullName;
import com.eucalyptus.util.RestrictedTypes;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
@@ -104,13 +108,18 @@
private static Logger LOG = Logger.getLogger( KeyPairManager.class );
public DescribeKeyPairsResponseType describe( DescribeKeyPairsType request ) throws Exception {
- DescribeKeyPairsResponseType reply = request.getReply( );
- Context ctx = Contexts.lookup( );
- boolean showAll = request.getKeySet( ).remove( "verbose" );
- for ( SshKeyPair kp : Iterables.filter( KeyPairs.list( ( ctx.hasAdministrativePrivileges( ) && showAll ) ? null : Contexts.lookup( ).getUserFullName( ).asAccountFullName( ) ), RestrictedTypes.filterPrivileged( ) ) ) {
- if ( request.getKeySet( ).isEmpty( ) || request.getKeySet( ).contains( kp.getDisplayName( ) ) ) {
- reply.getKeySet( ).add( new DescribeKeyPairsResponseItemType( kp.getDisplayName( ), kp.getFingerPrint( ) ) );
- }
+ final DescribeKeyPairsResponseType reply = request.getReply( );
+ final Context ctx = Contexts.lookup( );
+ final boolean showAll = request.getKeySet( ).remove( "verbose" );
+ final OwnerFullName ownerFullName = ctx.hasAdministrativePrivileges( ) && showAll ? null : Contexts.lookup( ).getUserFullName( ).asAccountFullName( );
+ final Filter filter = Filters.generate( request.getFilterSet(), SshKeyPair.class );
+ final Predicate<? super SshKeyPair> requestedAndAccessible = CloudMetadatas.filteringFor( SshKeyPair.class )
+ .byId( request.getKeySet( ) )
+ .byPredicate( filter.asPredicate() )
+ .byPrivileges()
+ .buildPredicate();
+ for ( final SshKeyPair kp : KeyPairs.list( ownerFullName, requestedAndAccessible, filter.asCriterion(), filter.getAliases() ) ) {
+ reply.getKeySet( ).add( new DescribeKeyPairsResponseItemType( kp.getDisplayName( ), kp.getFingerPrint( ) ) );
}
return reply;
}
View
46 clc/modules/cluster-manager/src/main/java/com/eucalyptus/keys/KeyPairs.java
@@ -73,10 +73,13 @@
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.List;
+import java.util.Map;
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
+import org.hibernate.criterion.Criterion;
import org.hibernate.exception.ConstraintViolationException;
import com.eucalyptus.auth.principal.UserFullName;
+import com.eucalyptus.cloud.CloudMetadatas;
import com.eucalyptus.cloud.util.DuplicateMetadataException;
import com.eucalyptus.cloud.util.MetadataCreationException;
import com.eucalyptus.cloud.util.MetadataException;
@@ -88,7 +91,10 @@
import com.eucalyptus.entities.TransactionException;
import com.eucalyptus.entities.Transactions;
import com.eucalyptus.records.Logs;
+import com.eucalyptus.tags.FilterSupport;
import com.eucalyptus.util.OwnerFullName;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import com.google.common.primitives.Ints;
public class KeyPairs {
@@ -108,6 +114,27 @@ public static SshKeyPair noKey( ) {
}
}
+ /**
+ * List key pairs for the given owner.
+ *
+ * @param ownerFullName The key pair owner
+ * @param filter Predicate to restrict the results
+ * @param criterion The database criterion to restrict the results
+ * @param aliases Aliases for the database criterion
+ * @return The list of key pairs.
+ * @throws NoSuchMetadataException If an error occurs
+ */
+ public static List<SshKeyPair> list( final OwnerFullName ownerFullName,
+ final Predicate<? super SshKeyPair> filter,
+ final Criterion criterion,
+ final Map<String,String> aliases ) throws NoSuchMetadataException {
+ try {
+ return Transactions.filter( SshKeyPair.named( ownerFullName, null ), filter, criterion, aliases );
+ } catch ( Exception e ) {
+ throw new NoSuchMetadataException( "Failed to find key pairs for " + ownerFullName, e );
+ }
+ }
+
public static SshKeyPair lookup( OwnerFullName ownerFullName, String keyName ) throws NoSuchMetadataException {
try {
return Transactions.find( new SshKeyPair( ownerFullName, keyName ) );
@@ -275,4 +302,23 @@ private static BigInteger intFromBytes( byte[] data, int index, int length ) {
System.arraycopy( data, index, intBytes, 0, length );
return new BigInteger( intBytes );
}
+
+ public static class KeyPairFilterSupport extends FilterSupport<SshKeyPair> {
+ public KeyPairFilterSupport() {
+ super( builderFor( SshKeyPair.class )
+ .withStringProperty( "fingerprint", FilterFunctions.FINGERPRINT )
+ .withStringProperty( "key-name", CloudMetadatas.toDisplayName() )
+ .withPersistenceFilter( "fingerprint", "fingerPrint" )
+ .withPersistenceFilter( "key-name", "displayName" ) );
+ }
+ }
+
+ private enum FilterFunctions implements Function<SshKeyPair,String> {
+ FINGERPRINT {
+ @Override
+ public String apply( final SshKeyPair keyPair ) {
+ return keyPair.getFingerPrint();
+ }
+ }
+ }
}
View
29 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroup.java
@@ -64,6 +64,7 @@
import static com.eucalyptus.util.Parameters.checkParam;
import static org.hamcrest.Matchers.notNullValue;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
@@ -89,6 +90,7 @@
import com.eucalyptus.cloud.util.NotEnoughResourcesException;
import com.eucalyptus.component.ComponentIds;
import com.eucalyptus.component.id.Eucalyptus;
+import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.TransientEntityException;
import com.eucalyptus.util.FullName;
@@ -115,6 +117,9 @@
ACTIVE
}
+ @Column( name = "metadata_network_group_id")
+ private String groupId;
+
@Column( name = "metadata_network_group_description" )
private String description;
@@ -128,7 +133,10 @@
@JoinColumn( name = "vm_network_index", nullable = true, insertable = true, updatable = true )
@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
private ExtantNetwork extantNetwork;
-
+
+ @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy = "networkGroup" )
+ private Collection<NetworkGroupTag> tags;
+
NetworkGroup( ) {}
NetworkGroup( final OwnerFullName ownerFullName ) {
@@ -143,6 +151,7 @@
this( ownerFullName, groupName );
checkParam( groupDescription, notNullValue() );
this.description = groupDescription;
+ this.groupId = Crypto.generateId( Integer.toHexString(groupName.hashCode()), "sg" );
}
public static NetworkGroup named( final OwnerFullName ownerFullName, final String groupName ) {
@@ -153,6 +162,10 @@ public static NetworkGroup withNaturalId( final String naturalId ) {
return new NetworkGroup( naturalId );
}
+ public static NetworkGroup withGroupId( final OwnerFullName ownerFullName, final String groupId ) {
+ return networkGroupWithGroupId(ownerFullName, groupId);
+ }
+
/**
* @param naturalId
*/
@@ -160,6 +173,12 @@ private NetworkGroup( final String naturalId ) {
this.setNaturalId( naturalId );
}
+ private static NetworkGroup networkGroupWithGroupId( final OwnerFullName ownerFullName, final String groupId ) {
+ NetworkGroup findGroupWithId = new NetworkGroup(ownerFullName);
+ findGroupWithId.setGroupId(groupId);
+ return findGroupWithId;
+ }
+
@PreRemove
private void preRemove( ) {
if ( this.extantNetwork != null && this.extantNetwork.teardown( ) ) {
@@ -181,6 +200,10 @@ public String getDescription( ) {
return this.description;
}
+ public String getGroupId( ) {
+ return this.groupId;
+ }
+
protected void setDescription( final String description ) {
this.description = description;
}
@@ -189,6 +212,10 @@ protected void setDescription( final String description ) {
return this.networkRules;
}
+ private void setGroupId( final String groupId ){
+ this.groupId = groupId;
+ }
+
private void setNetworkRules( final Set<NetworkRule> networkRules ) {
this.networkRules = networkRules;
}
View
148 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupManager.java
@@ -62,23 +62,30 @@
package com.eucalyptus.network;
+import java.util.ArrayList;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
import com.eucalyptus.auth.principal.AccountFullName;
+import com.eucalyptus.cloud.CloudMetadatas;
+import com.eucalyptus.cloud.CloudMetadatas.FilterBuilder;
import com.eucalyptus.cloud.util.MetadataException;
+import com.eucalyptus.cloud.util.NoSuchMetadataException;
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.records.Logs;
+import com.eucalyptus.tags.Filter;
+import com.eucalyptus.tags.Filters;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.OwnerFullName;
import com.eucalyptus.util.RestrictedTypes;
import com.eucalyptus.util.TypeMappers;
+import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
@@ -116,7 +123,8 @@ public NetworkGroup get( ) {
}
}
};
- RestrictedTypes.allocateUnitlessResource( allocator );
+ final NetworkGroup group = RestrictedTypes.allocateUnitlessResource( allocator );
+ reply.setGroupId( group.getGroupId() );
return reply;
} catch ( final Exception ex ) {
throw new EucalyptusCloudException( "CreateSecurityGroup failed because: " + Exceptions.causeString( ex ), ex );
@@ -126,49 +134,73 @@ public NetworkGroup get( ) {
public DeleteSecurityGroupResponseType delete( final DeleteSecurityGroupType request ) throws EucalyptusCloudException, MetadataException {
final Context ctx = Contexts.lookup( );
final DeleteSecurityGroupResponseType reply = ( DeleteSecurityGroupResponseType ) request.getReply( );
- if ( !RestrictedTypes.filterPrivileged( ).apply( NetworkGroups.lookup( ctx.getUserFullName( ).asAccountFullName( ), request.getGroupName( ) ) ) ) {
- throw new EucalyptusCloudException( "Not authorized to delete network group " + request.getGroupName( ) + " for " + ctx.getUser( ) );
+
+ String lookUpGroup = request.getGroupName() != null ? request.getGroupName() : request.getGroupId();
+ AccountFullName lookUpGroupAccount = ctx.getUserFullName( ).asAccountFullName( );
+
+ NetworkGroup group;
+ try {
+ group = NetworkGroups.lookup( lookUpGroupAccount , lookUpGroup );
+ } catch (MetadataException ex ) {
+ try {
+ group = NetworkGroups.lookupByGroupId(lookUpGroupAccount, lookUpGroup);
+ } catch ( NoSuchMetadataException ex1 ) {
+ throw ex1;
+ }
+ }
+
+ if ( !RestrictedTypes.filterPrivileged( ).apply(group) ) {
+ throw new EucalyptusCloudException( "Not authorized to delete network group " + group.getDisplayName() + " for " + ctx.getUser( ) );
}
- NetworkGroups.delete( ctx.getUserFullName( ), request.getGroupName( ) );
+ NetworkGroups.delete( ctx.getUserFullName( ), group.getDisplayName());
reply.set_return( true );
return reply;
}
+ private enum GetGroupId implements Function<NetworkGroup, String> {
+ EXTRACT_GROUP_ID;
+
+ public String apply(NetworkGroup networkGroup) {
+ return networkGroup.getGroupId();
+ }
+ }
+
public DescribeSecurityGroupsResponseType describe( final DescribeSecurityGroupsType request ) throws EucalyptusCloudException, MetadataException {
- final DescribeSecurityGroupsResponseType reply = request.getReply( );
- final Context ctx = Contexts.lookup( );
- boolean showAll = request.getSecurityGroupSet( ).remove( "verbose" );
- NetworkGroups.createDefault( ctx.getUserFullName( ) );//ensure the default group exists to cover some old broken installs
-
- final List<String> groupNames = request.getSecurityGroupSet( );
- final Predicate<NetworkGroup> argListFilter = new Predicate<NetworkGroup>( ) {
- @Override
- public boolean apply( final NetworkGroup arg0 ) {
- return groupNames.isEmpty( ) || groupNames.contains( arg0.getDisplayName( ) );
+ final DescribeSecurityGroupsResponseType reply = request.getReply( );
+ final Context ctx = Contexts.lookup( );
+ boolean showAll = request.getSecurityGroupSet( ).remove( "verbose" );
+ NetworkGroups.createDefault( ctx.getUserFullName( ) );//ensure the default group exists to cover some old broken installs
+
+ final List<String> groupNames = request.getSecurityGroupSet( );
+ final Predicate<NetworkGroup> argListFilter = new Predicate<NetworkGroup>( ) {
+ @Override
+ public boolean apply( final NetworkGroup arg0 ) {
+ return groupNames.isEmpty( ) || groupNames.contains( arg0.getDisplayName( ) ) || groupNames.contains(arg0.getGroupId( ) );
+
+ }
+ };
+
+ Predicate<NetworkGroup> netFilter = Predicates.and( argListFilter, RestrictedTypes.filterPrivileged( ) );
+ OwnerFullName ownerFn = AccountFullName.getInstance( ctx.getAccount( ) );
+ if ( Contexts.lookup( ).hasAdministrativePrivileges( ) ) {
+ if ( showAll ) {
+ ownerFn = null;
+ }
+ netFilter = argListFilter;
}
- };
-
- Predicate<NetworkGroup> netFilter = Predicates.and( argListFilter, RestrictedTypes.filterPrivileged( ) );
- OwnerFullName ownerFn = AccountFullName.getInstance( ctx.getAccount( ) );
- if ( Contexts.lookup( ).hasAdministrativePrivileges( ) ) {
- if ( showAll ) {
- ownerFn = null;
+
+ final EntityTransaction db = Entities.get( NetworkGroup.class );
+ try {
+ final List<NetworkGroup> networks = Entities.query( NetworkGroup.named( ownerFn, null ) );
+ final Iterable<NetworkGroup> matches = Iterables.filter( networks, netFilter );
+ final Iterable<SecurityGroupItemType> transformed = Iterables.transform( matches, TypeMappers.lookup( NetworkGroup.class, SecurityGroupItemType.class ) );
+ Iterables.addAll( reply.getSecurityGroupInfo( ), transformed );
+ db.commit( );
+ } catch ( final Exception ex ) {
+ db.rollback( );
}
- netFilter = argListFilter;
- }
-
- final EntityTransaction db = Entities.get( NetworkGroup.class );
- try {
- final List<NetworkGroup> networks = Entities.query( NetworkGroup.named( ownerFn, null ) );
- final Iterable<NetworkGroup> matches = Iterables.filter( networks, netFilter );
- final Iterable<SecurityGroupItemType> transformed = Iterables.transform( matches, TypeMappers.lookup( NetworkGroup.class, SecurityGroupItemType.class ) );
- Iterables.addAll( reply.getSecurityGroupInfo( ), transformed );
- db.commit( );
- } catch ( final Exception ex ) {
- db.rollback( );
- }
-
- return reply;
+
+ return reply;
}
public RevokeSecurityGroupIngressResponseType revoke( final RevokeSecurityGroupIngressType request ) throws EucalyptusCloudException, MetadataException {
@@ -181,12 +213,26 @@ public RevokeSecurityGroupIngressResponseType revoke( final RevokeSecurityGroupI
EntityTransaction db = Entities.get( NetworkGroup.class );
- try {
-
- final List<NetworkGroup> networkGroupList = NetworkGroups
+ try {
+ String lookUpGroup = request.getGroupName() != null ? request.getGroupName() : request.getGroupId();
+ AccountFullName lookUpGroupAccount = ctx.getUserFullName( ).asAccountFullName( );
+ String groupName;
+
+ try {
+ groupName = NetworkGroups.lookup( lookUpGroupAccount , lookUpGroup ).getDisplayName();
+ } catch (MetadataException ex ) {
+ try {
+ groupName = NetworkGroups.lookupByGroupId(lookUpGroupAccount, lookUpGroup).getDisplayName();
+ } catch ( NoSuchMetadataException ex1 ) {
+ throw ex1;
+ }
+ }
+
+ final List<NetworkGroup> networkGroupList = NetworkGroups
.lookupAll(ctx.getUserFullName().asAccountFullName(),
- request.getGroupName());
-
+ groupName);
+
+
for (NetworkGroup networkGroup : networkGroupList) {
if (RestrictedTypes.filterPrivileged().apply(networkGroup)) {
@@ -223,9 +269,23 @@ public AuthorizeSecurityGroupIngressResponseType authorize( final AuthorizeSecur
EntityTransaction db = Entities.get( NetworkGroup.class );
try {
- final NetworkGroup ruleGroup = NetworkGroups.lookup( ctx.getUserFullName( ).asAccountFullName( ), request.getGroupName( ) );
+
+ String lookUpGroup = request.getGroupName() != null ? request.getGroupName() : request.getGroupId();
+ AccountFullName lookUpGroupAccount = ctx.getUserFullName( ).asAccountFullName( );
+ NetworkGroup ruleGroup;
+
+ try {
+ ruleGroup = NetworkGroups.lookup( lookUpGroupAccount , lookUpGroup );
+ } catch (MetadataException ex ) {
+ try {
+ ruleGroup = NetworkGroups.lookupByGroupId(lookUpGroupAccount, lookUpGroup);
+ } catch ( NoSuchMetadataException ex1 ) {
+ throw ex1;
+ }
+ }
+
if ( !RestrictedTypes.filterPrivileged( ).apply( ruleGroup ) ) {
- throw new EucalyptusCloudException( "Not authorized to authorize network group " + request.getGroupName( ) + " for " + ctx.getUser( ) );
+ throw new EucalyptusCloudException( "Not authorized to authorize network group " + ruleGroup.getDisplayName() + " for " + ctx.getUser( ) );
}
final List<NetworkRule> ruleList = Lists.newArrayList( );
for ( final IpPermissionType ipPerm : request.getIpPermissions( ) ) {
View
125 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupTag.java
@@ -0,0 +1,125 @@
+/*************************************************************************
+ * Copyright 2009-2012 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
+ * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
+ * additional information or have any questions.
+ ************************************************************************/
+package com.eucalyptus.network;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Table;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Entity;
+import com.eucalyptus.cloud.CloudMetadata;
+import com.eucalyptus.entities.Entities;
+import com.eucalyptus.entities.TransactionException;
+import com.eucalyptus.tags.Tag;
+import com.eucalyptus.tags.TagSupport;
+import com.eucalyptus.tags.Tags;
+import com.eucalyptus.util.OwnerFullName;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ */
+@Entity
+@javax.persistence.Entity
+@PersistenceContext( name = "eucalyptus_cloud" )
+@Table( name = "metadata_tags_network_groups" )
+@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
+@DiscriminatorValue( "securitygroup" )
+public class NetworkGroupTag extends Tag<NetworkGroupTag> {
+ private static final long serialVersionUID = 1L;
+
+ @JoinColumn( name = "metadata_tag_resource_id", updatable = false, nullable = false )
+ @ManyToOne( fetch = FetchType.LAZY )
+ private NetworkGroup networkGroup;
+
+ protected NetworkGroupTag() {
+ super( "securitygroup", ResourceIdFunction.INSTANCE );
+ }
+
+ public NetworkGroupTag( @Nonnull final NetworkGroup networkGroup,
+ @Nonnull final OwnerFullName ownerFullName,
+ @Nullable final String key,
+ @Nullable final String value ) {
+ super( "securitygroup", ResourceIdFunction.INSTANCE, ownerFullName, key, value );
+ setNetworkGroup( networkGroup );
+ }
+
+ public NetworkGroup getNetworkGroup() {
+ return networkGroup;
+ }
+
+ public void setNetworkGroup( f