Skip to content

Commit 4a96a20

Browse files
committed
Merge branch 'master' into ui-plugins
2 parents 2cb50b1 + 606fa9d commit 4a96a20

41 files changed

Lines changed: 1918 additions & 436 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

INSTALL.md

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,21 @@ Apache CloudStack uses some ports, make sure at least those used by the manageme
5151
server are available and not blocked by any local firewall. Following ports are
5252
used by Apache CloudStack and its entities:
5353

54-
8787: Apache CloudStack (Tomcat) debug socket
55-
9090, 8250, 8080: Apache CloudStack Management Server, User/Client API
56-
8096: User/Client to CloudStack Management Server (unauthenticated)
57-
7080: AWS API Server
58-
3306: MySQL Server
59-
3922, 8250, 80/443, 111/2049, 53: Secondary Storage VM
60-
3922, 8250, 53: Console Proxy VM
61-
3922, 8250, 53: Virtual Router
54+
8080: API Server (authenticated), browser or CLI client to management server
55+
8096: API Server (unauthenticated), browser or CLI client to management server
56+
8787: Remote java debug debugging port, from IDE to management server
57+
9090: Management server to management server (cluster)
58+
7080: AWS API Server to which an AWS client can connect
59+
80/443: HTTP client to Secondary Storage VM (template download)
60+
111/2049: Secondary Storage to NFS server
61+
3922: Port used to ssh/scp into system vms (SSVM, CPVM, VR)
62+
8250: Agent (SSVM, CPVM, VR) to management server
6263
22, 80, 443: XenServer, XAPI
6364
22: KVM
6465
443: vCenter
65-
DNS: 53
66-
NFS: 111/2049
66+
53: DNS
67+
111/2049: NFS
68+
3306: MySQL Server to which the management server connects
6769

6870
### Configuring MySQL Server
6971

@@ -93,8 +95,7 @@ For example, for master:
9395

9496
Clean and build:
9597

96-
$ mvn clean
97-
$ mvn install
98+
$ mvn clean install -P systemvm,developer
9899

99100
In case you want support for VMWare, SRX and other non-Apache (referred to as nonoss)
100101
compliant libs, you may download the following jar artifacts from respective vendors:
@@ -112,17 +113,17 @@ Install them to ~/.m2 so maven can get them as dependencies:
112113
$ cd deps
113114
$ ./install-non-oss.sh
114115

115-
And build them with the nonoss flag:
116+
To build with nonoss components, use the build command with the nonoss flag:
116117

117-
$ mvn install -Dnonoss
118+
$ mvn clean install -P systemvm,developer -Dnonoss
118119

119120
Clear old database (if any) and deploy the database schema:
120121

121122
$ mvn -P developer -pl developer -Ddeploydb
122123

123124
Export the following variable if you need to run and debug the management server:
124125

125-
$ export MAVEN_OPTS="-Xmx1024m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
126+
$ export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=500m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
126127

127128
Start the management server:
128129

api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public void execute(){
5252
response.setProjectInviteRequired((Boolean)capabilities.get("projectInviteRequired"));
5353
response.setAllowUsersCreateProjects((Boolean)capabilities.get("allowusercreateprojects"));
5454
response.setDiskOffMaxSize((Long)capabilities.get("customDiskOffMaxSize"));
55+
response.setApiLimitInterval((Integer)capabilities.get("apiLimitInterval"));
56+
response.setApiLimitMax((Integer)capabilities.get("apiLimitMax"));
5557
response.setObjectName("capability");
5658
response.setResponseName(getCommandName());
5759
this.setResponseObject(response);

api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ public class CapabilitiesResponse extends BaseResponse {
4646
"create disk from disk offering with custom size")
4747
private Long diskOffMaxSize;
4848

49+
@SerializedName("apilimitinterval") @Param(description="time interval (in seconds) to reset api count")
50+
private Integer apiLimitInterval;
51+
52+
@SerializedName("apilimitmax") @Param(description="Max allowed number of api requests within the specified interval")
53+
private Integer apiLimitMax;
54+
4955

5056
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
5157
this.securityGroupsEnabled = securityGroupsEnabled;
@@ -75,4 +81,13 @@ public void setDiskOffMaxSize(Long diskOffMaxSize) {
7581
this.diskOffMaxSize = diskOffMaxSize;
7682
}
7783

84+
public void setApiLimitInterval(Integer apiLimitInterval) {
85+
this.apiLimitInterval = apiLimitInterval;
86+
}
87+
88+
public void setApiLimitMax(Integer apiLimitMax) {
89+
this.apiLimitMax = apiLimitMax;
90+
}
91+
92+
7893
}

