opdemand 0.9
Command-line Client for OpDemand
Latest Version: 0.9.3
The opdemand-cli project contains the command-line client interface to the OpDemand system. These python modules use OpDemand's REST API.
Open Source
The opdemand-cli project has been made open source by OpDemand.
OpDemand CLI Documentation
Before you begin
- You will need an active OpDemand account. Create one at http://www.opdemand.com
- Instructions assume OSX or Linux (Windows has not been tested, but should work)
Installation
Installation uses standard distutils convention.
sudo pip install opdemand
Logging In
Issue an opdemand login, which will prompt you for a username and password.
user@box:~$ opdemand login
username: myuser
password:
2011-06-07 08:44:12,052 - INFO - => POST https://c2.opdemand.com/api/system/session
2011-06-07 08:44:13,095 - INFO - <= 201 Created, reading 4082 bytes of application/json
{
# JSON Representation of the login session
}
2011-06-07 08:44:13,169 - INFO - (login) success in 3.283798s
Submit your AWS credentials
Edit the template provided in json/aws_credentials.json and supply the correct:
- Access Key
- Secret Key
Issue an opdemand credential create and read the credential body from standard input.
user@box:~$ opdemand credential create - < json/aws_credentials.json
2011-06-07 08:59:07,811 - INFO - reading object from stdin, ctrl-c to break...
2011-06-07 08:59:07,826 - INFO - => POST https://c2.opdemand.com/api/account/myuser/credential
2011-06-07 08:59:10,278 - INFO - <= 201 Created, reading 23623 bytes of application/json
{
# JSON Representation of credentials and their associated "clouds"
}
2011-06-07 08:59:10,527 - INFO - (credential/create) success in 2.716193s
Note: "-" parameter specifies reading from stdin
List Platform Templates
You now have access to the OpDemand Template Library. Issue an opdemand template list to view available templates.
user@box:~$ opdemand template list
2011-06-07 09:21:21,374 - INFO - => GET https://c2.opdemand.com/api/lib/system/core
2011-06-07 09:21:21,879 - INFO - <= 200 OK, reading 1822 bytes of application/json
[ # JSON list of templates
{
# First template
},
{
# Second template
}
]
2011-06-07 09:21:21,881 - INFO - (template/list) success in 0.524872s
Find the _id value of the template you want to deploy, and copy it to your clipboard.
Create a new Platform
Select the desired template and issue a opdemand template load of the template _id, which will create a fresh platform.
user@box:~$ opdemand template load --_id=6c86dfc5ddfe464199021b8dcaf521a2
2011-06-07 09:42:36,711 - INFO - => POST https://c2.opdemand.com/api/lib/system/core/template/6c86dfc5ddfe464199021b8dcaf521a2/load
2011-06-07 09:42:38,606 - INFO - <= 201 Created, reading 14850 bytes of application/json
{
# Much longer JSON representation of the template
}
2011-06-07 09:42:38,757 - INFO - (template/load) success in 2.061932s
List Platforms
Issue an opdemand platform list to see the available platforms in your account.
user@box:~$ opdemand platform list
2011-06-07 09:46:48,327 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform
2011-06-07 09:46:48,884 - INFO - <= 200 OK, reading 566 bytes of application/json
[
{
# Your new platform
}
]
2011-06-07 09:46:48,885 - INFO - (platform/list) success in 0.572228s
Copy the _id of this platform to your clipboard.
Read the platform
List operations only show summary representations of items in a collection. To view the full representation of a platform (one that includes its nested components) you must issue a opdemand platform read and provide the _id:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e
2011-06-07 10:16:06,050 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e
2011-06-07 10:16:06,984 - INFO - <= 200 OK, reading 14850 bytes of application/json
{
# Full platform representation
}
2011-06-07 10:16:07,152 - INFO - (platform/read) success in 1.117754s
Working with JSON responses
The above platform is too long to read. Fortunately the OpDemand shell includes an integrated JSON prettifier that makes JSON output from any OpDemand command much easier to read.
Simply pipe any opdemand command to opdemand pretty:
user@box:~$ opdemand template read --_id=6c86dfc5ddfe464199021b8dcaf521a2 | opdemand pretty 2011-06-07 09:32:00,646 - INFO - => GET https://c2.opdemand.com/api/lib/system/core/template/6c86dfc5ddfe464199021b8dcaf521a2 2011-06-07 09:32:01,378 - INFO - <= 200 OK, reading 12022 bytes of application/json 2011-06-07 09:32:01,535 - INFO - (template/read) success in 0.904613s tiers.0.name "Network Tier" tiers.0.doctype "tier" tiers.0._rev "1-5a37d211b276deee536cd72a016af8fa" ...rest of prettified JSON
All OpDemand commands read from standard input and write to standard output. This means raw JSON and prettified JSON can be piped to any other command that uses UNIX-style pipes. (e.g. grep).
Configure the platform
First read the platform and grep for the default config information:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep config 2011-06-07 10:26:29,828 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:26:30,486 - INFO - <= 200 OK, reading 14850 bytes of application/json 2011-06-07 10:26:30,635 - INFO - (platform/read) success in 0.821403s config.access_network "0.0.0.0/0" config.image_id "ami-06ad526f" config.doctype "config" config._rev "1-38d720a0975e4d377ccbfd3cb7864185" config.access_port "22" config.cloud_name "us-east-1" config.clone_.parent_id "ceee3724a3674bc096a2a6d2dfde7209" config.clone_.parent_impl.cls_ "c2.resolve.Config" config.admin_network "0.0.0.0/0" config._id "ceee3724a3674bc096a2a6d2dfde7209" config.impl.cls_ "c2.resolve.Config" config.views.7bbeacb1082e4810bb1a6643d024496e.0.0 "7bbeacb1082e4810bb1a6643d024496e" config.views.7bbeacb1082e4810bb1a6643d024496e.0.1 "config" metadata.config_info.access_port "Port listening on the server" metadata.config_info.access_network "Network mask for public users" metadata.config_info.cloud_name "Name of AWS region" metadata.config_info.admin_network "Network mask for admin users"
Let's restrict all network access to one host -- 1.1.1.1/32. This will require changing the access_network and admin_network keys.
Since config is a nested document with its own _id and _rev, we must modify the config document directly. To do this, we follow the RESTful convention of reading the representation and piping it to an update operation:
user@box:~$ opdemand config read --_id=ceee3724a3674bc096a2a6d2dfde7209 | opdemand config update - --access_network=1.1.1.1/32 --admin_network=1.1.1.1/32
2011-06-07 10:35:39,643 - INFO - reading object from stdin, ctrl-c to break...
2011-06-07 10:35:39,661 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/config/ceee3724a3674bc096a2a6d2dfde7209
2011-06-07 10:35:40,573 - INFO - <= 200 OK, reading 692 bytes of application/json
2011-06-07 10:35:40,574 - INFO - (config/read) success in 0.931527s
2011-06-07 10:35:40,603 - INFO - => PUT https://c2.opdemand.com/api/env/myuser/master/config/ceee3724a3674bc096a2a6d2dfde7209
2011-06-07 10:35:41,316 - INFO - <= 200 OK, reading 694 bytes of application/json
{
"_id": "ceee3724a3674bc096a2a6d2dfde7209",
"_rev": "2-6a1cac4a1851fead776d4184e1218028",
"access_network": "1.1.1.1/32",
"access_port": "22",
"admin_network": "1.1.1.1/32",
"....": "...."
}
2011-06-07 10:35:41,317 - INFO - (config/update) success in 0.730138s
Re-read the platform configuration to confirm the parent document includes the updated, nested configuration:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep config 2011-06-07 10:37:11,131 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:37:11,825 - INFO - <= 200 OK, reading 14852 bytes of application/json 2011-06-07 10:37:11,977 - INFO - (platform/read) success in 0.862029s config.access_network "1.1.1.1/32" config.image_id "ami-06ad526f" config.doctype "config" config._rev "2-6a1cac4a1851fead776d4184e1218028" config.access_port "22" config.cloud_name "us-east-1" config.clone_.parent_id "ceee3724a3674bc096a2a6d2dfde7209" config.clone_.parent_impl.cls_ "c2.resolve.Config" config.admin_network "1.1.1.1/32" config._id "ceee3724a3674bc096a2a6d2dfde7209" config.impl.cls_ "c2.resolve.Config" config.views.7bbeacb1082e4810bb1a6643d024496e.0.0 "7bbeacb1082e4810bb1a6643d024496e" config.views.7bbeacb1082e4810bb1a6643d024496e.0.1 "config" metadata.config_info.access_port "Port listening on the server" metadata.config_info.access_network "Network mask for public users" metadata.config_info.cloud_name "Name of AWS region" metadata.config_info.admin_network "Network mask for admin users"
Start the platform
With our AWS credentials in place, and our platform queued up we're ready to go. Issue a opdemand platform start and let the orchestration begin:
user@box:~$ opdemand platform start --_id=7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:42:52,849 - INFO - => POST https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e?action=start&async=true 2011-06-07 10:42:53,816 - INFO - <= 202 Accepted, reading 0 bytes of application/json 2011-06-07 10:42:53,816 - INFO - (platform/start) success in 0.981219s
To follow the platform's progress, read the full platform representation and grep for the status of all nested objects:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep status 2011-06-07 10:43:06,530 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:43:07,228 - INFO - <= 200 OK, reading 22227 bytes of application/json 2011-06-07 10:43:07,451 - INFO - (platform/read) success in 0.935643s tiers.0.status_.value "building" tiers.0.keypair.status_.detail "key pair created" tiers.0.keypair.status_.value "built" tiers.0.sg.status_.detail "rules authorized successfully" tiers.0.sg.status_.value "built" tiers.1.status_.value "building" tiers.1.server.status_.detail "waiting for running, currently pending" tiers.1.server.status_.value "building" status_.detail "start operation triggered" status_.value "starting"
We can see the platform-level status is starting. Re-issue this command a number of times to "poll" status. Grepping for state is also useful for demonstrating which components are currently transitioning. Once the platform is done, status should look as follows:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep status 2011-06-07 10:44:21,015 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:44:21,736 - INFO - <= 200 OK, reading 27129 bytes of application/json 2011-06-07 10:44:21,988 - INFO - (platform/read) success in 0.990599s tiers.0.status_.detail "started successfully" tiers.0.status_.value "running" tiers.0.keypair.status_.detail "key pair created" tiers.0.keypair.status_.value "running" tiers.0.sg.status_.detail "rules authorized successfully" tiers.0.sg.status_.value "running" tiers.1.status_.detail "started successfully" tiers.1.status_.value "running" tiers.1.server.status_.detail "listener ready at 22/tcp" tiers.1.server.status_.value "running" status_.detail "start operation successful" status_.value "running"
Note a parent-level status of "running" with the server listener ready on 22/tcp. Our platform is ready.
Using the platform
All platforms publish information about how they are used. Most platforms publish some combination of:
- URLs
- Hostname/Port combinations
- Logins
- Passwords
If we read the platform and grep for publish we can see this platform published a simple SSH url:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep publish 2011-06-07 10:51:30,694 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:51:31,764 - INFO - <= 200 OK, reading 27129 bytes of application/json 2011-06-07 10:51:32,038 - INFO - (platform/read) success in 1.367026s tiers.1.server.publish.access_url "ssh://ubuntu@ec2-50-19-55-84.compute-1.amazonaws.com/" metadata.publish_info.access_url "URL for accessing the platform"
A common pattern is for platforms to publish:
- Admin URL
- Admin Login
- Admin Password
- Access URL
Stopping the platform
Once the platform has stopped, its status will look something like this:
user@box:~$ opdemand platform read --_id=7bbeacb1082e4810bb1a6643d024496e | opdemand pretty | grep status 2011-06-07 10:57:51,345 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 10:57:52,128 - INFO - <= 200 OK, reading 27966 bytes of application/json 2011-06-07 10:57:52,424 - INFO - (platform/read) success in 1.093576s tiers.0.status_.detail "stopped successfully" tiers.0.status_.value "stopped" tiers.0.keypair.status_.detail "key pair created" tiers.0.keypair.status_.value "stopped" tiers.0.sg.status_.detail "rules authorized successfully" tiers.0.sg.status_.value "stopped" tiers.1.status_.detail "stopped successfully" tiers.1.status_.value "stopped" tiers.1.server.status_.detail "waiting for stopped, currently stopped" tiers.1.server.status_.value "stopped" status_.detail "stop operation successful" status_.value "stopped"
The platform still exists in the cloud, but it is no longer incurring expensive compute costs (it is, however incurring negligible storage costs). You're also no longer incurring OpDemand usage fees. At this point, your platform costs effectively nothing.
Platforms can be stopped and started without limit.
Destroy the platform
To actually destroy all of the cloud components included in your platform, you must issue a opdemand platform destroy and provide the _id of the target platform:
user@box:~$ opdemand platform destroy --_id=7bbeacb1082e4810bb1a6643d024496e 2011-06-07 11:04:10,667 - INFO - => POST https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e?action=destroy&async=true 2011-06-07 11:04:11,953 - INFO - <= 202 Accepted, reading 0 bytes of application/json 2011-06-07 11:04:11,953 - INFO - (platform/destroy) success in 1.300462s
Delete the platform
If you list the platforms you'll see that the destroyed platform still exists:
user@box:~$ opdemand platform list | opdemand pretty 2011-06-07 11:12:02,771 - INFO - => GET https://c2.opdemand.com/api/env/myuser/master/platform 2011-06-07 11:12:03,149 - INFO - <= 200 OK, reading 1577 bytes of application/json 2011-06-07 11:12:03,150 - INFO - (platform/list) success in 0.394324s 0.views.7bbeacb1082e4810bb1a6643d024496e.0.0 "7bbeacb1082e4810bb1a6643d024496e" 0.time_.disconnect.date_ "1307466249.487580" 0.time_.stop.date_ "1307465858.607597" 0.time_.start.date_ "1307465019.767619" 0.time_.build.date_ "1307465019.475195" 0.time_.destroy.date_ "1307466249.487347" 0.time_.connect.date_ "1307466240.220381" 0.status_.detail "destroy operation successful" 0.status_.value "destroyed" 0.doctype "platform" 0._rev "7-38fe44c5a900894adf48f4a416c94338" 0.template.cls_ "lib.platform.vanilla.natty.UbuntuNattyPlatform" 0._id "7bbeacb1082e4810bb1a6643d024496e" 0.state.running false 0.state.transitioning false 0.state.built false 0.impl.cls_ "lib.platform.vanilla.natty.UbuntuNattyPlatform" 0.interval_.destroy 9.3936290740966797 0.interval_.stop 33.600441932678223 0.interval_.build 57.54404091835022 0.interval_.start 57.836580991744995
From the interval you can see it took:
- 58 seconds to start this platform
- 33 seconds to stop it
- 9 seconds to destroy it
You can always re-start a destroyed platform and have it rebuild the cloud components again. However to complete delete the platform and its nested documents, you must issue an opdemand platform delete:
user@box:~$ opdemand platform delete --_id=7bbeacb1082e4810bb1a6643d024496e 2011-06-07 11:15:45,235 - INFO - => DELETE https://c2.opdemand.com/api/env/myuser/master/platform/7bbeacb1082e4810bb1a6643d024496e 2011-06-07 11:15:46,474 - INFO - <= 204 No Content, reading 0 bytes of application/json 2011-06-07 11:15:46,474 - INFO - (platform/delete) success in 1.252582s
To confirm, we can see our platform list is now empty:
user@box:~$ opdemand platform list 2011-06-07 11:15:51,890 - INFO - => GET https://c2.opdemand.com/platform 2011-06-07 11:15:52,296 - INFO - <= 200 OK, reading 2 bytes of application/json 2011-06-07 11:15:52,297 - INFO - (platform/list) success in 0.423616s
Logging out
By issuing a opdemand info we can see the status of our session:
user@box:~/workspace/c2-shell$ opdemandinfo
2011-06-07 11:17:11,656 - INFO - => GET https://c2.opdemand.com/api/system/session/73c2e9b49d01c695fb6c74927b8eb0eee5cdc82c2064cd728a8033eb83ea5b95
2011-06-07 11:17:12,134 - INFO - <= 200 OK, reading 4082 bytes of application/json
{
"expires_at": "Friday, 10 June 2011 08:44AM",
"session_id": "73c2e9b49d01c695fb6c74927b8eb0eee5cdc82c2064cd728a8033eb83ea5b95",
"username": "myuser"
}
2011-06-07 11:17:12,138 - INFO - (info) success in 0.497018s
Logging out is simply opdemand logout:
user@box:~$ opdemand logout 2011-06-07 11:17:44,903 - INFO - => DELETE https://c2.opdemand.com/api/system/session/73c2e9b49d01c695fb6c74927b8eb0eee5cdc82c2064cd728a8033eb83ea5b95 2011-06-07 11:17:45,330 - INFO - <= 204 No Content, reading 0 bytes of application/json 2011-06-07 11:17:45,330 - INFO - (logout) success in 0.443405s user@box:~$ opdemand info 2011-06-07 11:17:49,025 - INFO - (info) success in 0.000376s
| File | Type | Py Version | Uploaded on | Size | # downloads |
|---|---|---|---|---|---|
| opdemand-0.9.tar.gz (md5) | Source | 2012-01-10 | 12KB | 366 | |
- Author: OpDemand
- Home Page: http://www.opdemand.com/
- Bug Tracker: https://github.com/opdemand/opdemand-cli/issues
- Download URL: https://github.com/opdemand/opdemand-cli
- Keywords: opdemand,cloud,aws,ec2
-
Categories
- Development Status :: 4 - Beta
- Environment :: Console
- Intended Audience :: Developers
- Intended Audience :: Information Technology
- Intended Audience :: System Administrators
- License :: OSI Approved :: Apache Software License
- Operating System :: OS Independent
- Programming Language :: Python
- Programming Language :: Python :: 2.6
- Programming Language :: Python :: 2.7
- Topic :: Internet
- Topic :: System :: Systems Administration
- Package Index Owner: dgriff1, gabrtv, mboersma
- DOAP record: opdemand-0.9.xml
