/************************************************************************* * Copyright 2009-2016 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.compute.common.internal.vpc; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.PersistenceContext; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.hibernate.annotations.Type; import com.eucalyptus.auth.principal.FullName; import com.eucalyptus.auth.principal.OwnerFullName; import com.eucalyptus.auth.type.RestrictedType; import com.eucalyptus.component.ComponentIds; import com.eucalyptus.component.id.Eucalyptus; import com.eucalyptus.compute.common.CloudMetadata.NatGatewayMetadata; import com.eucalyptus.entities.UserMetadata; import com.eucalyptus.util.RestrictedTypes; import com.google.common.base.Function; /** * */ @Entity @PersistenceContext( name = "eucalyptus_cloud" ) @Table( name = "metadata_nat_gateways", indexes = { @Index( name = "metadata_nat_gateways_user_id_idx", columnList = "metadata_user_id" ), @Index( name = "metadata_nat_gateways_account_id_idx", columnList = "metadata_account_id" ), @Index( name = "metadata_nat_gateways_display_name_idx", columnList = "metadata_display_name" ), } ) public class NatGateway extends UserMetadata<NatGateway.State> implements NatGatewayMetadata { private static final long serialVersionUID = 1L; public enum State { pending, failed, available, deleting, deleted, ; } @Temporal( TemporalType.TIMESTAMP) @Column( name = "deletion_timestamp" ) private Date deletionTimestamp; @Column( name = "metadata_client_token", updatable = false ) private String clientToken; @Column( name = "metadata_client_token_unique", unique = true, updatable = false ) private String uniqueClientToken; @ManyToOne @JoinColumn( name = "metadata_vpc_id" ) private Vpc vpc; @Column( name = "metadata_vpc_name", nullable = false, updatable = false ) private String vpcId; @ManyToOne @JoinColumn( name = "metadata_subnet_id" ) private Subnet subnet; @Column( name = "metadata_subnet_name", nullable = false, updatable = false ) private String subnetId; @OneToOne( fetch = FetchType.LAZY ) @JoinColumn( name = "metadata_network_interface_id" ) private NetworkInterface networkInterface; @Column( name = "metadata_network_interface_name" ) private String networkInterfaceId; @Column( name = "metadata_failure_code" ) private String failureCode; @Column( name = "metadata_failure_message" ) @Lob @Type(type="org.hibernate.type.StringClobType") private String failureMessage; @Column( name = "metadata_allocation_id", nullable = false, updatable = false ) private String allocationId; @Column( name = "metadata_association_id" ) private String associationId; @Column( name = "metadata_mac_address" ) private String macAddress; @Column( name = "metadata_private_ip" ) private String privateIpAddress; @Column( name = "metadata_public_ip" ) private String publicIpAddress; protected NatGateway( ) { } public static NatGateway create( final OwnerFullName owner, final Vpc vpc, final Subnet subnet, final String displayName, final String clientToken, final String allocationId ) { final NatGateway natGateway = new NatGateway( ); natGateway.setOwner( owner ); natGateway.setDisplayName( displayName ); if ( clientToken != null ) { natGateway.setClientToken( clientToken ); natGateway.setUniqueClientToken( uniqueClientToken( owner, clientToken ) ); } natGateway.setVpc( vpc ); natGateway.setSubnet( subnet ); natGateway.setAllocationId( allocationId ); natGateway.setState( State.pending ); natGateway.updateTimeStamps( ); return natGateway; } public static NatGateway exampleWithOwner( final OwnerFullName owner ) { final NatGateway example = new NatGateway( ); example.setOwner( owner ); return example; } public static NatGateway exampleWithName( final OwnerFullName owner, final String name ) { final NatGateway example = exampleWithOwner( owner ); example.setDisplayName( name ); return example; } public static NatGateway exampleWithClientToken( final OwnerFullName owner, final String clientToken ) { final NatGateway example = new NatGateway( ); example.setUniqueClientToken( uniqueClientToken( owner, clientToken ) ); return example; } public static NatGateway exampleWithState( final State state ) { final NatGateway example = new NatGateway( ); example.setState( state ); example.setLastState( null ); example.setStateChangeStack( null ); return example; } public void attach( final NetworkInterface networkInterface ) { if ( getNetworkInterface( ) != null ) { throw new IllegalStateException( "Already attached" ); } setNetworkInterface( networkInterface ); setNetworkInterfaceId( RestrictedTypes.toDisplayName( ).apply( networkInterface ) ); if ( networkInterface.isAssociated( ) ) { associate( networkInterface.getAssociation( ).getPublicIp( ), networkInterface.getAssociation( ).getAssociationId( ) ); } setMacAddress( networkInterface.getMacAddress( ) ); setPrivateIpAddress( networkInterface.getPrivateIpAddress( ) ); } public void associate( final String publicIp, final String associationId ) { if ( getPublicIpAddress( ) != null ) { throw new IllegalStateException( "Already associated" ); } setPublicIpAddress( publicIp ); setAssociationId( associationId ); } @Override public String getPartition( ) { return "eucalyptus"; } @Override public FullName getFullName( ) { return FullName.create.vendor( "euca" ) .region( ComponentIds.lookup( Eucalyptus.class ).name( ) ) .namespace( getOwnerAccountNumber() ) .relativeId( "nat-gateway", getDisplayName( ) ); } public Vpc getVpc( ) { return vpc; } public void setVpc( final Vpc vpc ) { this.vpc = vpc; } public String getVpcId( ) { return vpcId; } public void setVpcId( final String vpcId ) { this.vpcId = vpcId; } public Subnet getSubnet( ) { return subnet; } public void setSubnet( final Subnet subnet ) { this.subnet = subnet; } public String getSubnetId( ) { return subnetId; } public void setSubnetId( final String subnetId ) { this.subnetId = subnetId; } public NetworkInterface getNetworkInterface( ) { return networkInterface; } public void setNetworkInterface( final NetworkInterface networkInterface ) { this.networkInterface = networkInterface; } public String getNetworkInterfaceId( ) { return networkInterfaceId; } public void setNetworkInterfaceId( final String networkInterfaceId ) { this.networkInterfaceId = networkInterfaceId; } public Date getDeletionTimestamp( ) { return deletionTimestamp; } public void setDeletionTimestamp( final Date deletionTimestamp ) { this.deletionTimestamp = deletionTimestamp; } public String getFailureCode( ) { return failureCode; } public void setFailureCode( final String failureCode ) { this.failureCode = failureCode; } public String getFailureMessage( ) { return failureMessage; } public void setFailureMessage( final String failureMessage ) { this.failureMessage = failureMessage; } public String getAllocationId( ) { return allocationId; } public void setAllocationId( final String allocationId ) { this.allocationId = allocationId; } public String getAssociationId( ) { return associationId; } public void setAssociationId( final String associationId ) { this.associationId = associationId; } public String getClientToken( ) { return clientToken; } public void setClientToken( final String clientToken ) { this.clientToken = clientToken; } public String getUniqueClientToken( ) { return uniqueClientToken; } public void setUniqueClientToken( final String uniqueClientToken ) { this.uniqueClientToken = uniqueClientToken; } public String getMacAddress( ) { return macAddress; } public void setMacAddress( final String macAddress ) { this.macAddress = macAddress; } public String getPrivateIpAddress( ) { return privateIpAddress; } public void setPrivateIpAddress( final String privateIpAddress ) { this.privateIpAddress = privateIpAddress; } public String getPublicIpAddress( ) { return publicIpAddress; } public void setPublicIpAddress( final String publicIpAddress ) { this.publicIpAddress = publicIpAddress; } public void markDeletion( ) { if ( getDeletionTimestamp( ) == null ) { setDeletionTimestamp( new Date( ) ); } } @Override protected String createUniqueName( ) { return getDisplayName( ); } @PrePersist @PreUpdate protected void updateReferences( ) { // not all reference updates will actually be persisted (as per field annotations) final Function<RestrictedType, String> nameTransform = RestrictedTypes.toDisplayName( ); setVpcId( nameTransform.apply( getVpc( ) ) ); setSubnetId( nameTransform.apply( getSubnet( ) ) ); final NetworkInterface networkInterface = getNetworkInterface( ); if ( networkInterface != null ) { setNetworkInterfaceId( nameTransform.apply( getNetworkInterface( ) ) ); } } private static String uniqueClientToken( final OwnerFullName owner, final String clientToken ) { return String.format( "%s:%s", owner.getAccountNumber( ), clientToken ); } }