awsapi/src/com/cloud/bridge/service/EC2RestServlet.java

Lines changed: 133 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import com.amazon.ec2.DisassociateAddressResponse;
8888
import com.amazon.ec2.GetPasswordDataResponse;
8989
import com.amazon.ec2.ImportKeyPairResponse;
90+
import com.amazon.ec2.LaunchPermissionItemType;
9091
import com.amazon.ec2.ModifyImageAttributeResponse;
9192
import com.amazon.ec2.RebootInstancesResponse;
9293
import com.amazon.ec2.RegisterImageResponse;
@@ -104,14 +105,17 @@
104105
import com.cloud.bridge.persist.dao.OfferingDaoImpl;
105106
import com.cloud.bridge.persist.dao.UserCredentialsDaoImpl;
106107
import com.cloud.bridge.service.controller.s3.ServiceProvider;
108+
import com.cloud.bridge.service.core.ec2.EC2AddressFilterSet;
107109
import com.cloud.bridge.service.core.ec2.EC2AssociateAddress;
108110
import com.cloud.bridge.service.core.ec2.EC2AuthorizeRevokeSecurityGroup;
111+
import com.cloud.bridge.service.core.ec2.EC2AvailabilityZonesFilterSet;
109112
import com.cloud.bridge.service.core.ec2.EC2CreateImage;
110113
import com.cloud.bridge.service.core.ec2.EC2CreateKeyPair;
111114
import com.cloud.bridge.service.core.ec2.EC2CreateVolume;
112115
import com.cloud.bridge.service.core.ec2.EC2DeleteKeyPair;
113116
import com.cloud.bridge.service.core.ec2.EC2DescribeAddresses;
114117
import com.cloud.bridge.service.core.ec2.EC2DescribeAvailabilityZones;
118+
import com.cloud.bridge.service.core.ec2.EC2DescribeImageAttribute;
115119
import com.cloud.bridge.service.core.ec2.EC2DescribeImages;
116120
import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
117121
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
@@ -123,10 +127,13 @@
123127
import com.cloud.bridge.service.core.ec2.EC2Filter;
124128
import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet;
125129
import com.cloud.bridge.service.core.ec2.EC2Image;
130+
import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute;
131+
import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission;
126132
import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair;
127133
import com.cloud.bridge.service.core.ec2.EC2InstanceFilterSet;
128134
import com.cloud.bridge.service.core.ec2.EC2IpPermission;
129135
import com.cloud.bridge.service.core.ec2.EC2KeyPairFilterSet;
136+
import com.cloud.bridge.service.core.ec2.EC2ModifyImageAttribute;
130137
import com.cloud.bridge.service.core.ec2.EC2RebootInstances;
131138
import com.cloud.bridge.service.core.ec2.EC2RegisterImage;
132139
import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress;
@@ -1021,38 +1028,105 @@ private void registerImage( HttpServletRequest request, HttpServletResponse resp
10211028
serializeResponse(response, EC2response);
10221029
}
10231030

