Cloud Foundry has a lightning fast CLI written in Go, a very well documented API https://apidocs.cloudfoundry.org/, and the API endpoints return consistently structured data. It is ripe for automation. But can we do it with just some bash scripts like sysadmins of old?
Oh yes indeed.
You too can write bash scripts that do magical automation to Cloud Foundry.
cf curl
Firstly, let me introduce you to cf curl
. This is like the standard unix tool curl
but you are already authenticated.
Look at the https://apidocs.cloudfoundry.org/ and you can GET, POST, PUT or DELETE every resource in Cloud Foundry.
As a user, want a list of all your applications?
cf curl /v2/apps
As an admin user, want a list of ALL APPLICATIONS?
cf login admin <password>
cf curl /v2/apps
The output will look like:
{
"total_results": 13,
"total_pages": 1,
"prev_url": null,
"next_url": null,
"resources": [
{
"metadata": {
"guid": "5efa524f-e833-4e35-b73c-c53982cad4f0",
"url": "/v2/apps/5efa524f-e833-4e35-b73c-c53982cad4f0",
"created_at": "2014-10-27T17:09:51Z",
"updated_at": "2014-12-29T22:15:12Z"
},
"entity": {
"name": "starkandwayne-ghost",
...
}
The result is JSON format. You’re thinking, oh that’s nasty. "Not very nice for bash scripting."
Processing JSON with jq
jq
is a CLI tool for processing JSON – but it also comes as an online exploration tool:
jq
is a little pre-compiled C app that’s easy to install on all platforms.
$ echo '{"name": "Dr Nic"}' | jq .
{
"name": "Dr Nic"
}
$ echo '{"name": "Dr Nic"}' | jq .name
"Dr Nic"
$ echo '{"name": "Dr Nic"}' | jq -r .name
Dr Nic
Boom! With jq
we can now parse out data into simple strings. The flag -r
(--raw-output
) emits simple strings without JSON quotes.
Using bash-fu we store the results in variables:
$ name=$(echo '{"name": "Dr Nic"}' | jq -r .name)
$ echo "Hello, $name"
Hello, Dr Nic
cf curl | jq
To get the names of all your applications:
$ cf curl /v2/apps | jq -r ".resources[].entity.name"
starkandwayne-ghost
trycf
trycf-dashboard
...
Put the names in a bash array and loop over them:
names=$(cf curl /v2/apps | jq -r ".resources[].entity.name")
for name in $names; do
echo "App: $name"
done
Will output:
App: starkandwayne-ghost
App: trycf
App: trycf-dashboard
...
Pagination
Any Cloud Foundry API endpoint that returns a list of resources will pagninate over that list.
You can shrink or grow the number of results per page. For example, two results per page:
$ cf curl "/v2/apps?results-per-page=2"
{
"total_results": 13,
"total_pages": 7,
"prev_url": null,
"next_url": "/v2/apps?order-direction=asc&page=2&results-per-page=2",
"resources": [
...
The result includes the URL for the next page of results. We can also get this out with jq
:
cf curl "/v2/apps?results-per-page=2" | jq -r .next_url
Finally, we can now loop over every page of results until we run out of pages:
next_url="/v2/apps?results-per-page=2"
while [[ "${next_url}" != "null" ]]; do
names=$(cf curl ${next_url} | jq -r ".resources[].entity.name")
for name in $names; do
echo "App: $name"
done
next_url=$(cf curl ${next_url} | jq -r -c ".next_url")
done
In the example above we’re forcing the pages to have only 2 items so the example is more interesting.
Examples
Below are some example bash scripts that interact with Cloud Foundry using cf curl
and jq
: