Admin scripting your way around Cloud Foundry

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.

looping

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:

jqplay

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.

looping

Examples

Below are some example bash scripts that interact with Cloud Foundry using cf curl and jq:

Spread the word

twitter icon facebook icon linkedin icon