Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changed the git clone url for cloudmonkey

Table of Contents

What is cloudmonkey?

Panel

cloudmonkey is a command line interface (CLI) tool for CloudStack written in Python. cloudmonkey can be use both as an interactive shell and as a command line tool which simplifies CS configuration and management. It is unofficially distributed by community maintained distribution at the cheese shop http://pypi.python.org/pypi/cloudmonkey/ as well as within the git repository in tools/cli/. It can be used with Apache CloudStack 4.0-incubating and above.

...

cloudmonkey requires Python 2.5 or above and has following dependencies:

Code Block

readline
Pygments
prettytable

...

For installing any Python package, pip is recommended: http://www.pip-installer.org/en/latest/installing.html

Code Block

$ pip install cloudmonkey

To upgrade:

Code Block

$ pip install --upgrade cloudmonkey

Thought a clean upgrade is recommended:

Code Block

$ pip uninstall cloudmonkey
$ pip install cloudmonkey

RHEL/CentOS 6.x (internet access required for python eggs repository)

Code Block

$ yum install python-setuptools
$ easy_install cloudmonkey

or if pip available (pip is recommended)

Code Block

$ pip install cloudmonkey

Ubuntu/Debian

Code Block

$ apt-get install python-pip
$ pip install cloudmonkey

Or, if pip is not available

Code Block

$ apt-get install python-setuptools
$ easy_install cloudmonkey

Building from source code withing source code

Code Block

$ git clone https://git-wip-us.apache.org/repos/asfgit clone https://git-wip-us.apache.org/repos/asf/incubatorcloudstack-cloudstackcloudmonkey.git
$ mvn clean install -P developer
# Run mgmt server and run cloudmonkey sync, this is only for build time cache generation using cachemaker.py
$ cd tools/cli # cloudmonkey-x.x.x.tar.gz will be built in dist
$ python setup.py build #
$ python setup.py install

...

Further it logs in ~/.cloudmonkey/log, stores history in ~/.cloudmonkey/history and caches discovered apis in ~/.cloudmonkey/cache. Only the log and history files can be custom paths and can be configured by setting appropriate file paths in ~/.cloudmonkey/config or by command:

Code Block

$ cloudmonkey
> set history_file /usr/share/cloudmonkey_history
> set log_file /var/log/cloudmonkey

Typical ~/.cloudmonkey/config:

Code Block

[core]
log_file = /Users/bhaisaab/.cloudmonkey/log
asyncblock = true
paramcompletion = false
history_file = /Users/bhaisaab/.cloudmonkey/history

[ui]
color = true
prompt = >
display = default

[user]
secretkey = "enter your developer secret key" "enter your developer secret key"
apikey = "enter API key" "enter API key"

[server]
path = /client/api
host = localhost
protocol = http
port = 8080
timeout = 3600

...

First set your host, port, apikey and secretkey using set. Api and Secret keys can be created via CloudStack management server UI, Accounts->Users->Generate keys.

Code Block

> set host 192.168.56.1
> set port 8080
> set apikey <put-your-api-key-for-your-user>
> set secretkey <put-your-secret-key-for-your-user>
> set prompt mycloudmonkey>

Make sure your management server is running, discover and sync/pull latest apis:

Code Block

> sync
324 APIs discovered and cached

...

Try autocompletion using tabbing:

Code Block

> <tab><tab>
> list <tab><tab>
> list users <tab><tab>

...

Help for any command can be obtained using help <cmd> or ?<cmd> or <cmd> --help or <cmd> -h, examples:

Code Block

> help list
> help list users
> ?list
> ?list users
> list users --help
> list users -h

...

Example help for listUsers api:

Code Block

> help list users
(listUsers) Lists user accounts
Parameters
==========
id = (uuid) List user by ID.
keyword = (string) List by keyword
accounttype = (long) List users by account type. Valid types include admin, domain-admin, read-only-admin, or user.
username = (string) List user by the username
domainid = (uuid) list only resources belonging to the domain specified
page = (integer)
pagesize = (integer)
listall = (boolean) If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false
state = (string) List users by state of the user account.
isrecursive = (boolean) defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves.
account = (string) list resources by account. Must be used with the domainId parameter.

...