1024-
private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response )
1031+
private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response )
10251032
throws ADBException, XMLStreamException, IOException {
1026-
EC2Image image = new EC2Image();
1033+
EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute();
10271034

1028-
// -> its interesting to note that the SOAP API docs has description but the REST API docs do not
1029-
String[] imageId = request.getParameterValues( "ImageId" );
1030-
if ( null != imageId && 0 < imageId.length )
1031-
image.setId( imageId[0] );
1032-
else { response.sendError(530, "Missing ImageId parameter" ); return; }
1035+
String[] imageId = request.getParameterValues( "ImageId" );
1036+
if ( imageId != null && imageId.length > 0 )
1037+
ec2request.setImageId( imageId[0]);
1038+
else {
1039+
response.sendError(530, "Missing ImageId parameter" );
1040+
return;
1041+
}
10331042

1034-
String[] description = request.getParameterValues( "Description" );
1035-
if ( null != description && 0 < description.length )
1036-
image.setDescription( description[0] );
1037-
else { response.sendError(530, "Missing Description parameter" ); return; }
1043+
String[] description = request.getParameterValues( "Description.Value" );
1044+
if ( description != null && description.length > 0 ) {
1045+
ec2request.setAttribute(ImageAttribute.description);
1046+
ec2request.setDescription(description[0]);
1047+
} else {
1048+
//add all launch permissions to ec2request
1049+
ec2request = addLaunchPermImageAttribute(request, ec2request);
1050+
if (ec2request.getLaunchPermissionSet().length > 0)
1051+
ec2request.setAttribute(ImageAttribute.launchPermission);
1052+
else {
1053+
response.sendError(530, "Missing Attribute parameter - Description/LaunchPermission should be provided" );
1054+
return;
1055+
}
1056+
}
10381057

10391058
// -> execute the request
1040-
ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image ));
1059+
ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse(
1060+
ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request ));
10411061
serializeResponse(response, EC2response);
10421062
}
10431063

1064+
private EC2ModifyImageAttribute addLaunchPermImageAttribute(HttpServletRequest request, EC2ModifyImageAttribute ec2request) {
1065+
String[] users = {".UserId", ".Group"};
1066+
String[] operations = {"LaunchPermission.Add.", "LaunchPermission.Remove."};
1067+
int nCount = 1;
1068+
1069+
for (int i = 0; i < 2; i++) {
1070+
for (int j = 0; j < 2; j++) {
1071+
List<String> launchPermissionList = new ArrayList<String>();
1072+
do {
1073+
String[] launchPermissionAddGroup = request.getParameterValues( operations[j] + nCount + users[i] );
1074+
if (launchPermissionAddGroup != null && launchPermissionAddGroup.length > 0)
1075+
launchPermissionList.add(launchPermissionAddGroup[0]);
1076+
else
1077+
break;
1078+
nCount++;
1079+
} while (true);
1080+
if (nCount != 1) {
1081+
EC2ImageLaunchPermission ec2LaunchPermission = new EC2ImageLaunchPermission();
1082+
if (operations[j].contains("Add"))
1083+
ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add);
1084+
else
1085+
ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove);
1086+
for (String launchPerm : launchPermissionList) {
1087+
ec2LaunchPermission.addLaunchPermission(launchPerm);
1088+
}
1089+
ec2request.addLaunchPermission(ec2LaunchPermission);
1090+
nCount = 1;
1091+
}
1092+
}
1093+
}
1094+
1095+
return ec2request;
1096+
}
1097+
10441098
private void resetImageAttribute( HttpServletRequest request, HttpServletResponse response )
10451099
throws ADBException, XMLStreamException, IOException {
1046-
EC2Image image = new EC2Image();
1100+
EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute();
10471101

10481102
String[] imageId = request.getParameterValues( "ImageId" );
1049-
if ( null != imageId && 0 < imageId.length )
1050-
image.setId( imageId[0] );
1051-
else { response.sendError(530, "Missing ImageId parameter" ); return; }
1103+
if ( imageId != null && imageId.length > 0)
1104+
ec2request.setImageId(imageId[0]);
1105+
else {
1106+
response.sendError(530, "Missing ImageId parameter" );
1107+
return;
1108+
}
1109+
1110+
String[] attribute = request.getParameterValues( "Attribute" );
1111+
if ( attribute != null && attribute.length > 0 ) {
1112+
if (attribute[0].equalsIgnoreCase("launchPermission"))
1113+
ec2request.setAttribute(ImageAttribute.launchPermission);
1114+
else {
1115+
response.sendError(501, "Unsupported Attribute - only launchPermission supported" );
1116+
return;
1117+
}
1118+
} else {
1119+
response.sendError(530, "Missing Attribute parameter" );
1120+
return;
1121+
}
1122+
1123+
EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission();
1124+
launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset);
1125+
ec2request.addLaunchPermission(launchPermission);
10521126

