This guide provides you with a quick start on how to communicate with the XMS component of XLcloud through its REST API. It covers the basics of how to securely connect to XMS, create a new user, create a stack from a ready-made stack blueprint, and run that stack. A complete list of all the available operations (including example requests, responses and possible error codes and their reasons) can be found in the XMS API Reference.
XMS REST API uses OAuth 2.0 for request authorization. In order to call XMS, you need an access token. This prevents non-authorized users from interacting with your cloud. Tokens are valid only for a certain configurable period of time, after which they will be automatically revoked. For details on how to acquire a valid access token from XLcloud IAM system, go to the Identity and Access Management section of the API Reference.
Most requests sent to the XLcloud REST API should contain the following parts (here, presented as a cURL command):
where:
The following snippets will take you step-by-step through the process of creating the fundamental entities of XMS – accounts, users, projects and stacks.
This part requires a platform administrator token, because only platform administrators are able to manage accounts. Hence, we will assume that you have already received the token that will allow you to create a new account. To create a new account:
Request
POST http://integ:8080/xlcloud-xms/accounts
{
"name": "amg-account"
}
Response
{
"id": 189,
"href": "accounts/189",
"name": "amg-account",
"osProjectId": "829622121fd74ac2b180bb3e9cab9627"
}
You can see that XMS replies by returning the details of the newly created account. The ID will be particularly useful in the next step.
Now, to add a new user to the account we created:
Request
POST http://integ:8080/xlcloud-xms/accounts/189/users
{
"username": "amg-admin",
"password": "amg.admin123"
}
Response
{
"id": 197,
"href": "users/197",
"username": "amg-admin",
"accountId": 189,
"osUserId": "54f60d3060ee4a5ebfe875d36bec6a8a"
}
Again, details of the created user are returned, and XMS automatically assigned this user to our account. Note that we used the ID of the account in the request path.
By default, newly created users only have entitlements related to managing their profile. Hence, we need to grant this user entitlements allowing him to accomplish what we need to do in this guide. The easiest way to do this is to assign him to an appropriate group. Groups define entitlements, and make assigning privileges easier. Whenever a new account is created, default groups are created for that account. To list all groups available in the account:
Request
GET http://integ:8080/xlcloud-xms/accounts/189/groups{{/code}}
Response
{
"group": [
{
"users": {
"user": []
},
"id": 216,
"href": "groups/216",
"name": "member",
"description": "Account members group that allows to view account resources and public catalogs.",
"accountId": 189
},
{
"users": {
"user": []
},
"id": 231,
"href": "groups/231",
"name": "power",
"description": "Account power users group that allows to manage stack lifecycles within the account.",
"accountId": 189
},
{
"users": {
"user": []
},
"id": 201,
"href": "groups/201",
"name": "admin",
"description": "Account administrators group that allows to fully operate on account resources.",
"accountId": 189
}
],
"href": "/accounts/189/groups"
}
Out of the three returned groups, the "admin" group is the one we need. To assign our user to that group:
Request
PUT http://integ:8080/xlcloud-xms/groups/201/users/197
For this request, not response body is returned. Once more, we use IDs to identify entities (the group and the user in this case).
Stacks need to be part of a project and cannot just float somewhere in your cloud. You will need the account ID of the user you just created (in this case, 189) in order to create a new project. To do this:
Request
POST http://integ:8080/xlcloud-xms/accounts/189/projects
{
"name": "amg_demo_project"
}
Response
{
"projectEnvironment": {
"networkConfiguration": {
"subnets": {
"subnet": [
{
"uuid": "05a7e389-a1c3-4625-817c-9c84551ae136",
"name": "amg_demo_project_first_subnet",
"cidr": "10.0.0.0/16"
}
]
},
"defaultSubnetName": "amg_demo_project_first_subnet"
}
},
"id": 215,
"href": "projects/215",
"name": "amg_demo_project",
"accountId": 189,
"osProjectId": "6b2bad11a2eb4cacb1a193368798257f",
"status": "starting"
}
This initiated the project startup. To check the current status of the project:
Request
GET http://integ:8080/xlcloud-xms/projects/215
Response
{
"id": 215,
"href": "projects/215",
"name": "amg_demo_project",
"accountId": 189,
"osProjectId": "6b2bad11a2eb4cacb1a193368798257f",
"status": "active"
}
Once the project is up an running (it's status is "active"), we can create a stack. The easiest way to do this is to utilize a stack blueprint. Stack blueprints are ready-made stacks, that can be cloned, and started with a minimal amount of configuration. First, we need to browse the stack blueprints catalog and chose one. To see available public stack blueprints:
Request
GET http://integ:8080/xlcloud-xms/stack-blueprints
Response
{
"stackBlueprint": [
{
"layers": {
"layer": [
{
"id": 1,
"href": "/layer-blueprints/1",
"parametersValues": {},
"name": "Slurm",
"template": {},
"author": "AMG.net",
"license": "freeware",
"type": "slurm",
"catalogScope": "public",
"stackBlueprintId": 1
},
{
"id": 2,
"href": "/layer-blueprints/2",
"parametersValues": {},
"name": "Monitor",
"template": {},
"author": "AMG.net",
"license": "freeware",
"type": "slurm",
"catalogScope": "public",
"stackBlueprintId": 1
}
]
},
"id": 1,
"href": "/stack-blueprints/1",
"parametersValues": {},
"name": "Slurm_Stack",
"template": {},
"author": "AMG.net",
"license": "freeware",
"type": "slurm",
"catalogScope": "public"
}
],
"href": "/stack-blueprints"
}
We can now create a stack using a blueprint (in this case, we choose the only blueprint available – with ID
1). To create such a stack:
Request
POST http://integ:8080/xlcloud-xms/projects/215/stacks?blueprintId=1
{
"name": "AMGTestStack"
}
Response
{
"layers": {
"layer": [
{
"id": 20,
"href": "layers/20",
"parametersValues": {},
"name": "Slurm",
"accountId": 100,
"template": {},
"stackId": 2
},
{
"id": 21,
"href": "layers/21",
"parametersValues": {},
"name": "Monitor",
"accountId": 100,
"template": {},
"stackId": 2
}
]
},
"id": 2,
"href": "stacks/2",
"parametersValues": {
"parametersValues": [
{
"value": "63613",
"name": "xlcloud:brokerPort"
},
{
"value": "8649",
"name": "MonitorPort"
},
{
"value": "2",
"name": "xlcloud:Computes:size"
},
{
"value": "m1.small",
"name": "xlcloud:defaultInstanceType"
},
{
"value": "xlcloud",
"name": "xlcloud:brokerUsername"
},
{
"value": "SLURM",
"name": "xlcloud:monitoringCluster"
},
{
"value": "xlcloud",
"name": "xlcloud:brokerPassword"
},
{
"value": "F19-x86_64-xlcloud",
"name": "xlcloud:defaultImageId"
}
]
},
"name": "AMGTestStack",
"accountId": 189,
"template": {
"Outputs": {
"MonitorURL": {
"Value": {
"Fn::GetAtt": [
"Monitor",
"Outputs.PublicURL"
]
},
"Description": "Public URL of the monitoring node"
},
"LoginIP": {
"Value": {
"Fn::GetAtt": [
"Slurm",
"Outputs.LoginAddress"
]
},
"Description": "Public address of the login node"
},
"xlcloud:xsaAddress": {
"Value": {
"Fn::Join": [
"",
[
"http://",
{
"Fn::GetAtt": [
"Slurm",
"Outputs.xsaIp"
]
},
":8080/xsa"
]
]
},
"Description": "XSA URL"
}
},
"Parameters": {
"xlcloud:brokerPort": {
"Default": "63613",
"Description": "RabbitMQ broker port",
"Type": "String"
},
"xlcloud:defaultKeyName": {
"Description": "Name of an existing EC2 KeyPair to enable SSH access",
"Type": "String"
},
"MonitorPort": {
"Default": "8649",
"Description": "TCP port of monitoring traffic data",
"Type": "String"
},
"xlcloud:brokerAddress": {
"Description": "RabbitMQ broker address",
"Type": "String"
},
"xlcloud:Computes:size": {
"Default": "2",
"Description": "Number of compute nodes to launch",
"Type": "String"
},
"xlcloud:brokerUsername": {
"Default": "xlcloud",
"Description": "RabbitMQ broker username",
"Type": "String"
},
"xlcloud:defaultInstanceType": {
"Default": "m1.small",
"AllowedValues": [
"m1.tiny",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge"
],
"Description": "Default instance type (flavor) for instances in this stack",
"Type": "String",
"ConstraintDescription": "must be a valid XLcloud instance type."
},
"xlcloud:monitoringCluster": {
"Default": "SLURM",
"Description": "Name of the cluster in the monitoring system",
"Type": "String",
"AllowedPattern": "[a-z|A-Z|0-9]*"
},
"xlcloud:brokerPassword": {
"Default": "xlcloud",
"Description": "RabbitMQ broker password",
"Type": "String"
},
"xlcloud:defaultImageId": {
"Default": "F19-x86_64-xlcloud",
"AllowedValues": [
"F19-x86_64-xlcloud"
],
"Description": "Default image name for instances in this stack",
"Type": "String",
"ConstraintDescription": "Must be a valid XLcloud image name."
}
},
"Description": "XLcloud Slurm Stack",
"AWSTemplateFormatVersion": "",
"Resources": {
"Monitor": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"Parameters": {
"xlcloud:brokerPort": {
"Ref": "xlcloud:brokerPort"
},
"xlcloud:defaultKeyName": {
"Ref": "xlcloud:defaultKeyName"
},
"MonitorPort": {
"Ref": "MonitorPort"
},
"xlcloud:brokerAddress": {
"Ref": "xlcloud:brokerAddress"
},
"xlcloud:brokerUsername": {
"Ref": "xlcloud:brokerUsername"
},
"xlcloud:defaultInstanceType": {
"Ref": "xlcloud:defaultInstanceType"
},
"xlcloud:layerSubnetUuid": "50e0c97a-46d8-4c32-87fa-8bf2de9febb4",
"xlcloud:stackId": {
"Ref": "AWS::StackId"
},
"xlcloud:monitoringCluster": {
"Ref": "xlcloud:monitoringCluster"
},
"xlcloud:brokerPassword": {
"Ref": "xlcloud:brokerPassword"
},
"xlcloud:defaultImageId": {
"Ref": "xlcloud:defaultImageId"
}
},
"TimeoutInMinutes": "5",
"TemplateURL": "layers/21"
}
},
"Slurm": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": "Monitor",
"Properties": {
"Parameters": {
"xlcloud:brokerPort": {
"Ref": "xlcloud:brokerPort"
},
"xlcloud:defaultKeyName": {
"Ref": "xlcloud:defaultKeyName"
},
"xlcloud:brokerAddress": {
"Ref": "xlcloud:brokerAddress"
},
"xlcloud:Computes:size": {
"Ref": "xlcloud:Computes:size"
},
"xlcloud:brokerUsername": {
"Ref": "xlcloud:brokerUsername"
},
"xlcloud:defaultInstanceType": {
"Ref": "xlcloud:defaultInstanceType"
},
"xlcloud:layerSubnetUuid": "50e0c97a-46d8-4c32-87fa-8bf2de9febb4",
"xlcloud:stackId": {
"Ref": "AWS::StackId"
},
"xlcloud:monitoringCluster": {
"Ref": "xlcloud:monitoringCluster"
},
"xlcloud:monitorIP": {
"Fn::GetAtt": [
"Monitor",
"Outputs.MonitorIP"
]
},
"xlcloud:brokerPassword": {
"Ref": "xlcloud:brokerPassword"
},
"xlcloud:defaultImageId": {
"Ref": "xlcloud:defaultImageId"
}
},
"TimeoutInMinutes": "40",
"TemplateURL": "layers/20"
}
}
}
},
"projectId": 215,
"stackOrigin": "from blueprint",
"blueprintId": 1
The response is pretty verbose, but the most important part for us is the ID – 2.
Starting a stack is even more secured. You will need to be authenticated with an SSH keypair. This keypair can be used later to connect with the instances of your stack. To generate a keypair:
Request
POST http://integ:8080/xlcloud-xms/users/197/os-keypairs/amg-test-keypair{
Response
{
"name": "amg-test-keypair",
"privateKey": "-BEGIN RSA PRIVATE KEY-\nMIIEpQIBAAKCAQEAr20T26hpJ5c4598Li1pJQugHnySQ6O/7ngAj7iN1U7tHC4k9\nidaVXxn8RMHeUDpkVB6HXxSEL6Z6Z/utzmQFY0sxi+d3rdpizZcaeJAbTC2csF4B\ntp5xwWRR8IlMkOPKcwRgBGyK3Xd9Ij3g8LriU1r+jIyZA9j1O9Ok07bHBBtqZZ1X\nPzHBar8ADKQ3Euc7BTQJcB1mwmWFHqnGdwaIgDTM+3q3dLkFOWUht/A7pKc8FZ7c\nNo6Qoa33Viwiy4hvWVOfXKzYj/e5kOr+bhyBwZb88FvUFIrUjGROM+Y8fVomcmIz\n8gxOpGKAHGNKw5D6nRO/7RFH40oVuaZ8O0apgQIDAQABAoIBAAmypwFiqwWER6IR\n44p9oEUxnJJArD4kXi2a5mGY1jidxsytdphzI2jRf++xJAAdakR4N5WbBb+4nVW4\nRSB+yQl3M7L/Rc93njStYMo/dTLd5qadW8zjr3g4eosom/H6lcuL917nPToHDATj\nlNbaDf77rczJTQA4cz4uchM+LHxejC6vUWKZFpnwGzbItFMtOqf0PtyRbE1vOsue\nGjtdqfiAx2NSomLNd9YvFMiyBCFgwyJwjzEzkdCTzs+/LNWrSmgpfvefUdMcs5nd\n75gYwEiXxFIdQChXIq6U6gSnwwXzti4xCICH59+JM1FSjWfM/C/Q2IjxhcYP7Li1\nIj3TtJ0CgYEA2wiGSZ88u+T/K/B+Q+jGz6Vjc8d+vlJDbHP+nlo/vCj9hOZK8TMc\nkIcVzZKf+W081ACXOaX66suSHTiA3x/bzKBBPqNAqxbbloXaMGCyNP4xNDjZw0Fw\noOLbbntOPr6iZPASsbPgssrguhfXc8qhMH1lPBzSQ/uEgQC1xbsmj68CgYEAzQh5\nnld/W+/4suhcR4pliVIvNf+nAURti23EZJBiFZpcPolZe/ZMWm+K04+Zi4iKYRKU\nD9JOnLX8PVqCB1aXXJi3bf/9xo/lU0N8GrdBtt6rLY58LofUP0U5+a7/4jU7mPUL\n+tGtzlcQYATWi9YS6IVvz4O/fDH4YlbblK9c8CgYEAj1t++QS97YSt9oZLPgtG\nxHVNKGQz8kFJW9x3lBEhkfeKJsfL2R5I3ddsT8Zd6hSzMVbJo7OdDLv8gB+RSXhC\nliV1TpfvJYuqYVRuQCepu8F7VuC2tnNIUiTo1eDij3KaO1JeCezfbmYWu/YK0ACZ\ni3EnJzb97/zY9s4OKsKZNIUCgYEAqaWDi8J1/Mo4C0A7am5WySKZMaLQujm2MhGm\n2Fam8Z0BCjV3Nxx53LJCOf6tW0ikxuEqZVTr+rqRdOp4gD3ji5hI3dlcT3kslJJY\nE3riAr+G/3DPy2hT8+4BpFhqHO9S2qKXQPdRSlO7ltcp9hYxGverCn6hnmzIpELI\noVsZbP0CgYEAnoAibwLmVJzvdNb1fDR6AH/sNOL/kNOV0CilVsb/Em6all/g5TdA\n2ZG5Krt/JePm3EHUvwxQXDjZ8Umv5sbPJi942pfTMNb+H5noSJ2RBXhKYYSjj7e4\nDiHXG1Egjj4FnhHUYIAGgSkt6z6udPeC6TObgH9Ivl4jmbEGAIszV8U=\n-END RSA PRIVATE KEY-\n",
"publicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvbRPbqGknlzjn3wuLWklC6AefJJDo7/ueACPuI3VTu0cLiT2J1pVfGfxEwd5QOmRUHodfFIQvpnpn+63OZAVjSzGL53et2mLNlxp4kBtMLZywXgG2nnHBZFHwiUyQ48pzBGAEbIrdd30iPeDwuuJTWv6MjJkD2PU706TTtscEG2plnVc/McFqvwAMpDcS5zsFNAlwHWbCZYUeqcZ3BoiANMz7erd0uQU5ZSG38DukpzwVntw2jpChrfdWLCLLiG9ZU59crNiP97mQ6v5uHIHBlvzwW9QUitSMZE4z5jx9WiZyYjPyDE6kYoAcY0rDkPqdE7/tEUfjShW5pnw7RqmB Generated by Nova\n",
"fingerprint": "5a:c8:85:e9:f8:08:f8:50:9c:4e:6e:02:6a:f0:b7:3f",
"href": "/users/197/os-keypairs/amg-test-keypair"
}
You should save your private key and store it securely. Now, we will select this keypair as the one to be used by the stack we created:
Request
PUT http://integ:8080/xlcloud-xms/stacks/2/parameters-values
{
"parametersValues": [
{
"name": "xlcloud:defaultKeyName",
"value": "amg-test-keyname"
}
]
}
Response
{
"parametersValues": [
{
"value": "63613",
"name": "xlcloud:brokerPort"
},
{
"value": "m1.small",
"name": "xlcloud:defaultInstanceType"
},
{
"value": "SLURM",
"name": "xlcloud:monitoringCluster"
},
{
"value": "xlcloud",
"name": "xlcloud:brokerPassword"
},
{
"value": "2",
"name": "xlcloud:Computes:size"
},
{
"value": "8649",
"name": "MonitorPort"
},
{
"value": "xlcloud",
"name": "xlcloud:brokerUsername"
},
{
"value": "F19-x86_64-xlcloud",
"name": "xlcloud:defaultImageId"
},
{
"value": "amg-test-keyname",
"name": "xlcloud:defaultKeyName"
}
]
}
Finally, we can start the stack:
Request
Response
{
"outputs": {},
"status": "configuring",
"statusReason": "Stack create completed successfully",
"physicalId": "9e2ba548-e64f-4036-804b-2889b009ccce"
}
Starting and configuring a stack can take time. To get the current status of the stack:
Response
{
"outputs": {
"output": [
{
"key": "LoginIP",
"description": "Public address of the login node",
"value": "10.197.217.161"
},
{
"key": "xlcloud:xsaAddress",
"description": "XSA URL",
"value": "http://10.197.217.161:8080/xsa"
},
{
"key": "MonitorURL",
"description": "Public URL of the monitoring node",
"value": "http://10.197.217.160/ganglia"
}
]
},
"resources": [
{
"logicalResourceId": "Slurm",
"resourceStatus": "running",
"physicalResourceId": "20f8cf1d-5c4c-4d4e-844f-ae3edf520c0c",
"resourceType": "AWS::CloudFormation::Stack"
},
{
"logicalResourceId": "Monitor",
"resourceStatus": "running",
"physicalResourceId": "44202b99-adc6-4203-b9b8-7ec194fdb627",
"resourceType": "AWS::CloudFormation::Stack"
},
{
"logicalResourceId": "ComputeHandle",
"resourceStatus": "running",
"physicalResourceId": "0e6f3f03c7cb428f933e9efa7649dcdc",
"resourceType": "AWS::CloudFormation::WaitConditionHandle"
},
{
"logicalResourceId": "LoginIpAssoc",
"resourceStatus": "running",
"physicalResourceId": "10.197.217.161",
"resourceType": "AWS::EC2::EIPAssociation"
},
{
"logicalResourceId": "LoginHandle",
"resourceStatus": "running",
"physicalResourceId": "249f4471afa543aa862823cfaacbc745",
"resourceType": "AWS::CloudFormation::WaitConditionHandle"
},
{
"logicalResourceId": "CfnUserKey",
"resourceStatus": "running",
"physicalResourceId": "6871b109f58f4db88115169222b3fb50",
"resourceType": "AWS::IAM::AccessKey"
},
{
"logicalResourceId": "CfnUser",
"resourceStatus": "running",
"physicalResourceId": "cb8e177922a94bf2b333029991ea9467",
"resourceType": "AWS::IAM::User"
},
{
"logicalResourceId": "LoginIp",
"resourceStatus": "running",
"physicalResourceId": "c942ee76-d813-4a59-8985-eda8bbaf9f22",
"resourceType": "AWS::EC2::EIP"
},
{
"logicalResourceId": "ComputeReady",
"resourceStatus": "running",
"physicalResourceId": "ComputeHandle",
"resourceType": "AWS::CloudFormation::WaitCondition"
},
{
"logicalResourceId": "LoginNetworkInterface",
"resourceStatus": "running",
"physicalResourceId": "35ff52e8-ba58-4b26-995b-8afe2672b6e8",
"resourceType": "AWS::EC2::NetworkInterface"
},
{
"logicalResourceId": "PrivateLayerSecurityGroup",
"resourceStatus": "running",
"physicalResourceId": "cd563569-e071-4278-94df-0a577edc0f8a",
"resourceType": "AWS::EC2::SecurityGroup"
},
{
"logicalResourceId": "Computes",
"resourceStatus": "running",
"physicalResourceId": "e1e97fa1-4d94-4578-9c78-cac4bb8ac499",
"resourceType": "AWS::AutoScaling::AutoScalingGroup"
},
{
"logicalResourceId": "ComputeConfiguration",
"resourceStatus": "running",
"resourceType": "AWS::AutoScaling::LaunchConfiguration"
},
{
"logicalResourceId": "ClusterMetaData",
"resourceStatus": "running",
"resourceType": "AWS::AutoScaling::LaunchConfiguration"
},
{
"logicalResourceId": "LoginNodeSecurityGroup",
"resourceStatus": "running",
"physicalResourceId": "335e3d5d-c37b-418e-afcb-54f8885bd920",
"resourceType": "AWS::EC2::SecurityGroup"
},
{
"logicalResourceId": "Login",
"resourceStatus": "running",
"physicalResourceId": "01a8e2f2-ff13-433c-8fa8-44457d8df3e3",
"resourceType": "AWS::EC2::Instance"
},
{
"logicalResourceId": "LoginReady",
"resourceStatus": "running",
"physicalResourceId": "LoginHandle",
"resourceType": "AWS::CloudFormation::WaitCondition"
},
{
"logicalResourceId": "PublicLayerSecurityGroup",
"resourceStatus": "running",
"physicalResourceId": "8779a6b0-73bf-4ad6-8981-b8fe6918950d",
"resourceType": "AWS::EC2::SecurityGroup"
},
{
"logicalResourceId": "v2dwlyzeg3sx",
"resourceStatus": "running",
"physicalResourceId": "1bbbe9e7-fd9c-4fad-bc92-f9d9732fee1c",
"resourceType": "AWS::EC2::Instance"
},
{
"logicalResourceId": "6tl6q2j7rfr5",
"resourceStatus": "running",
"physicalResourceId": "d4ac0344-cc9b-4ba6-adb8-3e13eb5bca75",
"resourceType": "AWS::EC2::Instance"
},
{
"logicalResourceId": "NodeIPAssoc",
"resourceStatus": "running",
"physicalResourceId": "10.197.217.160",
"resourceType": "AWS::EC2::EIPAssociation"
},
{
"logicalResourceId": "NodeIPAddress",
"resourceStatus": "running",
"physicalResourceId": "17f50f23-c1be-4a35-9e7d-eb62a3a6f638",
"resourceType": "AWS::EC2::EIP"
},
{
"logicalResourceId": "MonitorSecurityGroup",
"resourceStatus": "running",
"physicalResourceId": "dc7485c3-b363-4856-a91d-0b7ef698bef4",
"resourceType": "AWS::EC2::SecurityGroup"
},
{
"logicalResourceId": "MonitorNode",
"resourceStatus": "running",
"physicalResourceId": "6727cb84-5de9-40ad-96fc-3a14a7be8592",
"resourceType": "AWS::EC2::Instance"
}
],
"status": "shuttingDown",
"statusReason": "Stack create completed successfully",
"physicalId": "72c1728f-7c3d-4472-99d6-a36085ddc47a"
}
As stated in the introduction, you can find the documentation for every possible action in the XMS API Reference.