You may enable tabular listing and even choose set of column fields, this allows you to create your own field using the filter param which takes in comma separated argument. If argument has a space, put them under double quotes. The create table will have the same sequence of field filters provided. If your present cli does not have this, pl. upgrade cloudmonkey: pip install --upgrade cloudmonkey
To enable tabular output:

Code Block

> set display table

Examples:

Code Block

> list users account=admin username=admin filter=account,accountid,accounttype,created,domain
count = 1
user:
+---------+--------------------------------------+-------------+--------------------------+--------+
| account |              accountid               | accounttype |         created          | domain |
+---------+--------------------------------------+-------------+--------------------------+--------+
|  admin  | dc8ece35-9f03-401f-95f1-2db99c467e1c |      1      | 2013-04-03T02:13:25-0500 |  ROOT  |
+---------+--------------------------------------+-------------+--------------------------+--------+

...

JSON output formats cloudmonkey's output into pretty generated JSON documents. Filtering may also be used to limit the result set. Even with filtering, a valid JSON document is generated and may be saved into an external file and processed with your favorite programming language. If your present cli does not have this, pl. upgrade cloudmonkey: pip install --upgrade cloudmonkey
To enable json output:

Code Block

> set display json

Examples:

Code Block

> list users account=admin username=admin filter=account,accountid,accounttype,created,domain
{
  "count": 1,
  "user": [
    {
      "account": "admin",
      "accountid": "dc8ece35-9f03-401f-95f1-2db99c467e1c",
      "accounttype": 1,
      "created": "2013-04-03T02:13:25-0500",
      "domain": "ROOT"
    }
  ]
}

...

By default cloudmonkey logs in ~/.cloudmonkey_log which can be changed using the set command:

Code Block

> set log_file /var/log/cloud-cli.log

One can tail the log to keep track on what's happening:

Code Block

> tail -f ~/.cloudmonkey/log

...

Use cloudmonkey as a command line tool, by passing args to cloudmonkey. Example:

Code Block

$ cloudmonkey list users
$ cloudmonkey create domain name=mydomain

It can also take in list of commands from a file and interpret them, for example:

Code Block

$ cat file-with-cmds
list users
list zones
$ cloudmonkey < file-with-cmds

The follow example illustrates how one can use cloudmonkey to automate their deployments, this one deploys a basic zone:

Code Block
bash
bash

#!/bin/bash

cli=cloudmonkey
dns_ext=8.8.8.8
dns_int=10.147.28.6
gw=10.147.28.1
nmask=255.255.255.0
hpvr=XenServer
pod_start=10.147.28.225
pod_end=10.147.28.234
vlan_start=10.147.28.235
vlan_end=10.147.28.254

#Put space separated host ips in following
host_ips=10.147.28.60
host_user=root
host_passwd=password
sec_storage=nfs://10.147.28.7/export/home/rohit/secondary
prm_storage=nfs://10.147.28.7/export/home/rohit/primary

zone_id=`$cli create zone dns1=$dns_ext internaldns1=$dns_int name=MyZone networktype=Basic | grep ^id\ = | awk '{print $3}'`
echo "Created zone" $zone_id

phy_id=`$cli create physicalnetwork name=phy-network zoneid=$zone_id | grep ^id\ = | awk '{print $3}'`
echo "Created physical network" $phy_id
$cli add traffictype traffictype=Guest physicalnetworkid=$phy_id
echo "Added guest traffic"
$cli add traffictype traffictype=Management physicalnetworkid=$phy_id
echo "Added mgmt traffic"
$cli update physicalnetwork state=Enabled id=$phy_id
echo "Enabled physicalnetwork"

nsp_id=`$cli list networkserviceproviders name=VirtualRouter physicalnetworkid=$phy_id | grep ^id\ = | awk '{print $3}'`
vre_id=`$cli list virtualrouterelements nspid=$nsp_id | grep ^id\ = | awk '{print $3}'`
$cli api configureVirtualRouterElement enabled=true id=$vre_id
$cli update networkserviceprovider state=Enabled id=$nsp_id
echo "Enabled virtual router element and network service provider"

nsp_sg_id=`$cli list networkserviceproviders name=SecurityGroupProvider physicalnetworkid=$phy_id | grep ^id\ = | awk '{print $3}'`
$cli update networkserviceprovider state=Enabled id=$nsp_sg_id
echo "Enabled security group provider"

