Table of Contents |
---|
Panel |
---|
cloudmonkey is a command line interface (CLI) tool for CloudStack written in python that leverages Marvin that provides cloudstackAPIPython. 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 5.x requires Python 2.6 cloudmonkey requires Python 2.5 or above and has following dependencies:
Code Block |
---|
readline requests Pygments readlineprettytable clint argcomplete |
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
|
Code Block |
---|
$ yum install python-setuptools
$ easy_install cloudmonkey
|
or if pip available (pip is recommended)
Code Block |
---|
$ pip install cloudmonkey
|
Code Block |
---|
$ apt-get getinstall python-setuptoolspip $ pip easy_install cloudmonkey |
or Or, if pip is not available (pip is recommended)
Code Block |
---|
$ apt-get install python-setuptools $ pip easy_install cloudmonkey |
...
cloudmonkey is moved to a separate git repo
more info @ https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=commit;h=6f84e74a68d78705a06fe58f7927f42f61453a16
Code Block |
---|
$ git asfgit clone https://git-wip-us.apache.org/repos/asf/incubatorcloudstack-cloudstackcloudmonkey.git $# mvnRun cleanmgmt installserver -P developer $ cd tools/cli # cloudmonkey-x.x.x.tar.gz will be built in distand run "cloudmonkey sync", this is only for build time cache generation using cachemaker.py $ python setup.py build $ python setup.py install |
cloudmonkey gets reads configuration from ~/.cloudmonkey_/config which is it's config file in user's home directory/.cloudmonkey.
Further it logs in ~/.cloudmonkey_/log and , stores history in ~/.cloudmonkey_history. The /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
|
There are other parameters which can be customized:
Key | Purpose | Default |
host | IP or resolvable domain of management server | localhost |
port | Api server port, 8080 is encouraged over 8096 | 8080 |
apikey | User api key | "" |
secretkey | User secret key | "" |
prompt | cloudmonkey prompt, default prompt has a UTF-8 char which can be an issue | 🵠cloudmonkey> |
asyncblock | Poll for async commands, making it false will cause cloudmonkey to return jobid | true |
timeout | Timeout interval for polling async commands | 3600 |
color | Enable coloured output, set to false to disable | true |
log_file | Log file | ~/.cloudmonkey_log |
history_file | History file | ~/.cloudmonkey_history |
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, try out some commands:
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
|
A typical help doc for an api will list all available acceptable arguments and required arguments.
Ctrl+a (start of the line)
Ctrl+e (end of the line)
Ctlr+w (remove one word from back)
Ctrl+u (remove whole line) etc.
Ctrl+R and rest you know
...
Typical ~/.cloudmonkey/config for version 5.2.0 and above:
Code Block |
---|
[core]
profile = local
asyncblock = true
paramcompletion = true
history_file = /Users/bhaisaab/.cloudmonkey/history
log_file = /Users/bhaisaab/.cloudmonkey/log
cache_file = /Users/bhaisaab/.cloudmonkey/cache
[ui]
color = true
prompt = >
display = default
[local]
url = http://localhost:8080/client/api
username = admin
password = password
apikey =
secretkey =
timeout = 3600
expires = 600 |
The following configuration parameters can be configured by using the 'set' command in cloudmonkey:
Key | Purpose | Default |
profile | Management server profile name | local |
url | Management server API url (it should contain full url with protocol, port etc and paths) | |
timeout | Timeout interval for polling async commands | 3600 |
apikey | User api key | "" |
secretkey | User secret key | "" |
verifysslcert | Enables/Disables SSL certification verification when making HTTP calls (per server profile) | true |
username | CloudStack user name | admin |
password | CloudStack user password | password |
color | Enable coloured output, set to false to disable | true |
prompt | cloudmonkey prompt | > |
display | Line based, JSON, or tabular output, set to default or json or table | default |
log_file | Log file | ~/.cloudmonkey/log |
history_file | History file | ~/.cloudmonkey/history |
asyncblock | Poll for async commands, making it false will cause cloudmonkey to return jobid | true |
paramcompletion | Tries to predict api for listing a parameter value for an api, experimental may fail | true |
Note: If both username/password and apikey/secretkey are set (i.e. have non-empty values), apikey and secretkey are used while making HTTP API calls.
By default cloudmonkey will create 'local' server profile when it will start.
First set the management server API url, apikey and secretkey etc.
Api and Secret keys can be created via CloudStack management server UI, Accounts->Users->Generate keys. One can also use username and password though use of keys is recommended. CloudMonkey first tries to authenticate using apikey/secret key if provided, then if port specified in the URL is 8096 cloudmonkey assumes user is trying to use integration port and if both of them don't qualify i.e. keys are not provided and port is not 8096 we try to authenticate with username and password.
Code Block |
---|
> set url https://api.exoscale.ch:443/compute
> 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
500 APIs discovered and cached
|
The sync command in cloudmonkey pull a list of apis which are accessible to your user role, along with help docs etc. and stores the cache in ~/.cloudmonkey/cache. This allows cloudmonkey to be adaptable to changes in mgmt server, so in case the sysadmin enables a plugin such as Nicira NVP for that user role, the users can get those changes. New verbs and grammar (DSL) rules are created on the fly. A failsafe precache is bundled with the distribution but users are
Note: This features requires ApiDiscovery plugin to be enabled at the management server and it is enabled by default starting ACS 4.1 version.
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
|
A typical help doc for an api will list all available acceptable arguments and required arguments.
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.
|
CloudMonkey version 5.2.0 and above will support multiple (management) server profiles, so one can use the tool on the fly toggling between different CloudStack server in the interpreter mode. If cloudmonkey starts for the first time, it will create a default server profile by the name [local] and use the following default values which one can then override using the `set` command. The profile in use is set in the [core] section's profile parameter which is read at the time cloudmonkey loads.
Code Block |
---|
[core]
profile = local
...
[local]
url = http://localhost:8080/client/api
username = admin
password = password
apikey =
secretkey =
timeout = 3600
expires = 600 |
To create a new server profile, one can use: set profile <profile-name> and this will create a new server profile config section in ~/.cloudmonkey/config and use the above default values. Using set command on params such as url, username, password etc. will set these values for the currently selected profile only. Note: profile names cannot be whitespace/blank '', core or ui.
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 |
+---------+--------------------------------------+-------------+--------------------------+--------+
|
Tabular output comes with filtering, using filter parameter you can ask cloudmonkey to filter particular columns (like select field of mysql).
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"
}
]
}
|
CloudMonkey can filter output based on keys. Starting 5.3.0, filter is supported for all display outputs (json, default and table) and autocompletion works as well.
Code Block |
---|
> list users filter=<tab><tab>
account, accounttype, created, domainid, firstname, iscallerchilddomain, lastname, state, username,
accountid, apikey, domain, email, id, isdefault, secretkey, timezone,
> list users filter=id,username,firstname,lastname,
id = ef33f4a0-e7cf-11e3-a8a4-005056867a67
firstname = admin
lastname = cloud
username = admin
================================================================================
id = d052dfb3-828c-4fa3-9e72-75f4795bb554
firstname = रोहित
lastname = यादव
username = रोहित |
Ctrl+a (start of the line)
Ctrl+e (end of the line)
Ctlr+w (remove one word from back)
Ctrl+u (remove whole line) etc.
Ctrl+R etc. If it does not work and also any issue with tab completion it's probably a readline issue on your env. If autocompletion using tabs does not work for you, pl. open an issue on jira, issues.a.o
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. ExampleExample:
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 |
---|
$ cloudmonkey cat file-with-cmds list users list zones $ cloudmonkey create domain name=mydomain< file-with-cmds |
The follow example illustrates how one can use cloudmonkey to automate their deployments, this one deploys a basic zone:
Code Block | ||||
---|---|---|---|---|
| ||||
#!/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 provider" netoff_id=`$cli list networkofferings name=DefaultSharedNetworkOfferingWithSGService | grep ^id\ = | awk '{print $3}'` net_id=`$cli list networkofferings name=DefaultSharedNetworkOfferingWithSGServicecreate network zoneid=$zone_id name=guestNetworkForBasicZone displaytext=guestNetworkForBasicZone networkofferingid=$netoff_id | grep ^id\ = | awk '{print $3}'` net echo "Created network $net_id for zone" $zone_id pod_id=`$cli create pod networkname=MyPod zoneid=$zone_id gateway=$gw namenetmask=guestNetworkForBasicZone$nmask displaytextstartip=guestNetworkForBasicZone$pod_start networkofferingidendip=$netoff$pod_idend | grep ^id\ = | awk '{print $3}'` echo "Created network 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 zoneinstances" $zone_id podcluster_id=`$cli create pod name=MyPodadd cluster zoneid=$zone_id gatewayhypervisor=$gw$hpvr netmaskclustertype=$nmaskCloudManaged startippodid=$pod_startid endipclustername=$pod_endMyCluster | grep ^id\ = | awk '{print $3}'` echo "Created pod" $cli create vlaniprangecluster" $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 networkidclusterid=$net$cluster_id gatewayhypervisor=$gw$hpvr netmaskusername=$nmask$host_user startippassword=$vlan$host_startpasswd endip=$vlan_end forvirtualnetwork=false url=http://$host_ip; echo "CreatedAdded IP ranges for instances" cluster_id=`$cli add clusterhost" $host_ip; done; #$cli create storagepool zoneid=$zone_id hypervisorpodid=$hpvr$pod_id clustertype=CloudManaged podid=$podclusterid=$cluster_id clusternamename=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!" |
Arguments can be passed to an api command using the syntax; <cmd> <verb> key1=value1 etc.
By default cloudmonkey's lexical parser parses like shlex and split by spaces.
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
|
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>
|
1. Bash/zsh completion
2. DocBook Documentation
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!"
|
Arguments can be passed to an api command using the syntax; <cmd> <verb> key1=value1 etc.
By default cloudmonkey's lexical parser parses like shlex and split by spaces.
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>
|
Starting 5.3.0 version, parameter implementation works well for api arguments which are of uuid and boolean types. It can be enabled by setting paramcompletion to true. To automatically find out how to get values for a api arg it uses two heuristics (list apis and most likely related list api) so it is quite possible there are corner cases where this may fail. Whenever a list api is called or when parameter completion calls a list api in background, those results (pair of uuid and name strings) are cached by CloudMonkey to speed up rendering. The cache is kept for next 10-15 mins, after which a list api is called again in the background.
Example:
Code Block |
---|
> list users id=
cd58ff50-8642-11e2-9a8b-37057334a9b2 user1
|
cloudmonkey was named after the beloved mascot of Apache CloudStack and is powered by Marvin.
AuthorDev ML: The Apache CloudStack Team <cloudstack-dev@incubator<dev@cloudstack.apache.org>
Maintainer: Rohit Yadav <bhaisaab@apache.org>