1
1
/*******************************************************************************
2
*Copyright (c) 2009 Eucalyptus Systems, Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, only version 3 of the License.
9
* This file is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Please contact Eucalyptus Systems, Inc., 130 Castilian
18
* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
* if you need additional information or have any questions.
21
* This file may incorporate work covered under the following copyright and
24
* Software License Agreement (BSD License)
26
* Copyright (c) 2008, Regents of the University of California
27
* All rights reserved.
29
* Redistribution and use of this software in source and binary forms, with
30
* or without modification, are permitted provided that the following
33
* Redistributions of source code must retain the above copyright notice,
34
* this list of conditions and the following disclaimer.
36
* Redistributions in binary form must reproduce the above copyright
37
* notice, this list of conditions and the following disclaimer in the
38
* documentation and/or other materials provided with the distribution.
40
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
41
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
42
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
44
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
47
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
48
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
49
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
51
* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
52
* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
53
* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
* THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
* ANY SUCH LICENSES OR RIGHTS.
60
*******************************************************************************/
2
*Copyright (c) 2009 Eucalyptus Systems, Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, only version 3 of the License.
9
* This file is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Please contact Eucalyptus Systems, Inc., 130 Castilian
18
* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
* if you need additional information or have any questions.
21
* This file may incorporate work covered under the following copyright and
24
* Software License Agreement (BSD License)
26
* Copyright (c) 2008, Regents of the University of California
27
* All rights reserved.
29
* Redistribution and use of this software in source and binary forms, with
30
* or without modification, are permitted provided that the following
33
* Redistributions of source code must retain the above copyright notice,
34
* this list of conditions and the following disclaimer.
36
* Redistributions in binary form must reproduce the above copyright
37
* notice, this list of conditions and the following disclaimer in the
38
* documentation and/or other materials provided with the distribution.
40
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
41
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
42
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
44
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
47
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
48
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
49
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
51
* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
52
* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
53
* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
* THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
* ANY SUCH LICENSES OR RIGHTS.
60
*******************************************************************************/
62
62
* Author: chris grzegorczyk <grze@eucalyptus.com>
65
65
package com.eucalyptus.images;
67
import java.security.Principal;
67
68
import java.util.ArrayList;
69
import java.util.HashSet;
68
70
import java.util.List;
69
72
import javax.persistence.CascadeType;
70
73
import javax.persistence.Column;
71
74
import javax.persistence.Entity;
75
import javax.persistence.FetchType;
72
76
import javax.persistence.GeneratedValue;
73
77
import javax.persistence.Id;
74
78
import javax.persistence.JoinColumn;
75
79
import javax.persistence.JoinTable;
76
80
import javax.persistence.Lob;
77
81
import javax.persistence.ManyToMany;
82
import javax.persistence.OneToMany;
78
83
import javax.persistence.PersistenceContext;
79
84
import javax.persistence.Table;
80
85
import javax.persistence.Transient;
86
import org.apache.log4j.Logger;
81
87
import org.hibernate.annotations.Cache;
82
88
import org.hibernate.annotations.CacheConcurrencyStrategy;
89
import com.eucalyptus.auth.Groups;
83
90
import com.eucalyptus.auth.NoSuchUserException;
84
91
import com.eucalyptus.auth.UserInfo;
85
92
import com.eucalyptus.auth.Users;
93
import com.eucalyptus.auth.principal.Group;
94
import com.eucalyptus.auth.principal.User;
86
95
import com.eucalyptus.entities.EntityWrapper;
87
96
import com.eucalyptus.util.EucalyptusCloudException;
97
import com.eucalyptus.util.JoinTx;
98
import com.eucalyptus.util.TransactionException;
99
import com.eucalyptus.util.Transactions;
100
import com.eucalyptus.util.Tx;
88
101
import com.google.common.base.Function;
89
102
import edu.ucsb.eucalyptus.msgs.ImageDetails;
92
@PersistenceContext(name="eucalyptus_general")
105
@PersistenceContext( name = "eucalyptus_general" )
93
106
@Table( name = "Images" )
94
@Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
107
@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
95
108
public class ImageInfo implements Image {
97
public static ImageInfo ALL = new ImageInfo();
110
private static Logger LOG = Logger.getLogger( ImageInfo.class );
112
public static ImageInfo ALL = new ImageInfo( );
100
115
@Column( name = "image_id" )
101
private Long id = -1l;
116
private Long id = -1l;
102
117
@Column( name = "image_name" )
103
private String imageId;
118
private String imageId;
104
119
@Column( name = "image_path" )
105
private String imageLocation;
120
private String imageLocation;
106
121
@Column( name = "image_availability" )
107
private String imageState;
122
private String imageState;
108
123
@Column( name = "image_owner_id" )
109
private String imageOwnerId;
124
private String imageOwnerId;
110
125
@Column( name = "image_arch" )
111
private String architecture;
126
private String architecture;
112
127
@Column( name = "image_type" )
113
private String imageType;
128
private String imageType;
114
129
@Column( name = "image_kernel_id" )
115
private String kernelId;
130
private String kernelId;
116
131
@Column( name = "image_ramdisk_id" )
117
private String ramdiskId;
132
private String ramdiskId;
118
133
@Column( name = "image_is_public" )
119
private Boolean imagePublic;
134
private Boolean imagePublic;
121
136
@Column( name = "image_signature" )
122
private String signature;
123
// @ManyToMany( cascade = CascadeType.PERSIST )
125
// name = "image_has_groups",
126
// joinColumns = { @JoinColumn( name = "image_id" ) },
127
// inverseJoinColumns = @JoinColumn( name = "user_group_id" )
129
// @Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
130
// private List<Group> userGroups = new ArrayList<Group>();
133
name = "image_has_perms",
134
joinColumns = { @JoinColumn( name = "image_id" ) },
135
inverseJoinColumns = @JoinColumn( name = "user_id" )
137
@Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
138
private List<UserInfo> permissions = new ArrayList<UserInfo>();
139
@ManyToMany( cascade = CascadeType.PERSIST )
141
name = "image_has_product_codes",
142
joinColumns = { @JoinColumn( name = "image_id" ) },
143
inverseJoinColumns = @JoinColumn( name = "image_product_code_id" )
145
@Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
146
private List<ProductCode> productCodes = new ArrayList<ProductCode>();
148
public static ImageInfo deregistered() {
149
ImageInfo img = new ImageInfo();
137
private String signature;
138
@Column( name = "image_platform" )
139
private String platform;
140
@OneToMany( cascade = CascadeType.ALL )
141
@JoinTable( name = "image_has_group_auth", joinColumns = { @JoinColumn( name = "image_id" ) }, inverseJoinColumns = @JoinColumn( name = "image_auth_id" ) )
142
@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
143
private Set<ImageAuthorization> userGroups = new HashSet<ImageAuthorization>( );
144
@OneToMany( cascade = CascadeType.ALL )
145
@JoinTable( name = "image_has_user_auth", joinColumns = { @JoinColumn( name = "image_id" ) }, inverseJoinColumns = @JoinColumn( name = "image_auth_id" ) )
146
@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
147
private Set<ImageAuthorization> permissions = new HashSet<ImageAuthorization>( );
148
@OneToMany( cascade = CascadeType.ALL )
149
@JoinTable( name = "image_has_product_codes", joinColumns = { @JoinColumn( name = "image_id" ) }, inverseJoinColumns = @JoinColumn( name = "image_product_code_id" ) )
150
@Cache( usage = CacheConcurrencyStrategy.TRANSACTIONAL )
151
private Set<ProductCode> productCodes = new HashSet<ProductCode>( );
153
public static ImageInfo deregistered( ) {
154
ImageInfo img = new ImageInfo( );
150
155
img.setImageState( "deregistered" );
154
159
public static ImageInfo byOwnerId( String ownerId ) {
155
ImageInfo img = new ImageInfo();
160
ImageInfo img = new ImageInfo( );
156
161
img.setImageOwnerId( ownerId );
160
public ImageInfo() {}
165
public ImageInfo( ) {}
162
167
public ImageInfo( final String imageId ) {
163
this.imageId = imageId.substring( 0, 4 ).toLowerCase( ) + imageId.substring( 4 ).toUpperCase();
168
this.imageId = imageId.substring( 0, 4 ).toLowerCase( ) + imageId.substring( 4 ).toUpperCase( );
166
171
public ImageInfo( final String imageLocation, final String imageOwnerId, final String imageState, final Boolean aPublic ) {
167
172
this.imageLocation = imageLocation;
168
173
this.imageOwnerId = imageOwnerId;
169
174
this.imageState = imageState;
170
175
this.imagePublic = aPublic;
173
public ImageInfo( String architecture, String imageId, String imageLocation, String imageOwnerId, String imageState, String imageType, Boolean aPublic, String kernelId, String ramdiskId ) {
178
public ImageInfo( String architecture, String imageId, String imageLocation, String imageOwnerId, String imageState, String imageType, Boolean aPublic,
179
String kernelId, String ramdiskId ) {
174
180
this.architecture = architecture;
175
181
this.imageId = imageId;
176
182
this.imageLocation = imageLocation;
345
351
public void setSignature( final String signature ) {
346
352
this.signature = signature;
349
// public List<UserGroupEntity> getUserGroups() {
350
// return userGroups;
353
// public void setUserGroups( final List<UserGroupEntity> userGroups ) {
354
// this.userGroups = userGroups;
357
public List<UserInfo> getPermissions() {
355
public Set<ImageAuthorization> getUserGroups( ) {
359
public void setUserGroups( final Set<ImageAuthorization> userGroups ) {
360
this.userGroups = userGroups;
363
public Set<ImageAuthorization> getPermissions( ) {
358
364
return permissions;
361
public void setPermissions( final List<UserInfo> permissions ) {
367
public void setPermissions( final Set<ImageAuthorization> permissions ) {
362
368
this.permissions = permissions;
371
public String getPlatform( ) {
372
return this.platform;
375
public void setPlatform( String platform ) {
376
this.platform = platform;
380
public ImageInfo grantPermission( final Principal prin ) {
382
ImageInfo search = new ImageInfo( );
383
search.setImageId( this.imageId );
384
Transactions.one( search, new JoinTx<ImageInfo>( ) {
386
public void fire( EntityWrapper<ImageInfo> db, ImageInfo t ) throws Throwable {
387
ImageAuthorization imgAuth = new ImageAuthorization( prin.getName( ) );
388
if( prin instanceof Group ) {
389
if ( !t.getUserGroups( ).contains( imgAuth ) ) {
390
db.recast( ImageAuthorization.class ).add( imgAuth );
391
t.getUserGroups( ).add( imgAuth );
393
} else if( prin instanceof User ) {
394
if ( !t.getPermissions( ).contains( imgAuth ) ) {
395
db.recast( ImageAuthorization.class ).add( imgAuth );
396
t.getPermissions( ).add( imgAuth );
399
if ( t.getUserGroups( ).contains( new ImageAuthorization( "all" ) ) ) {
400
t.setImagePublic( true );
404
} catch ( TransactionException e ) {
410
public boolean checkPermission( final Principal prin ) throws EucalyptusCloudException {
411
final boolean[] result = { false };
413
ImageInfo search = new ImageInfo( );
414
search.setImageId( this.imageId );
415
Transactions.one( search, new Tx<ImageInfo>( ) {
417
public void fire( ImageInfo t ) throws Throwable {
418
if( prin instanceof Group ) {
419
result[0] = t.getUserGroups( ).contains( new ImageAuthorization( prin.getName( ) ) );
420
} else if ( prin instanceof User ) {
421
result[0] = t.getPermissions( ).contains( new ImageAuthorization( prin.getName( ) ) );
425
} catch ( TransactionException e ) {
431
public ImageInfo revokePermission( final Principal prin ) {
433
ImageInfo search = new ImageInfo( );
434
search.setImageId( this.imageId );
435
Transactions.one( search, new Tx<ImageInfo>( ) {
437
public void fire( ImageInfo t ) throws Throwable {
438
ImageAuthorization imgAuth = new ImageAuthorization( prin.getName( ) );
439
if( prin instanceof Group ) {
440
t.getUserGroups( ).remove( imgAuth );
441
} else if( prin instanceof User ) {
442
t.getPermissions( ).remove( imgAuth );
444
if ( !t.getPermissions( ).contains( new ImageAuthorization( "all" ) ) ) {
445
t.setImagePublic( false );
449
} catch ( TransactionException e ) {
366
456
* @see com.eucalyptus.images.Image#getAsImageDetails()
369
public ImageDetails getAsImageDetails() {
370
ImageDetails i = new ImageDetails();
371
i.setArchitecture( this.getArchitecture() );
372
i.setImageId( this.getImageId() );
373
i.setImageLocation( this.getImageLocation() );
374
i.setImageOwnerId( this.getImageOwnerId() );
375
i.setImageState( this.getImageState() );
376
i.setImageType( this.getImageType() );
377
i.setIsPublic( this.getImagePublic() );
378
i.setKernelId( this.getKernelId() );
379
i.setRamdiskId( this.getRamdiskId() );
459
public ImageDetails getAsImageDetails( ) {
460
ImageDetails i = new ImageDetails( );
461
i.setArchitecture( this.getArchitecture( ) );
462
i.setImageId( this.getImageId( ) );
463
i.setImageLocation( this.getImageLocation( ) );
464
i.setImageOwnerId( this.getImageOwnerId( ) );
465
i.setImageState( this.getImageState( ) );
466
i.setImageType( this.getImageType( ) );
467
i.setIsPublic( this.getImagePublic( ) );
468
i.setKernelId( this.getKernelId( ) );
469
i.setRamdiskId( this.getRamdiskId( ) );
470
i.setPlatform( this.getPlatform( ) );
384
475
* @see com.eucalyptus.images.Image#getProductCodes()
387
public List<ProductCode> getProductCodes() {
478
public Set<ProductCode> getProductCodes( ) {
388
479
return productCodes;
392
483
* @see com.eucalyptus.images.Image#setProductCodes(java.util.List)
393
484
* @param productCodes
395
public void setProductCodes( final List<ProductCode> productCodes ) {
486
public void setProductCodes( final Set<ProductCode> productCodes ) {
396
487
this.productCodes = productCodes;
400
491
* @see com.eucalyptus.images.Image#equals(java.lang.Object)