netoff_id=`$cli list networkofferings name=DefaultSharedNetworkOfferingWithSGService | grep ^id\ = | awk '{print $3}'`
net_id=`$cli create network zoneid=$zone_id name=guestNetworkForBasicZone displaytext=guestNetworkForBasicZone networkofferingid=$netoff_id | grep ^id\ = | awk '{print $3}'`
echo "Created network $net_id for zone" $zone_id

pod_id=`$cli create pod name=MyPod zoneid=$zone_id gateway=$gw netmask=$nmask startip=$pod_start endip=$pod_end | grep ^id\ = | awk '{print $3}'`
echo "Created pod"

$cli create vlaniprange podid=$pod_id networkid=$net_id gateway=$gw netmask=$nmask startip=$vlan_start endip=$vlan_end forvirtualnetwork=false
echo "Created IP ranges for instances"

cluster_id=`$cli add cluster zoneid=$zone_id hypervisor=$hpvr clustertype=CloudManaged podid=$pod_id clustername=MyCluster | grep ^id\ = | awk '{print $3}'`
echo "Created cluster" $cluster_id

#Put loop here if more than one
for host_ip in $host_ips;
do
  $cli add host zoneid=$zone_id podid=$pod_id clusterid=$cluster_id hypervisor=$hpvr username=$host_user password=$host_passwd url=http://$host_ip;
  echo "Added host" $host_ip;
done;

#$cli create storagepool zoneid=$zone_id podid=$pod_id clusterid=$cluster_id name=MyNFSPrimary url=$prm_storage
#echo "Added primary storage"

$cli add secondarystorage zoneid=$zone_id url=$sec_storage
echo "Added secondary storage"

$cli update zone allocationstate=Enabled id=$zone_id
echo "Basic zone deloyment completed!"

...

If values have spaces, one can put them under quotes, like:

Code Block

> create project name="my unique name" displaytext="my lengthy description"

Some api accept array or maps as their arguments, in that case use arg0.key=value syntax. For example, while creating network offering:

Code Block

> create networkoffering supportedservices=Dhcp,Dns serviceproviderlist[0].service=Dhcp serviceproviderlist[0].provider=VirtualRouter serviceproviderlist[1].service=Dns serviceproviderlist[1].provider=VirtualRouter

...

Text processing is very easy, one can pipe the data and call their favourite text processors, be it awk, sed or grep.
Examples:

Code Block

> list accounts listall=true | grep ^id\ =
> list users | wc -l
> list routers | more

...

Automation can be done using shell or ! followed by shell commands. For example:

Code Block

> shell ls -lahi
> shell whoami
> shell ssh root@<ip>
> !date
> !ping google.com

For example if one has to create 100 users, one can execute cloudmonkey with args in a loop:

Code Block

> !for((i=0;i<100;i++)); do cloudmonkey create user username=user$i account=admin firstname=user$i lastname=user$i password=password$i email=user$i@domain.org; done;

...

Use the special command api to send a raw api. It does not do autocompletion and assumes the user knows what he's trying to do.
For example:

Code Block

> api uploadVolume url=xxx format=yyy name=zzz zoneid=aaa

In latest version, we can directly call a raw api on the shell with parameters, example:

Code Block

> uploadVolume url=xxx format=yyy name=zzz zoneid=aaa

...

There are two kinds of apis in CloudStack, one are blocking or synchronous and other one is non-blocking or asynchronous. By default for async apis like deploying a vm ec. are polled by cloudmonkey, one can set cloudmonkey not to poll or wait till the api is finished using:

Code Block

> set asyncblock false

This causes an async command in cloudmonkey to return a jobid which can be used to poll the completion of that command. This is particularly useful if one wants to starts a lot of VMs without having to wait for the commands to complete. The job can be polled using query async job command, like:

Code Block

> query asyncjobresult jobid=<job-id>

...

A fuzzy implementation of parameter completion for an api is an experimental feature (a full proof feature would require annotations on each api cmd), this lets user complete a param on tabbing. It can be enabled by setting paramcompletion to true. At present it only works for only those params which accept a uuid.
Example:

Code Block

> list users id=
cd58ff50-8642-11e2-9a8b-37057334a9b2

...