10531127
// -> execute the request
1054-
image.setDescription( "" );
1055-
ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image ));
1128+
ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse(
1129+
ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request ));
10561130
serializeResponse(response, EC2response);
10571131
}
10581132

@@ -1214,6 +1288,17 @@ private void describeAvailabilityZones( HttpServletRequest request, HttpServletR
12141288
if (null != value && 0 < value.length) EC2request.addZone( value[0] );
12151289
}
12161290
}
1291+
1292+
// add filters
1293+
EC2Filter[] filterSet = extractFilters( request );
1294+
if ( filterSet != null ) {
1295+
EC2AvailabilityZonesFilterSet afs = new EC2AvailabilityZonesFilterSet();
1296+
for( int i=0; i < filterSet.length; i++ ) {
1297+
afs.addFilter(filterSet[i]);
1298+
}
1299+
EC2request.setFilterSet( afs );
1300+
}
1301+
12171302
// -> execute the request
12181303
DescribeAvailabilityZonesResponse EC2response = EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse( ServiceProvider.getInstance().getEC2Engine().handleRequest( EC2request ));
12191304
serializeResponse(response, EC2response);
@@ -1240,25 +1325,35 @@ private void describeImages( HttpServletRequest request, HttpServletResponse res
12401325

12411326
private void describeImageAttribute( HttpServletRequest request, HttpServletResponse response )
12421327
throws ADBException, XMLStreamException, IOException {
1243-
EC2DescribeImages EC2request = new EC2DescribeImages();
1328+
EC2DescribeImageAttribute ec2request = new EC2DescribeImageAttribute();
12441329

1245-
// -> only works for queries about descriptions
1246-
String[] descriptions = request.getParameterValues( "Description" );
1247-
if ( null != descriptions && 0 < descriptions.length ) {
1248-
String[] value = request.getParameterValues( "ImageId" );
1249-
EC2request.addImageSet( value[0] );
1250-
}
1330+
String[] imageId = request.getParameterValues( "ImageId" );
1331+
if (imageId != null && imageId.length > 0)
1332+
ec2request.setImageId(imageId[0]);
12511333
else {
1252-
response.sendError(501, "Unsupported - only description supported" );
1334+
response.sendError(530, "Missing ImageId parameter");
12531335
return;
12541336
}
12551337

1256-
// -> execute the request
1257-
DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().describeImages( EC2request ));
1338+
String[] attribute = request.getParameterValues( "Attribute" );
1339+
if (attribute != null && attribute.length > 0) {
1340+
if (attribute[0].equalsIgnoreCase("description"))
1341+
ec2request.setAttribute(ImageAttribute.description);
1342+
else if (attribute[0].equalsIgnoreCase("launchPermission"))
1343+
ec2request.setAttribute(ImageAttribute.launchPermission);
1344+
else {
1345+
response.sendError(501, "Unsupported Attribute - description and launchPermission supported" );
1346+
return;
1347+
}
1348+
} else {
1349+
response.sendError(530, "Missing Attribute parameter");
1350+
return;
1351+
}
1352+
1353+
DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().describeImageAttribute( ec2request ));
12581354
serializeResponse(response, EC2response);
12591355
}
12601356

1261-
12621357
private void describeInstances( HttpServletRequest request, HttpServletResponse response )
12631358
throws ADBException, XMLStreamException, IOException
12641359
{
@@ -1303,6 +1398,15 @@ private void describeAddresses( HttpServletRequest request, HttpServletResponse
13031398
if (null != value && 0 < value.length) ec2Request.addPublicIp( value[0] );
13041399
}
13051400
}
1401+
1402+
// add filters
1403+
EC2Filter[] filterSet = extractFilters( request );
1404+
if ( filterSet != null ) {
1405+
EC2AddressFilterSet afs = new EC2AddressFilterSet();
1406+
for ( int i=0; i < filterSet.length; i++ )
1407+
afs.addFilter( filterSet[i] );
1408+
ec2Request.setFilterSet( afs );
1409+
}
13061410
// -> execute the request
13071411
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
13081412
serializeResponse(response, EC2SoapServiceImpl.toDescribeAddressesResponse( engine.describeAddresses( ec2Request)));

0 commit comments

Comments
 (0)