mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' into vpc
Conflicts: server/src/com/cloud/api/ApiResponseHelper.java
This commit is contained in:
commit
766b7a2706
|
|
@ -33,6 +33,7 @@ import com.cloud.bridge.service.core.ec2.EC2CreateImage;
|
|||
import com.cloud.bridge.service.core.ec2.EC2CreateImageResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2CreateKeyPair;
|
||||
import com.cloud.bridge.service.core.ec2.EC2CreateVolume;
|
||||
import com.cloud.bridge.service.core.ec2.EC2Tags;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DeleteKeyPair;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeAddresses;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeAddressesResponse;
|
||||
|
|
@ -46,10 +47,13 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
|
|||
import com.cloud.bridge.service.core.ec2.EC2DescribeInstancesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairsResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2ResourceTag;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroupsResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeSnapshots;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeSnapshotsResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeTags;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeTagsResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeVolumes;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeVolumesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DisassociateAddress;
|
||||
|
|
@ -69,6 +73,8 @@ import com.cloud.bridge.service.core.ec2.EC2PasswordData;
|
|||
import com.cloud.bridge.service.core.ec2.EC2RebootInstances;
|
||||
import com.cloud.bridge.service.core.ec2.EC2RegisterImage;
|
||||
import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress;
|
||||
import com.cloud.bridge.service.core.ec2.EC2TagKeyValue;
|
||||
import com.cloud.bridge.service.core.ec2.EC2TagTypeId;
|
||||
import com.cloud.bridge.service.core.ec2.EC2RunInstances;
|
||||
import com.cloud.bridge.service.core.ec2.EC2RunInstancesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2SSHKeyPair;
|
||||
|
|
@ -79,6 +85,7 @@ import com.cloud.bridge.service.core.ec2.EC2StartInstances;
|
|||
import com.cloud.bridge.service.core.ec2.EC2StartInstancesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2StopInstances;
|
||||
import com.cloud.bridge.service.core.ec2.EC2StopInstancesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2TagsFilterSet;
|
||||
import com.cloud.bridge.service.core.ec2.EC2Volume;
|
||||
import com.cloud.bridge.service.core.ec2.EC2VolumeFilterSet;
|
||||
import com.cloud.bridge.service.exception.EC2ServiceException;
|
||||
|
|
@ -199,6 +206,89 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
return toCreateVolumeResponse( engine.createVolume( request ));
|
||||
}
|
||||
|
||||
public CreateTagsResponse createTags(CreateTags createTags) {
|
||||
EC2Tags request = new EC2Tags();
|
||||
CreateTagsType ctt = createTags.getCreateTags();
|
||||
|
||||
ResourceIdSetType resourceIds = ctt.getResourcesSet();
|
||||
ResourceTagSetType resourceTags = ctt.getTagSet();
|
||||
request = toResourceTypeAndIds(resourceIds);
|
||||
//add resource tag's to the request
|
||||
if (resourceTags != null) {
|
||||
ResourceTagSetItemType[] items = resourceTags.getItem();
|
||||
if (items != null) {
|
||||
for( int i=0; i < items.length; i++ ) {
|
||||
EC2TagKeyValue param1 = new EC2TagKeyValue();
|
||||
param1.setKey(items[i].getKey());
|
||||
param1.setValue(items[i].getValue());
|
||||
request.addResourceTag(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return toCreateTagsResponse( engine.modifyTags( request, "create"));
|
||||
}
|
||||
|
||||
public DeleteTagsResponse deleteTags(DeleteTags deleteTags) {
|
||||
EC2Tags request = new EC2Tags();
|
||||
DeleteTagsType dtt = deleteTags.getDeleteTags();
|
||||
|
||||
ResourceIdSetType resourceIds = dtt.getResourcesSet();
|
||||
DeleteTagsSetType resourceTags = dtt.getTagSet();
|
||||
request = toResourceTypeAndIds(resourceIds);
|
||||
//add resource tag's to the request
|
||||
if (resourceTags != null) {
|
||||
DeleteTagsSetItemType[] items = resourceTags.getItem();
|
||||
if (items != null) {
|
||||
for( int i=0; i < items.length; i++ ) {
|
||||
EC2TagKeyValue param1 = new EC2TagKeyValue();
|
||||
param1.setKey(items[i].getKey());
|
||||
if (items[i].getValue() != null)
|
||||
param1.setValue(items[i].getValue());
|
||||
request.addResourceTag(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return toDeleteTagsResponse( engine.modifyTags( request, "delete"));
|
||||
}
|
||||
|
||||
private EC2Tags toResourceTypeAndIds(ResourceIdSetType resourceIds) {
|
||||
EC2Tags request = new EC2Tags();
|
||||
//add resource-type and resource-id's to the request
|
||||
if (resourceIds != null) {
|
||||
ResourceIdSetItemType[] items = resourceIds.getItem();
|
||||
List<String> resourceTypeList = new ArrayList<String>();
|
||||
if (items != null) {
|
||||
for( int i=0; i < items.length; i++ ) {
|
||||
String resourceType = items[i].getResourceId().split(":")[0];
|
||||
if (resourceTypeList.isEmpty())
|
||||
resourceTypeList.add(resourceType);
|
||||
else {
|
||||
Boolean existsInList = false;
|
||||
for (String addedResourceType : resourceTypeList) {
|
||||
if (addedResourceType.equalsIgnoreCase(resourceType)) {
|
||||
existsInList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!existsInList)
|
||||
resourceTypeList.add(resourceType);
|
||||
}
|
||||
}
|
||||
for (String resourceType : resourceTypeList){
|
||||
EC2TagTypeId param1 = new EC2TagTypeId();
|
||||
param1.setResourceType(resourceType);
|
||||
for( int i=0; i < items.length; i++ ) {
|
||||
String[] resourceTag = items[i].getResourceId().split(":");
|
||||
if (resourceType.equals(resourceTag[0]))
|
||||
param1.addResourceId(resourceTag[1]);
|
||||
}
|
||||
request.addResourceType(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
public DeleteSecurityGroupResponse deleteSecurityGroup(DeleteSecurityGroup deleteSecurityGroup) {
|
||||
DeleteSecurityGroupType sgt = deleteSecurityGroup.getDeleteSecurityGroup();
|
||||
return toDeleteSecurityGroupResponse( engine.deleteSecurityGroup( sgt.getGroupName()));
|
||||
|
|
@ -323,11 +413,10 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
if (null != items) { // -> can be empty
|
||||
for( int i=0; i < items.length; i++ ) request.addInstanceId( items[i].getInstanceId());
|
||||
}
|
||||
|
||||
if (null != fst) {
|
||||
request.setFilterSet( toInstanceFilterSet( fst ));
|
||||
}
|
||||
|
||||
|
||||
if (null != fst)
|
||||
request = toInstanceFilterSet( request, fst );
|
||||
|
||||
return toDescribeInstancesResponse( engine.describeInstances( request ), engine );
|
||||
}
|
||||
|
||||
|
|
@ -428,13 +517,24 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
{
|
||||
String[] timeFilters = new String[1];
|
||||
timeFilters[0] = new String( "start-time" );
|
||||
request.setFilterSet( toSnapshotFilterSet( fst, timeFilters ));
|
||||
request = toSnapshotFilterSet( request, fst, timeFilters );
|
||||
}
|
||||
|
||||
return toDescribeSnapshotsResponse(engine.handleRequest(request));
|
||||
}
|
||||
|
||||
|
||||
public DescribeTagsResponse describeTags(DescribeTags decsribeTags) {
|
||||
EC2DescribeTags request = new EC2DescribeTags();
|
||||
DescribeTagsType dtt = decsribeTags.getDescribeTags();
|
||||
|
||||
FilterSetType fst = dtt.getFilterSet();
|
||||
|
||||
if (fst != null)
|
||||
request.setFilterSet( toTagsFilterSet( fst ));
|
||||
|
||||
return toDescribeTagsResponse(engine.describeTags(request));
|
||||
}
|
||||
|
||||
public DescribeVolumesResponse describeVolumes(DescribeVolumes describeVolumes)
|
||||
{
|
||||
EC2DescribeVolumes request = new EC2DescribeVolumes();
|
||||
|
|
@ -456,7 +556,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
String[] timeFilters = new String[2];
|
||||
timeFilters[0] = new String( "attachment.attach-time" );
|
||||
timeFilters[1] = new String( "create-time" );
|
||||
request.setFilterSet( toVolumeFilterSet( fst, timeFilters ));
|
||||
request = toVolumeFilterSet( request, fst, timeFilters );
|
||||
}
|
||||
|
||||
return toDescribeVolumesResponse( engine.handleRequest( request ));
|
||||
|
|
@ -855,7 +955,11 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
param7.addItem( param8 );
|
||||
|
||||
param3.setBlockDeviceMapping( param7 );
|
||||
param2.addItem( param3 );
|
||||
|
||||
EC2TagKeyValue[] tags = images[i].getResourceTags();
|
||||
param3.setTagSet(setResourceTags(tags));
|
||||
|
||||
param2.addItem( param3 );
|
||||
}
|
||||
|
||||
param1.setImagesSet( param2 );
|
||||
|
|
@ -940,8 +1044,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
return vfs;
|
||||
}
|
||||
|
||||
|
||||
private EC2VolumeFilterSet toVolumeFilterSet( FilterSetType fst, String[] timeStrs )
|
||||
private EC2DescribeVolumes toVolumeFilterSet( EC2DescribeVolumes request, FilterSetType fst, String[] timeStrs )
|
||||
{
|
||||
EC2VolumeFilterSet vfs = new EC2VolumeFilterSet();
|
||||
boolean timeFilter = false;
|
||||
|
|
@ -952,73 +1055,94 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
// -> each filter can have one or more values associated with it
|
||||
for( int j=0; j < items.length; j++ )
|
||||
{
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
String filterName = items[j].getName();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
// -> is the filter one of the xsd:dateTime filters?
|
||||
timeFilter = false;
|
||||
for( int m=0; m < timeStrs.length; m++ )
|
||||
{
|
||||
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
|
||||
if (timeFilter) break;
|
||||
}
|
||||
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
for( int k=0; k < valueItems.length; k++ )
|
||||
{
|
||||
// -> time values are not encoded as regexes
|
||||
if ( timeFilter )
|
||||
oneFilter.addValue( valueItems[k].getValue());
|
||||
else oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
}
|
||||
vfs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
return vfs;
|
||||
}
|
||||
String filterName = items[j].getName();
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
|
||||
|
||||
private EC2SnapshotFilterSet toSnapshotFilterSet( FilterSetType fst, String[] timeStrs )
|
||||
{
|
||||
EC2SnapshotFilterSet vfs = new EC2SnapshotFilterSet();
|
||||
if (filterName.startsWith("tag:")) {
|
||||
String key= filterName.split(":")[1];
|
||||
for (ValueType valueItem : valueItems) {
|
||||
EC2TagKeyValue tag = new EC2TagKeyValue();
|
||||
tag.setKey(key);
|
||||
tag.setValue(valueItem.getValue());
|
||||
request.addResourceTag(tag);
|
||||
}
|
||||
} else {
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
// -> is the filter one of the xsd:dateTime filters?
|
||||
timeFilter = false;
|
||||
for( int m=0; m < timeStrs.length; m++ ) {
|
||||
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
|
||||
if (timeFilter) break;
|
||||
}
|
||||
|
||||
for( int k=0; k < valueItems.length; k++ ) {
|
||||
// -> time values are not encoded as regexes
|
||||
if ( timeFilter )
|
||||
oneFilter.addValue( valueItems[k].getValue());
|
||||
else
|
||||
oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
}
|
||||
vfs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
request.setFilterSet(vfs);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
private EC2DescribeSnapshots toSnapshotFilterSet( EC2DescribeSnapshots request, FilterSetType fst, String[] timeStrs )
|
||||
{
|
||||
EC2SnapshotFilterSet sfs = new EC2SnapshotFilterSet();
|
||||
boolean timeFilter = false;
|
||||
|
||||
|
||||
FilterType[] items = fst.getItem();
|
||||
if (null != items)
|
||||
{
|
||||
// -> each filter can have one or more values associated with it
|
||||
for( int j=0; j < items.length; j++ )
|
||||
{
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
String filterName = items[j].getName();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
// -> is the filter one of the xsd:dateTime filters?
|
||||
timeFilter = false;
|
||||
for( int m=0; m < timeStrs.length; m++ )
|
||||
{
|
||||
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
|
||||
if (timeFilter) break;
|
||||
}
|
||||
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
for( int k=0; k < valueItems.length; k++ )
|
||||
{
|
||||
// -> time values are not encoded as regexes
|
||||
if ( timeFilter )
|
||||
oneFilter.addValue( valueItems[k].getValue());
|
||||
else oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
}
|
||||
vfs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
return vfs;
|
||||
}
|
||||
String filterName = items[j].getName();
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
|
||||
if (filterName.startsWith("tag:")) {
|
||||
String key= filterName.split(":")[1];
|
||||
for (ValueType valueItem : valueItems) {
|
||||
EC2TagKeyValue tag = new EC2TagKeyValue();
|
||||
tag.setKey(key);
|
||||
tag.setValue(valueItem.getValue());
|
||||
request.addResourceTag(tag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
// -> is the filter one of the xsd:dateTime filters?
|
||||
timeFilter = false;
|
||||
for( int m=0; m < timeStrs.length; m++ ) {
|
||||
timeFilter = filterName.equalsIgnoreCase( timeStrs[m] );
|
||||
if (timeFilter) break;
|
||||
}
|
||||
|
||||
for( int k=0; k < valueItems.length; k++ ) {
|
||||
// -> time values are not encoded as regexes
|
||||
if ( timeFilter )
|
||||
oneFilter.addValue( valueItems[k].getValue());
|
||||
else
|
||||
oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
}
|
||||
sfs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
request.setFilterSet(sfs);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
// TODO make these filter set functions use generics
|
||||
private EC2GroupFilterSet toGroupFilterSet( FilterSetType fst )
|
||||
{
|
||||
|
|
@ -1046,8 +1170,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
return gfs;
|
||||
}
|
||||
|
||||
|
||||
private EC2InstanceFilterSet toInstanceFilterSet( FilterSetType fst )
|
||||
private EC2DescribeInstances toInstanceFilterSet( EC2DescribeInstances request, FilterSetType fst )
|
||||
{
|
||||
EC2InstanceFilterSet ifs = new EC2InstanceFilterSet();
|
||||
|
||||
|
|
@ -1057,22 +1180,30 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
// -> each filter can have one or more values associated with it
|
||||
for( int j=0; j < items.length; j++ )
|
||||
{
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
String filterName = items[j].getName();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
for( int k=0; k < valueItems.length; k++ )
|
||||
{
|
||||
oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
}
|
||||
ifs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
return ifs;
|
||||
}
|
||||
String filterName = items[j].getName();
|
||||
ValueSetType vst = items[j].getValueSet();
|
||||
ValueType[] valueItems = vst.getItem();
|
||||
|
||||
if (filterName.startsWith("tag:")) {
|
||||
String key= filterName.split(":")[1];
|
||||
for (ValueType valueItem : valueItems) {
|
||||
EC2TagKeyValue tag = new EC2TagKeyValue();
|
||||
tag.setKey(key);
|
||||
tag.setValue(valueItem.getValue());
|
||||
request.addResourceTag(tag);
|
||||
}
|
||||
} else {
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
oneFilter.setName( filterName );
|
||||
for( int k=0; k < valueItems.length; k++ )
|
||||
oneFilter.addValueEncoded( valueItems[k].getValue());
|
||||
ifs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
request.setFilterSet(ifs);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
private EC2AvailabilityZonesFilterSet toAvailabiltyZonesFilterSet( FilterSetType fst ) {
|
||||
EC2AvailabilityZonesFilterSet azfs = new EC2AvailabilityZonesFilterSet();
|
||||
|
|
@ -1094,8 +1225,28 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
}
|
||||
return azfs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private EC2TagsFilterSet toTagsFilterSet( FilterSetType fst ) {
|
||||
EC2TagsFilterSet tfs = new EC2TagsFilterSet();
|
||||
|
||||
FilterType[] items = fst.getItem();
|
||||
if (items != null) {
|
||||
for (FilterType item : items) {
|
||||
EC2Filter oneFilter = new EC2Filter();
|
||||
String filterName = item.getName();
|
||||
oneFilter.setName( filterName );
|
||||
|
||||
ValueSetType vft = item.getValueSet();
|
||||
ValueType[] valueItems = vft.getItem();
|
||||
for (ValueType valueItem : valueItems) {
|
||||
oneFilter.addValueEncoded( valueItem.getValue());
|
||||
}
|
||||
tfs.addFilter( oneFilter );
|
||||
}
|
||||
}
|
||||
return tfs;
|
||||
}
|
||||
|
||||
// toMethods
|
||||
public static DescribeVolumesResponse toDescribeVolumesResponse( EC2DescribeVolumesResponse engineResponse )
|
||||
{
|
||||
|
|
@ -1142,14 +1293,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
}
|
||||
|
||||
param3.setAttachmentSet( param4 );
|
||||
|
||||
// -> try to generate an empty tag does not seem to work
|
||||
ResourceTagSetType param6 = new ResourceTagSetType();
|
||||
ResourceTagSetItemType param7 = new ResourceTagSetItemType();
|
||||
param7.setKey("");
|
||||
param7.setValue("");
|
||||
param6.addItem( param7 );
|
||||
param3.setTagSet( param6 );
|
||||
|
||||
EC2TagKeyValue[] tags = vol.getResourceTags();
|
||||
param3.setTagSet( setResourceTags(tags) );
|
||||
param2.addItem( param3 );
|
||||
}
|
||||
param1.setVolumeSet( param2 );
|
||||
|
|
@ -1277,6 +1423,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
param7.setSpotInstanceRequestId( "" );
|
||||
param7.setHypervisor(inst.getHypervisor());
|
||||
|
||||
EC2TagKeyValue[] tags = inst.getResourceTags();
|
||||
param7.setTagSet(setResourceTags(tags));
|
||||
|
||||
param6.addItem( param7 );
|
||||
param3.setInstancesSet( param6 );
|
||||
param2.addItem( param3 );
|
||||
|
|
@ -1759,12 +1908,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
param3.setDescription( snap.getName());
|
||||
param3.setOwnerAlias( snap.getAccountName() );
|
||||
|
||||
ResourceTagSetType param18 = new ResourceTagSetType();
|
||||
ResourceTagSetItemType param19 = new ResourceTagSetItemType();
|
||||
param19.setKey("");
|
||||
param19.setValue("");
|
||||
param18.addItem( param19 );
|
||||
param3.setTagSet( param18 );
|
||||
|
||||
EC2TagKeyValue[] tags = snap.getResourceTags();
|
||||
param3.setTagSet(setResourceTags(tags));
|
||||
param2.addItem( param3 );
|
||||
}
|
||||
|
||||
|
|
@ -1931,7 +2077,48 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
response.setRevokeSecurityGroupIngressResponse( param1 );
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public static CreateTagsResponse toCreateTagsResponse( boolean success ) {
|
||||
CreateTagsResponse response = new CreateTagsResponse();
|
||||
CreateTagsResponseType param1 = new CreateTagsResponseType();
|
||||
|
||||
param1.set_return(success);
|
||||
param1.setRequestId( UUID.randomUUID().toString());
|
||||
response.setCreateTagsResponse(param1);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static DeleteTagsResponse toDeleteTagsResponse( boolean success ) {
|
||||
DeleteTagsResponse response = new DeleteTagsResponse();
|
||||
DeleteTagsResponseType param1 = new DeleteTagsResponseType();
|
||||
|
||||
param1.set_return(success);
|
||||
param1.setRequestId( UUID.randomUUID().toString());
|
||||
response.setDeleteTagsResponse(param1);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static DescribeTagsResponse toDescribeTagsResponse( EC2DescribeTagsResponse engineResponse) {
|
||||
DescribeTagsResponse response = new DescribeTagsResponse();
|
||||
DescribeTagsResponseType param1 = new DescribeTagsResponseType();
|
||||
|
||||
EC2ResourceTag[] tags = engineResponse.getTagsSet();
|
||||
TagSetType param2 = new TagSetType();
|
||||
for (EC2ResourceTag tag : tags) {
|
||||
TagSetItemType param3 = new TagSetItemType();
|
||||
param3.setResourceId(tag.getResourceId());
|
||||
param3.setResourceType(tag.getResourceType());
|
||||
param3.setKey(tag.getKey());
|
||||
if (tag.getValue() != null)
|
||||
param3.setValue(tag.getValue());
|
||||
param2.addItem(param3);
|
||||
}
|
||||
param1.setTagSet(param2);
|
||||
param1.setRequestId( UUID.randomUUID().toString());
|
||||
response.setDescribeTagsResponse(param1);
|
||||
return response;
|
||||
}
|
||||
|
||||
public DescribeKeyPairsResponse describeKeyPairs(DescribeKeyPairs describeKeyPairs) {
|
||||
|
||||
EC2DescribeKeyPairs ec2Request = new EC2DescribeKeyPairs();
|
||||
|
|
@ -2047,7 +2234,29 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
public GetPasswordDataResponse getPasswordData(GetPasswordData getPasswordData) {
|
||||
return toGetPasswordData(engine.getPasswordData(getPasswordData.getGetPasswordData().getInstanceId()));
|
||||
}
|
||||
|
||||
|
||||
public static ResourceTagSetType setResourceTags(EC2TagKeyValue[] tags){
|
||||
ResourceTagSetType param1 = new ResourceTagSetType();
|
||||
if (null == tags || 0 == tags.length) {
|
||||
ResourceTagSetItemType param2 = new ResourceTagSetItemType();
|
||||
param2.setKey("");
|
||||
param2.setValue("");
|
||||
param1.addItem( param2 );
|
||||
}
|
||||
else {
|
||||
for(EC2TagKeyValue tag : tags) {
|
||||
ResourceTagSetItemType param2 = new ResourceTagSetItemType();
|
||||
param2.setKey(tag.getKey());
|
||||
if (tag.getValue() != null)
|
||||
param2.setValue(tag.getValue());
|
||||
else
|
||||
param2.setValue("");
|
||||
param1.addItem(param2);
|
||||
}
|
||||
}
|
||||
return param1;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static GetPasswordDataResponse toGetPasswordData(final EC2PasswordData passwdData) {
|
||||
return new GetPasswordDataResponse() {{
|
||||
|
|
@ -2116,10 +2325,6 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
public CreateSubnetResponse createSubnet(CreateSubnet createSubnet) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public CreateTagsResponse createTags(CreateTags createTags) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public CreateVpcResponse createVpc(CreateVpc createVpc) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
|
|
@ -2156,10 +2361,6 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
public DeleteSubnetResponse deleteSubnet(DeleteSubnet deleteSubnet) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public DeleteTagsResponse deleteTags(DeleteTags deleteTags) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public DeleteVpcResponse deleteVpc(DeleteVpc deleteVpc) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
|
|
@ -2229,10 +2430,6 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
|||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public DescribeTagsResponse describeTags(DescribeTags describeTags) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
||||
public DescribeVpcsResponse describeVpcs(DescribeVpcs describeVpcs) {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class EC2DescribeInstances {
|
|||
|
||||
private List<String> instancesSet = new ArrayList<String>(); // a list of strings identifying instances
|
||||
private EC2InstanceFilterSet ifs = null;
|
||||
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
|
||||
|
||||
public EC2DescribeInstances() {
|
||||
}
|
||||
|
|
@ -42,4 +43,12 @@ public class EC2DescribeInstances {
|
|||
public void setFilterSet( EC2InstanceFilterSet param ) {
|
||||
ifs = param;
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
resourceTagSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTagSet() {
|
||||
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class EC2DescribeSnapshots {
|
|||
|
||||
private List<String> snapshotSet = new ArrayList<String>(); // a list of strings identifying snapshots
|
||||
private EC2SnapshotFilterSet sfs = null;
|
||||
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
|
||||
|
||||
public EC2DescribeSnapshots() {
|
||||
}
|
||||
|
|
@ -42,4 +43,12 @@ public class EC2DescribeSnapshots {
|
|||
public void setFilterSet( EC2SnapshotFilterSet param ) {
|
||||
sfs = param;
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
resourceTagSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTagSet() {
|
||||
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
public class EC2DescribeTags {
|
||||
|
||||
private EC2TagsFilterSet tfs = null;
|
||||
|
||||
public EC2DescribeTags() {
|
||||
}
|
||||
|
||||
public EC2TagsFilterSet getFilterSet() {
|
||||
return tfs;
|
||||
}
|
||||
|
||||
public void setFilterSet( EC2TagsFilterSet param ) {
|
||||
tfs = param;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EC2DescribeTagsResponse {
|
||||
|
||||
private List<EC2ResourceTag> tagsSet = new ArrayList<EC2ResourceTag>();
|
||||
|
||||
public EC2DescribeTagsResponse() {
|
||||
}
|
||||
|
||||
public void addTags( EC2ResourceTag param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
public EC2ResourceTag[] getTagsSet() {
|
||||
return tagsSet.toArray(new EC2ResourceTag[0]);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ public class EC2DescribeVolumes {
|
|||
|
||||
private List<String> volumeSet = new ArrayList<String>(); // a list of strings identifying volume ids
|
||||
private EC2VolumeFilterSet vfs = null;
|
||||
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
|
||||
|
||||
public EC2DescribeVolumes() {
|
||||
}
|
||||
|
|
@ -42,4 +43,12 @@ public class EC2DescribeVolumes {
|
|||
public void setFilterSet( EC2VolumeFilterSet param ) {
|
||||
vfs = param;
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
resourceTagSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTagSet() {
|
||||
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import com.cloud.stack.models.CloudStackNic;
|
|||
import com.cloud.stack.models.CloudStackOsType;
|
||||
import com.cloud.stack.models.CloudStackPasswordData;
|
||||
import com.cloud.stack.models.CloudStackResourceLimit;
|
||||
import com.cloud.stack.models.CloudStackResourceTag;
|
||||
import com.cloud.stack.models.CloudStackSecurityGroup;
|
||||
import com.cloud.stack.models.CloudStackSecurityGroupIngress;
|
||||
import com.cloud.stack.models.CloudStackServiceOffering;
|
||||
|
|
@ -417,20 +418,22 @@ public class EC2Engine {
|
|||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public EC2DescribeSnapshotsResponse handleRequest( EC2DescribeSnapshots request )
|
||||
public EC2DescribeSnapshotsResponse handleRequest( EC2DescribeSnapshots request )
|
||||
{
|
||||
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
|
||||
EC2SnapshotFilterSet sfs = request.getFilterSet();
|
||||
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
|
||||
|
||||
try {
|
||||
// -> query to get the volume size for each snapshot
|
||||
EC2DescribeSnapshotsResponse response = listSnapshots( request.getSnapshotSet());
|
||||
EC2DescribeSnapshotsResponse response = listSnapshots( request.getSnapshotSet(),
|
||||
getResourceTags(tagKeyValueSet));
|
||||
if (response == null) {
|
||||
return new EC2DescribeSnapshotsResponse();
|
||||
}
|
||||
EC2Snapshot[] snapshots = response.getSnapshotSet();
|
||||
for (EC2Snapshot snap : snapshots) {
|
||||
volumes = listVolumes(snap.getVolumeId(), null, volumes);
|
||||
volumes = listVolumes(snap.getVolumeId(), null, volumes, null);
|
||||
EC2Volume[] volSet = volumes.getVolumeSet();
|
||||
if (0 < volSet.length) snap.setVolumeSize(volSet[0].getSize());
|
||||
volumes.reset();
|
||||
|
|
@ -472,7 +475,7 @@ public class EC2Engine {
|
|||
ec2Snapshot.setCreated(snap.getCreated());
|
||||
ec2Snapshot.setVolumeId(snap.getVolumeId());
|
||||
|
||||
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null);
|
||||
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null, null);
|
||||
|
||||
if(vols.size() > 0) {
|
||||
assert(vols.get(0).getSize() != null);
|
||||
|
|
@ -629,17 +632,18 @@ public class EC2Engine {
|
|||
*
|
||||
* @param interestedShots - can be null, should be a subset of all snapshots
|
||||
*/
|
||||
private EC2DescribeSnapshotsResponse listSnapshots( String[] interestedShots ) throws Exception {
|
||||
private EC2DescribeSnapshotsResponse listSnapshots( String[] interestedShots, List<CloudStackKeyValue> resourceTagSet ) throws Exception {
|
||||
EC2DescribeSnapshotsResponse snapshots = new EC2DescribeSnapshotsResponse();
|
||||
|
||||
List<CloudStackSnapshot> cloudSnaps;
|
||||
if (interestedShots == null || interestedShots.length == 0) {
|
||||
cloudSnaps = getApi().listSnapshots(null, null, null, null, null, null, null, null, null);
|
||||
cloudSnaps = getApi().listSnapshots(null, null, null, null, null, null, null, null, null, resourceTagSet);
|
||||
} else {
|
||||
cloudSnaps = new ArrayList<CloudStackSnapshot>();
|
||||
|
||||
for(String id : interestedShots) {
|
||||
List<CloudStackSnapshot> tmpList = getApi().listSnapshots(null, null, id, null, null, null, null, null, null);
|
||||
List<CloudStackSnapshot> tmpList = getApi().listSnapshots(null, null, id, null, null, null, null,
|
||||
null, null, resourceTagSet);
|
||||
cloudSnaps.addAll(tmpList);
|
||||
}
|
||||
}
|
||||
|
|
@ -659,6 +663,15 @@ public class EC2Engine {
|
|||
shot.setAccountName(cloudSnapshot.getAccountName());
|
||||
shot.setDomainId(cloudSnapshot.getDomainId());
|
||||
|
||||
List<CloudStackKeyValue> resourceTags = cloudSnapshot.getTags();
|
||||
for(CloudStackKeyValue resourceTag : resourceTags) {
|
||||
EC2TagKeyValue param = new EC2TagKeyValue();
|
||||
param.setKey(resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
param.setValue(resourceTag.getValue());
|
||||
shot.addResourceTag(param);
|
||||
}
|
||||
|
||||
snapshots.addSnapshot(shot);
|
||||
}
|
||||
return snapshots;
|
||||
|
|
@ -870,7 +883,7 @@ public class EC2Engine {
|
|||
public boolean associateAddress( EC2AssociateAddress request ) {
|
||||
try {
|
||||
CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
|
||||
CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null).get(0);
|
||||
CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null).get(0);
|
||||
|
||||
CloudStackInfoResponse resp = getApi().enableStaticNat(cloudIp.getId(), cloudVm.getId());
|
||||
if (resp != null) {
|
||||
|
|
@ -995,7 +1008,7 @@ public class EC2Engine {
|
|||
// [A] Creating a template from a VM volume should be from the ROOT volume
|
||||
// Also for this to work the VM must be in a Stopped state so we 'reboot' it if its not
|
||||
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
|
||||
volumes = listVolumes( null, request.getInstanceId(), volumes );
|
||||
volumes = listVolumes( null, request.getInstanceId(), volumes, null );
|
||||
EC2Volume[] volSet = volumes.getVolumeSet();
|
||||
for (EC2Volume vol : volSet) {
|
||||
if (vol.getType().equalsIgnoreCase( "ROOT" )) {
|
||||
|
|
@ -1012,7 +1025,7 @@ public class EC2Engine {
|
|||
|
||||
// [B] The parameters must be in sorted order for proper signature generation
|
||||
EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
|
||||
instances = lookupInstances( request.getInstanceId(), instances );
|
||||
instances = lookupInstances( request.getInstanceId(), instances, null );
|
||||
EC2Instance[] instanceSet = instances.getInstanceSet();
|
||||
String templateId = instanceSet[0].getTemplateId();
|
||||
|
||||
|
|
@ -1055,9 +1068,8 @@ public class EC2Engine {
|
|||
{
|
||||
try {
|
||||
CloudStackAccount caller = getCurrentAccount();
|
||||
if (null == request.getFormat() || null == request.getName() || null == request.getOsTypeName() ||
|
||||
null == request.getLocation() || null == request.getZoneName())
|
||||
throw new EC2ServiceException(ServerError.InternalError, "Missing parameter - location/architecture/name");
|
||||
if (null == request.getName())
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "Missing parameter - name");
|
||||
|
||||
List<CloudStackTemplate> templates = getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()),
|
||||
request.getFormat(), request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(),
|
||||
|
|
@ -1106,7 +1118,9 @@ public class EC2Engine {
|
|||
*/
|
||||
public EC2DescribeInstancesResponse describeInstances(EC2DescribeInstances request ) {
|
||||
try {
|
||||
return listVirtualMachines( request.getInstancesSet(), request.getFilterSet());
|
||||
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
|
||||
return listVirtualMachines( request.getInstancesSet(), request.getFilterSet(),
|
||||
getResourceTags(tagKeyValueSet));
|
||||
} catch( Exception e ) {
|
||||
logger.error( "EC2 DescribeInstances - " ,e);
|
||||
throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
|
||||
|
|
@ -1150,14 +1164,14 @@ public class EC2Engine {
|
|||
public EC2DescribeVolumesResponse handleRequest( EC2DescribeVolumes request ) {
|
||||
EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
|
||||
EC2VolumeFilterSet vfs = request.getFilterSet();
|
||||
|
||||
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
|
||||
try {
|
||||
String[] volumeIds = request.getVolumeSet();
|
||||
if ( 0 == volumeIds.length ){
|
||||
volumes = listVolumes( null, null, volumes );
|
||||
volumes = listVolumes( null, null, volumes, getResourceTags(tagKeyValueSet) );
|
||||
} else {
|
||||
for (String s : volumeIds)
|
||||
volumes = listVolumes(s, null, volumes );
|
||||
volumes = listVolumes(s, null, volumes, getResourceTags(tagKeyValueSet) );
|
||||
}
|
||||
|
||||
if ( null == vfs )
|
||||
|
|
@ -1311,6 +1325,80 @@ public class EC2Engine {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create/Delete tags
|
||||
*
|
||||
* @param request
|
||||
* @param operation
|
||||
* @return
|
||||
*/
|
||||
public boolean modifyTags( EC2Tags request, String operation) {
|
||||
try {
|
||||
List<CloudStackKeyValue> resourceTagList = new ArrayList<CloudStackKeyValue>();
|
||||
for ( EC2TagKeyValue resourceTag : request.getResourceTags()){
|
||||
CloudStackKeyValue pair = new CloudStackKeyValue();
|
||||
pair.setKeyValue(resourceTag.getKey(), resourceTag.getValue());
|
||||
resourceTagList.add(pair);
|
||||
}
|
||||
EC2TagTypeId[] resourceTypeSet = request.getResourceTypeSet();
|
||||
for (EC2TagTypeId resourceType : resourceTypeSet) {
|
||||
String cloudStackResourceType = mapToCloudStackResourceType(resourceType.getResourceType());
|
||||
List<String> resourceIdList = new ArrayList<String>();
|
||||
for ( String resourceId : resourceType.getResourceIds())
|
||||
resourceIdList.add(resourceId);
|
||||
CloudStackInfoResponse resp = new CloudStackInfoResponse();
|
||||
if (operation.equalsIgnoreCase("create"))
|
||||
resp = getApi().createTags(cloudStackResourceType, resourceIdList, resourceTagList);
|
||||
else if(operation.equalsIgnoreCase("delete"))
|
||||
resp = getApi().deleteTags(cloudStackResourceType, resourceIdList, resourceTagList);
|
||||
else
|
||||
throw new EC2ServiceException( ServerError.InternalError, "Unknown operation." );
|
||||
if (resp.getSuccess() == false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
logger.error( "EC2 Create/Delete Tags - ", e);
|
||||
throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ?
|
||||
e.getMessage() : "An unexpected error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe tags
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public EC2DescribeTagsResponse describeTags (EC2DescribeTags request) {
|
||||
try {
|
||||
EC2DescribeTagsResponse tagResponse = new EC2DescribeTagsResponse();
|
||||
List<CloudStackResourceTag> resourceTagList = getApi().listTags(null, null, null, true, null);
|
||||
|
||||
List<EC2ResourceTag> tagList = new ArrayList<EC2ResourceTag>();
|
||||
if (resourceTagList != null && resourceTagList.size() > 0) {
|
||||
for (CloudStackResourceTag resourceTag: resourceTagList) {
|
||||
EC2ResourceTag tag = new EC2ResourceTag();
|
||||
tag.setResourceId(resourceTag.getResourceId());
|
||||
tag.setResourceType(mapToAmazonResourceType(resourceTag.getResourceType()));
|
||||
tag.setKey(resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
tag.setValue(resourceTag.getValue());
|
||||
tagResponse.addTags(tag);
|
||||
}
|
||||
}
|
||||
|
||||
EC2TagsFilterSet tfs = request.getFilterSet();
|
||||
if (tfs == null)
|
||||
return tagResponse;
|
||||
else
|
||||
return tfs.evaluate(tagResponse);
|
||||
} catch(Exception e) {
|
||||
logger.error("EC2 DescribeTags - ", e);
|
||||
throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reboot an instance or instances
|
||||
*
|
||||
|
|
@ -1324,7 +1412,7 @@ public class EC2Engine {
|
|||
// -> reboot is not allowed on destroyed (i.e., terminated) instances
|
||||
try {
|
||||
String[] instanceSet = request.getInstancesSet();
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null );
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null, null );
|
||||
vms = previousState.getInstanceSet();
|
||||
|
||||
// -> send reboot requests for each found VM
|
||||
|
|
@ -1461,7 +1549,7 @@ public class EC2Engine {
|
|||
|
||||
// -> first determine the current state of each VM (becomes it previous state)
|
||||
try {
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( request.getInstancesSet(), null );
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( request.getInstancesSet(), null, null );
|
||||
vms = previousState.getInstanceSet();
|
||||
|
||||
// -> send start requests for each item
|
||||
|
|
@ -1503,7 +1591,7 @@ public class EC2Engine {
|
|||
try {
|
||||
String[] instanceSet = request.getInstancesSet();
|
||||
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null );
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null, null );
|
||||
virtualMachines = previousState.getInstanceSet();
|
||||
|
||||
// -> send stop requests for each item
|
||||
|
|
@ -1570,7 +1658,7 @@ public class EC2Engine {
|
|||
if (maxAllowed == -1)
|
||||
return -1; // no limit
|
||||
|
||||
EC2DescribeInstancesResponse existingVMS = listVirtualMachines( null, null );
|
||||
EC2DescribeInstancesResponse existingVMS = listVirtualMachines( null, null, null );
|
||||
EC2Instance[] vmsList = existingVMS.getInstanceSet();
|
||||
return (maxAllowed - vmsList.length);
|
||||
} else {
|
||||
|
|
@ -1584,15 +1672,16 @@ public class EC2Engine {
|
|||
* @param virtualMachineIds - an array of instances we are interested in getting information on
|
||||
* @param ifs - filter out unwanted instances
|
||||
*/
|
||||
private EC2DescribeInstancesResponse listVirtualMachines( String[] virtualMachineIds, EC2InstanceFilterSet ifs ) throws Exception
|
||||
private EC2DescribeInstancesResponse listVirtualMachines( String[] virtualMachineIds, EC2InstanceFilterSet ifs,
|
||||
List<CloudStackKeyValue> resourceTags ) throws Exception
|
||||
{
|
||||
EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
|
||||
|
||||
if (null == virtualMachineIds || 0 == virtualMachineIds.length) {
|
||||
instances = lookupInstances( null, instances );
|
||||
instances = lookupInstances( null, instances, resourceTags );
|
||||
} else {
|
||||
for( int i=0; i < virtualMachineIds.length; i++ ) {
|
||||
instances = lookupInstances( virtualMachineIds[i], instances );
|
||||
instances = lookupInstances( virtualMachineIds[i], instances, resourceTags );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1607,9 +1696,11 @@ public class EC2Engine {
|
|||
* @param volumeId - if interested in one specific volume, null if want to list all volumes
|
||||
* @param instanceId - if interested in volumes for a specific instance, null if instance is not important
|
||||
*/
|
||||
private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes)throws Exception {
|
||||
private EC2DescribeVolumesResponse listVolumes(String volumeId, String instanceId, EC2DescribeVolumesResponse volumes,
|
||||
List<CloudStackKeyValue> resourceTagSet)throws Exception {
|
||||
|
||||
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null, instanceId, null);
|
||||
List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, volumeId, null, null, null, null, null,
|
||||
instanceId, null, resourceTagSet);
|
||||
if(vols != null && vols.size() > 0) {
|
||||
for(CloudStackVolume vol : vols) {
|
||||
EC2Volume ec2Vol = new EC2Volume();
|
||||
|
|
@ -1635,6 +1726,15 @@ public class EC2Engine {
|
|||
ec2Vol.setVMState(vol.getVirtualMachineState());
|
||||
ec2Vol.setZoneName(vol.getZoneName());
|
||||
|
||||
List<CloudStackKeyValue> resourceTags = vol.getTags();
|
||||
for(CloudStackKeyValue resourceTag : resourceTags) {
|
||||
EC2TagKeyValue param = new EC2TagKeyValue();
|
||||
param.setKey(resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
param.setValue(resourceTag.getValue());
|
||||
ec2Vol.addResourceTag(param);
|
||||
}
|
||||
|
||||
volumes.addVolume(ec2Vol);
|
||||
}
|
||||
}
|
||||
|
|
@ -1779,12 +1879,13 @@ public class EC2Engine {
|
|||
* @return the same object passed in as the "instances" parameter modified with one or more
|
||||
* EC2Instance objects loaded.
|
||||
*/
|
||||
private EC2DescribeInstancesResponse lookupInstances( String instanceId, EC2DescribeInstancesResponse instances )
|
||||
private EC2DescribeInstancesResponse lookupInstances( String instanceId, EC2DescribeInstancesResponse instances,
|
||||
List<CloudStackKeyValue> resourceTagSet )
|
||||
throws Exception {
|
||||
|
||||
String instId = instanceId != null ? instanceId : null;
|
||||
List<CloudStackUserVm> vms = getApi().listVirtualMachines(null, null, true, null, null, null, null,
|
||||
instId, null, null, null, null, null, null, null, null);
|
||||
instId, null, null, null, null, null, null, null, null, resourceTagSet);
|
||||
|
||||
if(vms != null && vms.size() > 0) {
|
||||
for(CloudStackUserVm cloudVm : vms) {
|
||||
|
|
@ -1812,7 +1913,16 @@ public class EC2Engine {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<CloudStackKeyValue> resourceTags = cloudVm.getTags();
|
||||
for(CloudStackKeyValue resourceTag : resourceTags) {
|
||||
EC2TagKeyValue param = new EC2TagKeyValue();
|
||||
param.setKey(resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
param.setValue(resourceTag.getValue());
|
||||
ec2Vm.addResourceTag(param);
|
||||
}
|
||||
|
||||
if (cloudVm.getSecurityGroupList() != null && cloudVm.getSecurityGroupList().size() > 0) {
|
||||
// TODO, we have a list of security groups, just return the first one?
|
||||
List<CloudStackSecurityGroup> securityGroupList = cloudVm.getSecurityGroupList();
|
||||
|
|
@ -1885,6 +1995,14 @@ public class EC2Engine {
|
|||
ec2Image.setIsPublic(temp.getIsPublic());
|
||||
ec2Image.setIsReady(temp.getIsReady());
|
||||
ec2Image.setDomainId(temp.getDomainId());
|
||||
List<CloudStackKeyValue> resourceTags = temp.getTags();
|
||||
for(CloudStackKeyValue resourceTag : resourceTags) {
|
||||
EC2TagKeyValue param = new EC2TagKeyValue();
|
||||
param.setKey(resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
param.setValue(resourceTag.getValue());
|
||||
ec2Image.addResourceTag(param);
|
||||
}
|
||||
images.addImage(ec2Image);
|
||||
}
|
||||
}
|
||||
|
|
@ -2245,6 +2363,36 @@ public class EC2Engine {
|
|||
return "error";
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Amazon resourceType to CloudStack resourceType
|
||||
*
|
||||
* @param Amazon resourceType
|
||||
* @return CloudStack resourceType
|
||||
*/
|
||||
private String mapToCloudStackResourceType( String resourceType) {
|
||||
if (resourceType.equalsIgnoreCase("image"))
|
||||
return("template");
|
||||
else if(resourceType.equalsIgnoreCase("instance"))
|
||||
return("userVm");
|
||||
else
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Amazon resourceType to CloudStack resourceType
|
||||
*
|
||||
* @param CloudStack resourceType
|
||||
* @return Amazon resourceType
|
||||
*/
|
||||
private String mapToAmazonResourceType( String resourceType) {
|
||||
if (resourceType.equalsIgnoreCase("template"))
|
||||
return("image");
|
||||
else if(resourceType.equalsIgnoreCase("userVm"))
|
||||
return("instance");
|
||||
else
|
||||
return (resourceType.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop an instance
|
||||
* Wait until one specific VM has stopped
|
||||
|
|
@ -2299,4 +2447,15 @@ public class EC2Engine {
|
|||
}
|
||||
return elementList.toString();
|
||||
}
|
||||
|
||||
private List<CloudStackKeyValue> getResourceTags(EC2TagKeyValue[] tagKeyValueSet) {
|
||||
List<CloudStackKeyValue> resourceTags = new ArrayList<CloudStackKeyValue>();
|
||||
for (EC2TagKeyValue tagKeyValue : tagKeyValueSet) {
|
||||
CloudStackKeyValue resourceTag = new CloudStackKeyValue();
|
||||
resourceTag.setKeyValue(tagKeyValue.getKey(), tagKeyValue.getValue());
|
||||
resourceTags.add(resourceTag);
|
||||
}
|
||||
return resourceTags;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An EC2 Image is a Cloud template.
|
||||
*/
|
||||
|
|
@ -29,6 +32,7 @@ public class EC2Image {
|
|||
private boolean isReady;
|
||||
private String accountName;
|
||||
private String domainId;
|
||||
private List<EC2TagKeyValue> tagsSet;
|
||||
|
||||
public EC2Image() {
|
||||
id = null;
|
||||
|
|
@ -39,6 +43,7 @@ public class EC2Image {
|
|||
isReady = false;
|
||||
accountName = null;
|
||||
domainId = null;
|
||||
tagsSet = new ArrayList<EC2TagKeyValue>();
|
||||
}
|
||||
|
||||
public void setId( String id ) {
|
||||
|
|
@ -104,5 +109,13 @@ public class EC2Image {
|
|||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTags() {
|
||||
return tagsSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class EC2Instance {
|
|||
private String rootDeviceType;
|
||||
private String rootDeviceId;
|
||||
private List<String> groupSet;
|
||||
private List<EC2TagKeyValue> tagsSet;
|
||||
|
||||
public EC2Instance() {
|
||||
id = null;
|
||||
|
|
@ -60,6 +61,7 @@ public class EC2Instance {
|
|||
rootDeviceType = null;
|
||||
rootDeviceId = null;
|
||||
groupSet = new ArrayList<String>();
|
||||
tagsSet = new ArrayList<EC2TagKeyValue>();
|
||||
}
|
||||
|
||||
public void setId( String id ) {
|
||||
|
|
@ -197,5 +199,13 @@ public class EC2Instance {
|
|||
public String[] getGroupSet() {
|
||||
return groupSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTags() {
|
||||
return tagsSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,20 +48,21 @@ public class EC2InstanceFilterSet {
|
|||
filterTypes.put( "root-device-name", "string" );
|
||||
filterTypes.put( "private-ip-address", "string" );
|
||||
filterTypes.put( "group-id", "string" );
|
||||
filterTypes.put( "tag-key", "string" );
|
||||
filterTypes.put( "tag-value", "string" );
|
||||
}
|
||||
|
||||
|
||||
public void addFilter( EC2Filter param )
|
||||
{
|
||||
String filterName = param.getName();
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
|
||||
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
|
||||
filterSet.add( param );
|
||||
}
|
||||
|
|
@ -162,6 +163,26 @@ public class EC2InstanceFilterSet {
|
|||
for (String group : groupSet)
|
||||
if (containsString(group, valueSet)) return true;
|
||||
return false;
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-key"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = vm.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet)
|
||||
if (containsString(tag.getKey(), valueSet)) return true;
|
||||
return false;
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-value"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = vm.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet) {
|
||||
if (tag.getValue() == null) {
|
||||
if (containsEmptyValue(valueSet)) return true;
|
||||
}
|
||||
else {
|
||||
if (containsString(tag.getValue(), valueSet)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
|
@ -178,8 +199,14 @@ public class EC2InstanceFilterSet {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean containsEmptyValue( String[] set )
|
||||
{
|
||||
for( int i=0; i < set.length; i++ )
|
||||
if (set[i].isEmpty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsInteger( int lookingFor, String[] set )
|
||||
{
|
||||
for( int i=0; i < set.length; i++ )
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import com.cloud.bridge.service.exception.EC2ServiceException;
|
||||
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
|
||||
|
||||
public class EC2RegisterImage {
|
||||
|
||||
private String location;
|
||||
|
|
@ -67,14 +70,19 @@ public class EC2RegisterImage {
|
|||
*/
|
||||
public void setArchitecture( String param ) {
|
||||
if (null != param) {
|
||||
String parts[] = param.split( ":" );
|
||||
if (3 <= parts.length) {
|
||||
format = parts[0];
|
||||
zoneName = parts[1];
|
||||
osTypeName = parts[2];
|
||||
hypervisor = parts[3];
|
||||
}
|
||||
}
|
||||
if (!param.contains(":") || param.split(":").length < 4) {
|
||||
throw new EC2ServiceException( ClientError.InvalidParameterValue, "Supported format for " +
|
||||
"'architecture' is format:zonename:ostypename:hypervisor" );
|
||||
}
|
||||
String parts[] = param.split( ":" );
|
||||
format = parts[0];
|
||||
zoneName = parts[1];
|
||||
osTypeName = parts[2];
|
||||
hypervisor = parts[3];
|
||||
}
|
||||
else {
|
||||
throw new EC2ServiceException(ClientError.Unsupported, "Missing Parameter -" + " architecture");
|
||||
}
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
public class EC2ResourceTag {
|
||||
private String resourceId;
|
||||
private String resourceType;
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public EC2ResourceTag() {
|
||||
resourceId = null;
|
||||
resourceType = null;
|
||||
key = null;
|
||||
value = null;
|
||||
}
|
||||
|
||||
public void setResourceId( String resourceId ) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return this.resourceId;
|
||||
}
|
||||
|
||||
public void setResourceType( String resourceType ) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return this.resourceType;
|
||||
}
|
||||
|
||||
public void setKey( String key ) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public void setValue( String value ) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.bridge.util.EC2RestAuth;
|
||||
|
||||
|
|
@ -31,6 +33,7 @@ public class EC2Snapshot {
|
|||
private Calendar created;
|
||||
private String accountName;
|
||||
private String domainId;
|
||||
private List<EC2TagKeyValue> tagsSet;
|
||||
|
||||
public EC2Snapshot() {
|
||||
id = null;
|
||||
|
|
@ -42,6 +45,7 @@ public class EC2Snapshot {
|
|||
created = null;
|
||||
accountName = null;
|
||||
domainId = null;
|
||||
tagsSet = new ArrayList<EC2TagKeyValue>();
|
||||
}
|
||||
|
||||
public void setId(String id ) {
|
||||
|
|
@ -116,4 +120,12 @@ public class EC2Snapshot {
|
|||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTags() {
|
||||
return tagsSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,20 +46,23 @@ public class EC2SnapshotFilterSet {
|
|||
filterTypes.put( "status", "string" );
|
||||
filterTypes.put( "volume-id", "string" );
|
||||
filterTypes.put( "volume-size", "string" );
|
||||
filterTypes.put( "tag-key", "string" );
|
||||
filterTypes.put( "tag-value", "string" );
|
||||
}
|
||||
|
||||
|
||||
public void addFilter( EC2Filter param )
|
||||
{
|
||||
String filterName = param.getName();
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
|
||||
if (!filterName.startsWith("tag:")) {
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
|
||||
}
|
||||
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
|
||||
filterSet.add( param );
|
||||
}
|
||||
|
|
@ -140,6 +143,26 @@ public class EC2SnapshotFilterSet {
|
|||
{
|
||||
return containsLong( snap.getVolumeSize(), valueSet );
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-key"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = snap.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet)
|
||||
if (containsString(tag.getKey(), valueSet)) return true;
|
||||
return false;
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-value"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = snap.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet){
|
||||
if (tag.getValue() == null) {
|
||||
if (containsEmptyValue(valueSet)) return true;
|
||||
}
|
||||
else {
|
||||
if (containsString(tag.getValue(), valueSet)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +178,13 @@ public class EC2SnapshotFilterSet {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean containsEmptyValue( String[] set )
|
||||
{
|
||||
for( int i=0; i < set.length; i++ )
|
||||
if (set[i].isEmpty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsLong( long lookingFor, String[] set )
|
||||
{
|
||||
for (String s : set) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
public class EC2TagKeyValue {
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public EC2TagKeyValue() {
|
||||
key = null;
|
||||
value = null;
|
||||
}
|
||||
|
||||
public void setKey( String key ) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public void setValue( String value ) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EC2TagTypeId {
|
||||
|
||||
private String resourceType;
|
||||
private List<String> resourceIdSet = new ArrayList<String>();
|
||||
|
||||
public EC2TagTypeId() {
|
||||
resourceType = null;
|
||||
}
|
||||
|
||||
public void setResourceType( String resourceType ) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return this.resourceType;
|
||||
}
|
||||
|
||||
public void addResourceId( String param ) {
|
||||
resourceIdSet.add( param );
|
||||
}
|
||||
|
||||
public String[] getResourceIds() {
|
||||
return resourceIdSet.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EC2Tags {
|
||||
|
||||
private List<EC2TagTypeId> resourceTypeSet = new ArrayList<EC2TagTypeId>();
|
||||
private List<EC2TagKeyValue> resourceTagSet = new ArrayList<EC2TagKeyValue>();
|
||||
|
||||
public void addResourceType( EC2TagTypeId param ) {
|
||||
resourceTypeSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagTypeId[] getResourceTypeSet() {
|
||||
return resourceTypeSet.toArray(new EC2TagTypeId[0]);
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
resourceTagSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTags() {
|
||||
return resourceTagSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.bridge.service.exception.EC2ServiceException;
|
||||
|
||||
public class EC2TagsFilterSet {
|
||||
protected final static Logger logger = Logger.getLogger(EC2TagsFilterSet.class);
|
||||
|
||||
protected List<EC2Filter> filterSet = new ArrayList<EC2Filter>();
|
||||
|
||||
private Map<String,String> filterTypes = new HashMap<String,String>();
|
||||
|
||||
public EC2TagsFilterSet() {
|
||||
filterTypes.put( "resource-id", "String" );
|
||||
filterTypes.put( "resource-type", "String" );
|
||||
filterTypes.put( "key", "String" );
|
||||
filterTypes.put( "value", "String" );
|
||||
}
|
||||
|
||||
public void addFilter( EC2Filter param ) {
|
||||
String filterName = param.getName();
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
|
||||
|
||||
filterSet.add( param );
|
||||
}
|
||||
|
||||
public EC2Filter[] getFilterSet() {
|
||||
return filterSet.toArray(new EC2Filter[0]);
|
||||
}
|
||||
|
||||
public EC2DescribeTagsResponse evaluate( EC2DescribeTagsResponse sampleList) throws ParseException {
|
||||
EC2DescribeTagsResponse resultList = new EC2DescribeTagsResponse();
|
||||
|
||||
boolean matched;
|
||||
|
||||
EC2ResourceTag[] tagSet = sampleList.getTagsSet();
|
||||
EC2Filter[] filterSet = getFilterSet();
|
||||
for (EC2ResourceTag tag : tagSet) {
|
||||
matched = true;
|
||||
for (EC2Filter filter : filterSet) {
|
||||
if (!filterMatched(tag, filter)) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matched == true)
|
||||
resultList.addTags(tag);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private boolean filterMatched( EC2ResourceTag tag, EC2Filter filter ) throws ParseException {
|
||||
String filterName = filter.getName();
|
||||
String[] valueSet = filter.getValueSet();
|
||||
|
||||
if ( filterName.equalsIgnoreCase("resource-id")) {
|
||||
return containsString(tag.getResourceId(), valueSet);
|
||||
} else if ( filterName.equalsIgnoreCase("resource-type")) {
|
||||
return containsString(tag.getResourceType(), valueSet);
|
||||
} else if ( filterName.equalsIgnoreCase("key")) {
|
||||
return containsString(tag.getKey(), valueSet);
|
||||
} else if ( filterName.equalsIgnoreCase("value")) {
|
||||
return containsString(tag.getValue(), valueSet);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsString( String lookingFor, String[] set ){
|
||||
if (lookingFor == null)
|
||||
return false;
|
||||
|
||||
for (String filter: set) {
|
||||
if (lookingFor.matches( filter )) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class EC2Volume {
|
||||
|
||||
|
|
@ -32,6 +35,7 @@ public class EC2Volume {
|
|||
private String hypervisor;
|
||||
private String created;
|
||||
private String attached;
|
||||
private List<EC2TagKeyValue> tagsSet;
|
||||
|
||||
public EC2Volume() {
|
||||
id = null;
|
||||
|
|
@ -46,6 +50,7 @@ public class EC2Volume {
|
|||
hypervisor = null;
|
||||
created = null;
|
||||
attached = null;
|
||||
tagsSet = new ArrayList<EC2TagKeyValue>();
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
|
|
@ -230,5 +235,13 @@ public class EC2Volume {
|
|||
public void setAttached(String attached) {
|
||||
this.attached = attached;
|
||||
}
|
||||
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
public EC2TagKeyValue[] getResourceTags() {
|
||||
return tagsSet.toArray(new EC2TagKeyValue[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ public class EC2VolumeFilterSet {
|
|||
filterTypes.put( "size", "integer" );
|
||||
filterTypes.put( "snapshot-id", "string" );
|
||||
filterTypes.put( "status", "set:creating|available|in-use|deleting|deleted|error" );
|
||||
filterTypes.put( "tag-key", "null" );
|
||||
filterTypes.put( "tag-value", "null" );
|
||||
filterTypes.put( "tag-key", "string" );
|
||||
filterTypes.put( "tag-value", "string" );
|
||||
filterTypes.put( "volume-id", "string" );
|
||||
// filterTypes.put( "tag:*", "null" );
|
||||
}
|
||||
|
|
@ -59,14 +59,13 @@ public class EC2VolumeFilterSet {
|
|||
public void addFilter( EC2Filter param )
|
||||
{
|
||||
String filterName = param.getName();
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
String value = (String) filterTypes.get( filterName );
|
||||
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
|
||||
if (null == value)
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
|
||||
|
||||
if (null != value && value.equalsIgnoreCase( "null" ))
|
||||
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
|
||||
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
|
||||
filterSet.add( param );
|
||||
}
|
||||
|
|
@ -136,7 +135,27 @@ public class EC2VolumeFilterSet {
|
|||
else if (filterName.equalsIgnoreCase( "attachment.device" ))
|
||||
return containsDevice(vol.getDeviceId(), valueSet );
|
||||
else if (filterName.equalsIgnoreCase( "attachment.instance-id" ))
|
||||
return containsString(String.valueOf(vol.getInstanceId()), valueSet );
|
||||
return containsString(String.valueOf(vol.getInstanceId()), valueSet );
|
||||
else if (filterName.equalsIgnoreCase("tag-key"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = vol.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet)
|
||||
if (containsString(tag.getKey(), valueSet)) return true;
|
||||
return false;
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-value"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = vol.getResourceTags();
|
||||
for (EC2TagKeyValue tag : tagSet){
|
||||
if (tag.getValue() == null) {
|
||||
if (containsEmptyValue(valueSet)) return true;
|
||||
}
|
||||
else {
|
||||
if (containsString(tag.getValue(), valueSet)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
|
@ -150,6 +169,12 @@ public class EC2VolumeFilterSet {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean containsEmptyValue( String[] set )
|
||||
{
|
||||
for( int i=0; i < set.length; i++ )
|
||||
if (set[i].isEmpty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsLong( long lookingFor, String[] set )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import com.cloud.stack.models.CloudStackOsType;
|
|||
import com.cloud.stack.models.CloudStackPasswordData;
|
||||
import com.cloud.stack.models.CloudStackPortForwardingRule;
|
||||
import com.cloud.stack.models.CloudStackResourceLimit;
|
||||
import com.cloud.stack.models.CloudStackResourceTag;
|
||||
import com.cloud.stack.models.CloudStackSecurityGroup;
|
||||
import com.cloud.stack.models.CloudStackSecurityGroupIngress;
|
||||
import com.cloud.stack.models.CloudStackServiceOffering;
|
||||
|
|
@ -313,7 +314,7 @@ public class CloudStackApi {
|
|||
*/
|
||||
public List<CloudStackUserVm> listVirtualMachines(String account, String accountId, Boolean listAll, Boolean forVirtualNetwork, String groupId, String hostId,
|
||||
String hypervisor, String id, Boolean isRecursive, String keyWord, String name, String networkId, String podId, String state, String storageId,
|
||||
String zoneId) throws Exception {
|
||||
String zoneId, List<CloudStackKeyValue> resourceTags) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_VIRTUAL_MACHINES);
|
||||
if (cmd != null) {
|
||||
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
|
||||
|
|
@ -332,6 +333,8 @@ public class CloudStackApi {
|
|||
if (state != null) cmd.setParam(ApiConstants.STATE, state);
|
||||
if (storageId != null) cmd.setParam(ApiConstants.STORAGE_ID, storageId);
|
||||
if (zoneId != null) cmd.setParam(ApiConstants.ZONE_ID, zoneId);
|
||||
if (resourceTags != null && resourceTags.size() > 0)
|
||||
cmd = setParams(cmd, null, null, resourceTags);
|
||||
}
|
||||
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_VIRTUAL_MACHINES_RESPONSE, ApiConstants.VIRTUAL_MACHINE,
|
||||
new TypeToken<List<CloudStackUserVm>>() {}.getType());
|
||||
|
|
@ -934,7 +937,7 @@ public class CloudStackApi {
|
|||
* @throws Exception
|
||||
*/
|
||||
public List<CloudStackVolume> listVolumes(String account, String domainId, String hostId, String id, Boolean isRecursive, String keyWord, String name,
|
||||
String podId, String type, String virtualMachineId, String zoneId) throws Exception {
|
||||
String podId, String type, String virtualMachineId, String zoneId, List<CloudStackKeyValue> resourceTags) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_VOLUMES);
|
||||
if (cmd != null) {
|
||||
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
|
||||
|
|
@ -948,6 +951,8 @@ public class CloudStackApi {
|
|||
if (type != null) cmd.setParam(ApiConstants.TYPE, type);
|
||||
if (virtualMachineId != null) cmd.setParam(ApiConstants.VIRTUAL_MACHINE_ID, virtualMachineId);
|
||||
if (zoneId != null) cmd.setParam(ApiConstants.ZONE_ID, zoneId);
|
||||
if (resourceTags != null && resourceTags.size() > 0)
|
||||
cmd = setParams(cmd, null, null, resourceTags);
|
||||
}
|
||||
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_VOLUMES_RESPONSE, ApiConstants.VOLUME,
|
||||
new TypeToken<List<CloudStackVolume>>() {}.getType());
|
||||
|
|
@ -973,7 +978,82 @@ public class CloudStackApi {
|
|||
}
|
||||
return _client.call(cmd, apiKey, secretKey, true, ApiConstants.EXTRACT_VOLUME_RESPONSE, ApiConstants.VOLUME, CloudStackExtractTemplate.class);
|
||||
}
|
||||
|
||||
|
||||
//Tags
|
||||
/**
|
||||
* Create tags
|
||||
*
|
||||
* @param resource type
|
||||
* @param resource id's
|
||||
* @param tags
|
||||
* @return
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public CloudStackInfoResponse createTags(String resourceType, List<String>resourceIds,
|
||||
List<CloudStackKeyValue> resourceTags) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.CREATE_TAGS);
|
||||
cmd = setParams(cmd, resourceType, resourceIds, resourceTags);
|
||||
return _client.call(cmd, apiKey, secretKey, true, ApiConstants.CREATE_TAGS_RESPONSE,
|
||||
null, CloudStackInfoResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete tags
|
||||
*
|
||||
* @param resource type
|
||||
* @param resource id's
|
||||
* @param tags
|
||||
* @return
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public CloudStackInfoResponse deleteTags(String resourceType, List<String>resourceIds,
|
||||
List<CloudStackKeyValue> resourceTags) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.DELETE_TAGS);
|
||||
cmd = setParams(cmd, resourceType, resourceIds, resourceTags);
|
||||
return _client.call(cmd, apiKey, secretKey, true, ApiConstants.DELETE_TAGS_RESPONSE,
|
||||
null, CloudStackInfoResponse.class);
|
||||
}
|
||||
|
||||
public List<CloudStackResourceTag> listTags(String account, String domainId,
|
||||
Boolean isRecursive, Boolean listAll, String keyWord) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_TAGS);
|
||||
if (cmd != null) {
|
||||
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
|
||||
if (domainId != null) cmd.setParam(ApiConstants.DOMAIN_ID, domainId);
|
||||
if (isRecursive != null) cmd.setParam(ApiConstants.IS_RECURSIVE, isRecursive.toString());
|
||||
if (listAll != null) cmd.setParam(ApiConstants.LIST_ALL, listAll.toString());
|
||||
if (keyWord != null) cmd.setParam(ApiConstants.KEYWORD, keyWord);
|
||||
}
|
||||
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_TAGS_RESPONSE,
|
||||
ApiConstants.TAG , new TypeToken<List<CloudStackResourceTag>>() {}.getType());
|
||||
}
|
||||
|
||||
private CloudStackCommand setParams(CloudStackCommand cmd, String resourceType, List<String>resourceIds,
|
||||
List<CloudStackKeyValue> resourceTags) {
|
||||
if (cmd != null) {
|
||||
if (resourceType != null)
|
||||
cmd.setParam(ApiConstants.RESOURCE_TYPE, resourceType);
|
||||
if (resourceIds != null && resourceIds.size() > 0) {
|
||||
String resourceIdList = resourceIds.get(0);
|
||||
for (int i=1 ; i<resourceIds.size(); i++)
|
||||
resourceIdList = resourceIdList.concat(","+resourceIds.get(i));
|
||||
cmd.setParam(ApiConstants.RESOURCE_IDS, resourceIdList);
|
||||
}
|
||||
if (resourceTags != null && resourceTags.size() > 0) {
|
||||
int i=0;
|
||||
for (CloudStackKeyValue resourceTag : resourceTags) {
|
||||
cmd.setParam(ApiConstants.TAGS+"["+i+"].key", resourceTag.getKey());
|
||||
if (resourceTag.getValue() != null)
|
||||
cmd.setParam(ApiConstants.TAGS+"["+i+"].value", resourceTag.getValue());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// Security Groups
|
||||
/**
|
||||
* Creates a security group
|
||||
|
|
@ -1168,7 +1248,7 @@ public class CloudStackApi {
|
|||
* @throws Exception
|
||||
*/
|
||||
public List<CloudStackSnapshot> listSnapshots(String account, String domainId, String id, String intervalType, Boolean isRecursive,
|
||||
String keyWord, String name, String snapshotType, String volumeId) throws Exception {
|
||||
String keyWord, String name, String snapshotType, String volumeId, List<CloudStackKeyValue> resourceTags) throws Exception {
|
||||
CloudStackCommand cmd = new CloudStackCommand(ApiConstants.LIST_SNAPSHOTS);
|
||||
if (cmd != null) {
|
||||
if (account != null) cmd.setParam(ApiConstants.ACCOUNT, account);
|
||||
|
|
@ -1180,6 +1260,8 @@ public class CloudStackApi {
|
|||
if (name != null) cmd.setParam(ApiConstants.NAME, name);
|
||||
if (snapshotType != null) cmd.setParam(ApiConstants.SNAPSHOT_TYPE, snapshotType);
|
||||
if (volumeId != null) cmd.setParam(ApiConstants.VOLUME_ID, volumeId);
|
||||
if (resourceTags != null && resourceTags.size() > 0)
|
||||
cmd = setParams(cmd, null, null, resourceTags);
|
||||
}
|
||||
return _client.listCall(cmd, apiKey, secretKey, ApiConstants.LIST_SNAPSHOTS_RESPONSE, ApiConstants.SNAPSHOT,
|
||||
new TypeToken<List<CloudStackSnapshot>>() {}.getType());
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public class ApiConstants {
|
|||
public static final String CREATE_SNAPSHOT_RESPONSE = "createsnapshotresponse";
|
||||
public static final String CREATE_SSH_KEY_PAIR = "createSSHKeyPair";
|
||||
public static final String CREATE_SSH_KEY_PAIR_RESPONSE = "createsshkeypairresponse";
|
||||
public static final String CREATE_TAGS = "createTags";
|
||||
public static final String CREATE_TAGS_RESPONSE = "createtagsresponse";
|
||||
public static final String CREATE_TEMPLATE = "createTemplate";
|
||||
public static final String CREATE_TEMPLATE_RESPONSE = "createtemplateresponse";
|
||||
public static final String CREATE_VOLUME = "createVolume";
|
||||
|
|
@ -114,6 +116,8 @@ public class ApiConstants {
|
|||
public static final String DELETE_SNAPSHOT_RESPONSE = "deletesnapshotresponse";
|
||||
public static final String DELETE_SSH_KEY_PAIR = "deleteSSHKeyPair";
|
||||
public static final String DELETE_SSH_KEY_PAIR_RESPONSE = "deletesshkeypairresponse";
|
||||
public static final String DELETE_TAGS = "deleteTags";
|
||||
public static final String DELETE_TAGS_RESPONSE = "deletetagsresponse";
|
||||
public static final String DELETE_TEMPLATE = "deleteTemplate";
|
||||
public static final String DELETE_TEMPLATE_RESPONSE = "deletetemplateresponse";
|
||||
public static final String DELETE_VOLUME = "deleteVolume";
|
||||
|
|
@ -228,6 +232,7 @@ public class ApiConstants {
|
|||
public static final String ISOLATION_URI = "isolationuri";
|
||||
public static final String JOB_ID = "jobid";
|
||||
public static final String JOB_STATUS = "jobstatus";
|
||||
public static final String KEY = "key";
|
||||
public static final String KEY_PAIR = "keypair";
|
||||
public static final String KEYWORD = "keyword";
|
||||
public static final String LASTNAME = "lastname";
|
||||
|
|
@ -290,6 +295,8 @@ public class ApiConstants {
|
|||
public static final String LIST_SSH_KEY_PAIRS = "listSSHKeyPairs";
|
||||
public static final String LIST_SSH_KEY_PAIRS_RESPONSE = "listsshkeypairsresponse";
|
||||
public static final String LIST_TEMPLATE_PERMISSIONS = "listTemplatePermissions";
|
||||
public static final String LIST_TAGS = "listTags";
|
||||
public static final String LIST_TAGS_RESPONSE = "listtagsresponse";
|
||||
public static final String LIST_TEMPLATE_PERMISSIONS_RESPONSE = "listtemplatepermissionsresponse";
|
||||
public static final String LIST_TEMPLATES = "listTemplates";
|
||||
public static final String LIST_TEMPLATES_RESPONSE = "listtemplatesresponse";
|
||||
|
|
@ -380,6 +387,8 @@ public class ApiConstants {
|
|||
public static final String REQUIRES_HVM = "requireshvm";
|
||||
public static final String RESET_PASSWORD_FOR_VIRTUAL_MACHINE = "resetPasswordForVirtualMachine";
|
||||
public static final String RESET_PASSWORD_FOR_VIRTUAL_MACHINE_RESPONSE = "resetpasswordforvirtualmachineresponse";
|
||||
public static final String RESOURCE_ID = "resourceid";
|
||||
public static final String RESOURCE_IDS = "resourceIds";
|
||||
public static final String RESOURCE_LIMIT = "resourcelimit";
|
||||
public static final String RESOURCE_TYPE = "resourcetype";
|
||||
public static final String RESTART_NETWORK = "restartNetwork";
|
||||
|
|
@ -433,6 +442,7 @@ public class ApiConstants {
|
|||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String SUCCESS = "success";
|
||||
public static final String SYSTEM_VM_TYPE = "systemvmtype";
|
||||
public static final String TAG = "tag";
|
||||
public static final String TAGS = "tags";
|
||||
public static final String TARGET_IQN = "targetiqn";
|
||||
public static final String TEMPLATE = "template";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.stack.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class CloudStackResourceTag {
|
||||
@SerializedName(ApiConstants.RESOURCE_ID)
|
||||
private String resourceId;
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE)
|
||||
private String resourceType;
|
||||
@SerializedName(ApiConstants.KEY)
|
||||
private String key;
|
||||
@SerializedName(ApiConstants.VALUE)
|
||||
private String value;
|
||||
|
||||
public CloudStackResourceTag() {
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.stack.models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class CloudStackSnapshot {
|
||||
|
|
@ -47,6 +49,8 @@ public class CloudStackSnapshot {
|
|||
private String volumeName;
|
||||
@SerializedName(ApiConstants.VOLUME_TYPE)
|
||||
private String volumeType;
|
||||
@SerializedName(ApiConstants.TAGS)
|
||||
private List<CloudStackKeyValue> tags;
|
||||
|
||||
public CloudStackSnapshot() {
|
||||
}
|
||||
|
|
@ -106,4 +110,9 @@ public class CloudStackSnapshot {
|
|||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public List<CloudStackKeyValue> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package com.cloud.stack.models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class CloudStackTemplate {
|
||||
|
|
@ -82,6 +84,8 @@ public class CloudStackTemplate {
|
|||
private String zoneId;
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
private String zoneName;
|
||||
@SerializedName(ApiConstants.TAGS)
|
||||
private List<CloudStackKeyValue> tags;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -306,4 +310,10 @@ public class CloudStackTemplate {
|
|||
return zoneName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all tags
|
||||
*/
|
||||
public List<CloudStackKeyValue> getTags() {
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ public class CloudStackUserVm {
|
|||
private List<CloudStackNic> nics;
|
||||
@SerializedName(ApiConstants.SECURITY_GROUP)
|
||||
private List<CloudStackSecurityGroup> securityGroupList;
|
||||
@SerializedName(ApiConstants.TAGS)
|
||||
private List<CloudStackKeyValue> tags;
|
||||
|
||||
public CloudStackUserVm() {
|
||||
}
|
||||
|
|
@ -394,5 +396,12 @@ public class CloudStackUserVm {
|
|||
return securityGroupList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all tags
|
||||
*/
|
||||
public List<CloudStackKeyValue> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.stack.models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class CloudStackVolume {
|
||||
|
|
@ -81,6 +83,8 @@ public class CloudStackVolume {
|
|||
private String zoneId;
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
private String zoneName;
|
||||
@SerializedName(ApiConstants.TAGS)
|
||||
private List<CloudStackKeyValue> tags;
|
||||
|
||||
|
||||
public CloudStackVolume() {
|
||||
|
|
@ -334,4 +338,10 @@ public class CloudStackVolume {
|
|||
return zoneName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all tags
|
||||
*/
|
||||
public List<CloudStackKeyValue> getTags() {
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -777,7 +777,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
ipResponse.setIsSystem(ipAddr.getSystem());
|
||||
|
||||
// get account information
|
||||
populateOwner(ipResponse, ipAddr);
|
||||
if (ipAddr.getAllocatedToAccountId() != null) {
|
||||
populateOwner(ipResponse, ipAddr);
|
||||
}
|
||||
|
||||
ipResponse.setForVirtualNetwork(forVirtualNetworks);
|
||||
ipResponse.setStaticNat(ipAddr.isOneToOneNat());
|
||||
|
|
|
|||
|
|
@ -1714,23 +1714,30 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
Long vpcId = cmd.getVpcId();
|
||||
Map<String, String> tags = cmd.getTags();
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
|
||||
Boolean isAllocated = cmd.isAllocatedOnly();
|
||||
if (isAllocated == null) {
|
||||
isAllocated = Boolean.TRUE;
|
||||
}
|
||||
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||
_accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||
Long domainId = domainIdRecursiveListProject.first();
|
||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||
|
||||
Filter searchFilter = new Filter(IPAddressVO.class, "address", false, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
SearchBuilder<IPAddressVO> sb = _publicIpAddressDao.createSearchBuilder();
|
||||
Long domainId = null;
|
||||
Boolean isRecursive = null;
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = null;
|
||||
if (isAllocated) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject =
|
||||
new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||
_accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(),
|
||||
permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||
domainId = domainIdRecursiveListProject.first();
|
||||
isRecursive = domainIdRecursiveListProject.second();
|
||||
listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||
_accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
}
|
||||
|
||||
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("address", sb.entity().getAddress(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -1798,7 +1805,9 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
}
|
||||
|
||||
SearchCriteria<IPAddressVO> sc = sb.create();
|
||||
if (isAllocated) {
|
||||
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
}
|
||||
|
||||
sc.setJoinParameters("vlanSearch", "vlanType", vlanType);
|
||||
|
||||
|
|
|
|||
|
|
@ -3210,10 +3210,25 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
|||
} else {
|
||||
if (assignedPool.getId() != vol.getPoolId()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Volume " + vol + " is not recreatable! Cannot recreate on storagepool: " + assignedPool);
|
||||
s_logger.debug("Mismatch in storage pool " + assignedPool + " assigned by deploymentPlanner and the one associated with volume " + vol);
|
||||
}
|
||||
if (vm.getServiceOffering().getUseLocalStorage())
|
||||
{
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Local volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
|
||||
}
|
||||
recreateVols.add(vol);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
|
||||
}
|
||||
try {
|
||||
Volume migratedVol = migrateVolume(vol.getId(), assignedPool.getId());
|
||||
vm.addDisk(new VolumeTO(migratedVol, assignedPool));
|
||||
} catch (ConcurrentOperationException e) {
|
||||
throw new StorageUnavailableException("Volume migration failed for " + vol, Volume.class, vol.getId());
|
||||
}
|
||||
}
|
||||
throw new StorageUnavailableException("Volume is not recreatable, Unable to create " + vol, Volume.class, vol.getId());
|
||||
// copy volume usecase - not yet developed.
|
||||
} else {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
|
||||
vm.addDisk(new VolumeTO(vol, pool));
|
||||
|
|
|
|||
|
|
@ -8952,6 +8952,204 @@ div.panel.ui-dialog div.list-view div.fixed-header {
|
|||
background: #DFE1E3;
|
||||
}
|
||||
|
||||
/*Tagger*/
|
||||
.tagger {
|
||||
width: 94%;
|
||||
margin: auto;
|
||||
padding-bottom: 12px;
|
||||
background: #F2F0F0;
|
||||
border: 1px solid #CFC9C9;
|
||||
/*+placement:shift -4px 0px;*/
|
||||
position: relative;
|
||||
left: -4px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.tagger .field {
|
||||
width: 179px;
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tagger .tag-info {
|
||||
font-size: 11px;
|
||||
color: #757575;
|
||||
margin-top: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.tagger .tag-info.title {
|
||||
font-size: 11px;
|
||||
color: #6F9BF0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.tagger form {
|
||||
margin: 12px 9px 0px;
|
||||
}
|
||||
|
||||
.tagger.readonly form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tagger form label {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 28px;
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
color: #394552;
|
||||
margin-right: 9px;
|
||||
/*+placement:shift 5px 8px;*/
|
||||
position: relative;
|
||||
left: 5px;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.tagger form label.error {
|
||||
position: absolute;
|
||||
color: #FF0000;
|
||||
left: 42px;
|
||||
top: 29px;
|
||||
/*[empty]background-color:;*/
|
||||
}
|
||||
|
||||
.tagger form input {
|
||||
padding: 4px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #808080;
|
||||
/*+border-radius:4px;*/
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tagger form input[type=submit] {
|
||||
background: url(../images/bg-gradients.png) repeat-x 0px -220px;
|
||||
cursor: pointer;
|
||||
color: #FFFFFF;
|
||||
/*+text-shadow:0px -1px 2px #000000;*/
|
||||
-moz-text-shadow: 0px -1px 2px #000000;
|
||||
-webkit-text-shadow: 0px -1px 2px #000000;
|
||||
-o-text-shadow: 0px -1px 2px #000000;
|
||||
text-shadow: 0px -1px 2px #000000;
|
||||
border: none;
|
||||
/*+border-radius:4px;*/
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
padding: 7px 25px 7px 26px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.tagger form input[type=submit]:hover {
|
||||
background-position: 0px -946px;
|
||||
}
|
||||
|
||||
.tagger ul {
|
||||
display: block;
|
||||
width: 96%;
|
||||
margin: 16px auto auto;
|
||||
/*+border-radius:2px;*/
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-khtml-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
overflow: auto;
|
||||
padding-bottom: 10px;
|
||||
border: 1px solid #D2D2D2;
|
||||
background: #FFFFFF;
|
||||
/*+box-shadow:inset 0px 0px 10px #DCDCDC;*/
|
||||
-moz-box-shadow: inset 0px 0px 10px #DCDCDC;
|
||||
-webkit-box-shadow: inset 0px 0px 10px #DCDCDC;
|
||||
-o-box-shadow: inset 0px 0px 10px #DCDCDC;
|
||||
box-shadow: inset 0px 0px 10px #DCDCDC;
|
||||
}
|
||||
|
||||
.tagger.readonly ul {
|
||||
}
|
||||
|
||||
.tagger ul li {
|
||||
background: #DFDFDF 0px 4px;
|
||||
height: 15px;
|
||||
padding: 0px 18px 0 7px;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin-left: 7px;
|
||||
margin-right: 2px;
|
||||
margin-top: 5px;
|
||||
/*+border-radius:4px;*/
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
/*+placement:shift 0px 2px;*/
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.tagger ul li span {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.tagger ul li span.label {
|
||||
font-size: 10px;
|
||||
position: relative;
|
||||
left: 15px;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.tagger.readonly ul li span.label {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.tagger ul li span.remove {
|
||||
width: 15px !important;
|
||||
overflow: hidden !important;
|
||||
height: 11px !important;
|
||||
background: #DFDFDF url(../images/sprites.png) no-repeat -596px -1183px;
|
||||
display: block;
|
||||
top: 0px !important;
|
||||
left: -3px !important;
|
||||
text-indent: 4px;
|
||||
padding: 4px 0px 0px 8px;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
position: absolute !important;
|
||||
color: #5B5B5B;
|
||||
}
|
||||
|
||||
.tagger.readonly ul li span.remove {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tagger ul li span.remove:hover {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/** Dialog tagger*/
|
||||
.ui-dialog .tagger {
|
||||
}
|
||||
|
||||
.ui-dialog .tagger .field {
|
||||
width: 119px !important;
|
||||
}
|
||||
|
||||
.ui-dialog .tagger input.key,
|
||||
.ui-dialog .tagger input.value {
|
||||
width: 66px !important;
|
||||
height: 15px;
|
||||
font-size: 11px !important;
|
||||
}
|
||||
|
||||
.ui-dialog .tagger input[type=submit] {
|
||||
padding: 6px 15px;
|
||||
}
|
||||
|
||||
/*VPC / vApps*/
|
||||
.vpc-chart {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -1616,6 +1616,7 @@
|
|||
<script type="text/javascript" src="scripts/ui/widgets/detailView.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/treeView.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/notifications.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/tagger.js?t=<%=now%>"></script>
|
||||
|
||||
<script type="text/javascript" src="scripts/cloud.core.callbacks.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/sharedFunctions.js?t=<%=now%>"></script>
|
||||
|
|
|
|||
|
|
@ -617,5 +617,83 @@ cloudStack.api = {
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
tags: function(args) {
|
||||
var resourceType = args.resourceType;
|
||||
var contextId = args.contextId;
|
||||
|
||||
return {
|
||||
actions: {
|
||||
add: function(args) {
|
||||
var data = args.data;
|
||||
var resourceId = args.context[contextId][0].id;
|
||||
|
||||
$.ajax({
|
||||
url: createURL(
|
||||
'createTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value
|
||||
),
|
||||
data: {
|
||||
resourceIds: resourceId,
|
||||
resourceType: resourceType
|
||||
},
|
||||
success: function(json) {
|
||||
args.response.success({
|
||||
_custom: { jobId: json.createtagsresponse.jobid },
|
||||
notification: {
|
||||
desc: 'Add tag for instance',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(args) {
|
||||
var data = args.context.tagItems[0];
|
||||
var resourceId = args.context[contextId][0].id;
|
||||
|
||||
$.ajax({
|
||||
url: createURL(
|
||||
'deleteTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value
|
||||
),
|
||||
data: {
|
||||
resourceIds: resourceId,
|
||||
resourceType: resourceType
|
||||
},
|
||||
success: function(json) {
|
||||
args.response.success({
|
||||
_custom: { jobId: json.deletetagsresponse.jobid },
|
||||
notification: {
|
||||
desc: 'Remove tag for instance',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
var resourceId = args.context[contextId][0].id;
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listTags'),
|
||||
data: {
|
||||
listAll: true,
|
||||
resourceId: resourceId,
|
||||
resourceType: resourceType
|
||||
},
|
||||
success: function(json) {
|
||||
args.response.success({
|
||||
data: json.listtagsresponse ?
|
||||
json.listtagsresponse.tag : []
|
||||
});
|
||||
},
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -287,10 +287,14 @@
|
|||
* @param callback
|
||||
*/
|
||||
edit: function($detailView, args) {
|
||||
$detailView.addClass('edit-mode');
|
||||
|
||||
if ($detailView.find('.button.done').size()) return false;
|
||||
|
||||
// Convert value TDs
|
||||
var $inputs = $detailView.find('input, select');
|
||||
var $inputs = $detailView.find('input, select').filter(function() {
|
||||
return !$(this).closest('.tagger').size() && !$(this).attr('type') == 'submit';
|
||||
});
|
||||
var action = args.actions[args.actionName];
|
||||
var id = $detailView.data('view-args').id;
|
||||
var $editButton = $('<div>').addClass('button done').html(_l('label.apply')).hide();
|
||||
|
|
@ -302,9 +306,14 @@
|
|||
$detailView.find('.ui-tabs-panel .detail-group.actions')
|
||||
).fadeIn();
|
||||
|
||||
$detailView.find('.tagger').removeClass('readonly');
|
||||
$detailView.find('.tagger').find('input[type=text]').val('');
|
||||
|
||||
var convertInputs = function($inputs) {
|
||||
// Save and turn back into labels
|
||||
$inputs.each(function() {
|
||||
if ($(this).closest('.tagger').size()) return true;
|
||||
|
||||
var $input = $(this);
|
||||
var $value = $input.closest('td.value span');
|
||||
|
||||
|
|
@ -328,8 +337,12 @@
|
|||
};
|
||||
|
||||
var removeEditForm = function() {
|
||||
$detailView.removeClass('edit-mode');
|
||||
|
||||
// Remove Edit form
|
||||
var $form = $detailView.find('form');
|
||||
var $form = $detailView.find('form').filter(function() {
|
||||
return !$(this).closest('.tagger').size();
|
||||
});
|
||||
if ($form.size()) {
|
||||
var $mainGroups = $form.find('div.main-groups').detach();
|
||||
$form.parent('div').append($mainGroups);
|
||||
|
|
@ -337,11 +350,15 @@
|
|||
}
|
||||
//Remove required labels
|
||||
$detailView.find('span.field-required').remove();
|
||||
}
|
||||
$detailView.find('.tagger').addClass('readonly');
|
||||
|
||||
};
|
||||
|
||||
// Put in original values
|
||||
var cancelEdits = function($inputs, $editButton) {
|
||||
$inputs.each(function() {
|
||||
if ($(this).closest('.tagger').size()) return true;
|
||||
|
||||
var $input = $(this);
|
||||
var $value = $input.closest('td.value span');
|
||||
var originalValue = $input.data('original-value');
|
||||
|
|
@ -424,8 +441,12 @@
|
|||
};
|
||||
|
||||
$editButton.click(function() {
|
||||
var $inputs = $detailView.find('input, select'),
|
||||
$form = $detailView.find('form');
|
||||
var $inputs = $detailView.find('input, select').filter(function() {
|
||||
return !$(this).closest('.tagger').size();
|
||||
});
|
||||
var $form = $detailView.find('form').filter(function() {
|
||||
return !$(this).closest('.tagger').size();
|
||||
});
|
||||
|
||||
if ($(this).hasClass('done')) {
|
||||
if (!$form.valid()) {
|
||||
|
|
@ -438,6 +459,8 @@
|
|||
} else { // Cancel
|
||||
cancelEdits($inputs, $editButton);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$detailView.find('td.value span').each(function() {
|
||||
|
|
@ -511,8 +534,11 @@
|
|||
}
|
||||
|
||||
// Setup form validation
|
||||
$detailView.find('form').validate();
|
||||
$detailView.find('form').find('input, select').each(function() {
|
||||
var $form = $detailView.find('form').filter(function() {
|
||||
return !$(this).closest('.tagger').size();
|
||||
});
|
||||
$form.validate();
|
||||
$form.find('input, select').each(function() {
|
||||
var data = $(this).parent('span').data('validation-rules');
|
||||
if (data) {
|
||||
$(this).rules('add', data);
|
||||
|
|
@ -934,6 +960,14 @@
|
|||
actionFilter: actionFilter
|
||||
}).appendTo($tabContent);
|
||||
|
||||
if (tabs.tags) {
|
||||
$('<div>').tagger(
|
||||
$.extend(true, {}, tabs.tags, {
|
||||
context: $detailView.data('view-args').context
|
||||
})
|
||||
).appendTo($detailView.find('.main-groups')).addClass('readonly');
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
error: function() {
|
||||
|
|
|
|||
|
|
@ -333,10 +333,16 @@
|
|||
after: function(args) {
|
||||
var $loading = $('<div>').addClass('loading-overlay').prependTo($dataItem);
|
||||
performAction({ data: args.data, complete: function() {
|
||||
$multi.multiEdit('refresh');
|
||||
$multi.trigger('refresh');
|
||||
} });
|
||||
}
|
||||
});
|
||||
|
||||
if (options.tags) {
|
||||
$(':ui-dialog').append(
|
||||
$('<div>').addClass('multi-edit-tags').tagger(options.tags)
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
@ -652,6 +658,7 @@
|
|||
$.fn.multiEdit = function(args) {
|
||||
var dataProvider = args.dataProvider;
|
||||
var multipleAdd = args.multipleAdd;
|
||||
var tags = args.tags;
|
||||
var $multi = $('<div>').addClass('multi-edit').appendTo(this);
|
||||
var $multiForm = $('<form>').appendTo($multi);
|
||||
var $inputTable = $('<table>').addClass('multi-edit').appendTo($multiForm);
|
||||
|
|
@ -918,7 +925,8 @@
|
|||
context: $.extend(true, {}, context, this._context),
|
||||
ignoreEmptyFields: ignoreEmptyFields,
|
||||
preFilter: actionPreFilter,
|
||||
listView: listView
|
||||
listView: listView,
|
||||
tags: tags
|
||||
}
|
||||
).appendTo($dataBody);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,201 @@
|
|||
(function($, cloudStack) {
|
||||
var elems = {
|
||||
inputArea: function(args) {
|
||||
var $form = $('<form>').addClass('tag-input');
|
||||
var $keyField = $('<div>').addClass('field key');
|
||||
var $keyLabel = $('<label>').attr('for', 'key').html('Key:');
|
||||
var $key = $('<input>').addClass('key required').attr('name', 'key');
|
||||
var $valueField = $('<div>').addClass('field value');
|
||||
var $valueLabel = $('<label>').attr('for', 'value').html('Value:');
|
||||
var $value = $('<input>').addClass('value required').attr('name', 'value');
|
||||
var $submit = $('<input>').attr('type', 'submit').val('Add');
|
||||
|
||||
$keyField.append($keyLabel, $key);
|
||||
$valueField.append($valueLabel, $value);
|
||||
$form.append(
|
||||
$keyField, $valueField,
|
||||
$submit
|
||||
);
|
||||
|
||||
$form.validate({ onfocusout: false });
|
||||
|
||||
$form.submit(
|
||||
args.onSubmit ?
|
||||
function() {
|
||||
if (!$form.valid()) return false;
|
||||
|
||||
args.onSubmit({
|
||||
data: cloudStack.serializeForm($form),
|
||||
response: {
|
||||
success: function() {
|
||||
// Restore editing of input
|
||||
$key.attr('disabled', false);
|
||||
$value.attr('disabled', false);
|
||||
|
||||
// Clear out old data
|
||||
$key.val(''); $value.val('');
|
||||
$key.focus();
|
||||
},
|
||||
error: function() {
|
||||
// Restore editing of input
|
||||
$key.attr('disabled', false);
|
||||
$value.attr('disabled', false);
|
||||
$key.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent input during submission
|
||||
$key.attr('disabled', 'disabled');
|
||||
$value.attr('disabled', 'disabled');
|
||||
|
||||
return false;
|
||||
} :
|
||||
function() { return false; }
|
||||
);
|
||||
|
||||
return $form;
|
||||
},
|
||||
tagItem: function(title, onRemove, data) {
|
||||
var $li = $('<li>');
|
||||
var $label = $('<span>').addClass('label').html(title);
|
||||
var $remove = $('<span>').addClass('remove').html('X');
|
||||
|
||||
$remove.click(function() {
|
||||
if (onRemove) onRemove($li, data);
|
||||
});
|
||||
|
||||
$li.append($remove, $label);
|
||||
|
||||
return $li;
|
||||
},
|
||||
|
||||
info: function(text) {
|
||||
var $info = $('<div>').addClass('tag-info');
|
||||
var $text = $('<span>').html(text);
|
||||
|
||||
$text.appendTo($info);
|
||||
|
||||
return $info;
|
||||
}
|
||||
};
|
||||
|
||||
$.widget('cloudStack.tagger', {
|
||||
_init: function(args) {
|
||||
var context = this.options.context;
|
||||
var dataProvider = this.options.dataProvider;
|
||||
var actions = this.options.actions;
|
||||
var $container = this.element.addClass('tagger');
|
||||
var $tagArea = $('<ul>').addClass('tags');
|
||||
var $title = elems.info('Tags').addClass('title');
|
||||
var $loading = $('<div>').addClass('loading-overlay');
|
||||
|
||||
var onRemoveItem = function($item, data) {
|
||||
$loading.appendTo($container);
|
||||
actions.remove({
|
||||
context: $.extend(true, {}, context, {
|
||||
tagItems: [data]
|
||||
}),
|
||||
response: {
|
||||
success: function(args) {
|
||||
var notification = $.extend(true, {} , args.notification, {
|
||||
interval: 500,
|
||||
_custom: args._custom
|
||||
});
|
||||
|
||||
cloudStack.ui.notifications.add(
|
||||
notification,
|
||||
|
||||
// Success
|
||||
function() {
|
||||
$loading.remove();
|
||||
$item.remove();
|
||||
}, {},
|
||||
|
||||
// Error
|
||||
function() {
|
||||
$loading.remove();
|
||||
}, {}
|
||||
);
|
||||
},
|
||||
error: function(message) {
|
||||
$loading.remove();
|
||||
cloudStack.dialog.notice({ message: message });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var $inputArea = elems.inputArea({
|
||||
onSubmit: function(args) {
|
||||
var data = args.data;
|
||||
var success = args.response.success;
|
||||
var error = args.response.error;
|
||||
var title = data.key + ' = ' + data.value;
|
||||
|
||||
$loading.appendTo($container);
|
||||
actions.add({
|
||||
data: data,
|
||||
context: context,
|
||||
response: {
|
||||
success: function(args) {
|
||||
var notification = $.extend(true, {} , args.notification, {
|
||||
interval: 500,
|
||||
_custom: args._custom
|
||||
});
|
||||
|
||||
cloudStack.ui.notifications.add(
|
||||
notification,
|
||||
|
||||
// Success
|
||||
function() {
|
||||
$loading.remove();
|
||||
elems.tagItem(title, onRemoveItem, data).appendTo($tagArea);
|
||||
success();
|
||||
}, {},
|
||||
|
||||
// Error
|
||||
function() {
|
||||
$loading.remove();
|
||||
error();
|
||||
}, {}
|
||||
);
|
||||
},
|
||||
error: function(message) {
|
||||
$loading.remove();
|
||||
error();
|
||||
cloudStack.dialog.notice({ message: message });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$container.append($title, $inputArea, $tagArea);
|
||||
|
||||
// Get data
|
||||
$loading.appendTo($container);
|
||||
dataProvider({
|
||||
context: context,
|
||||
response: {
|
||||
success: function(args) {
|
||||
var data = args.data;
|
||||
|
||||
$loading.remove();
|
||||
$(data).map(function(index, item) {
|
||||
var key = item.key;
|
||||
var value = item.value;
|
||||
var data = { key: key, value: value };
|
||||
|
||||
elems.tagItem(key + ' = ' + value, onRemoveItem, data).appendTo($tagArea);
|
||||
});
|
||||
},
|
||||
error: function(message) {
|
||||
$loading.remove();
|
||||
$container.find('ul').html(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}(jQuery, cloudStack));
|
||||
Loading…
Reference in New Issue