Skip to content

Extension chaoscf

Version 0.7.1
Repository https://github.com/chaostoolkit-incubator/chaostoolkit-cloud-foundry

Build Status Python versions Requirements Status Has wheel

This extension package provides probes and actions for Chaos Engineering experiments against a Cloud Foundry instance using the Chaos Toolkit.

Install

This package requires Python 3.5+

To be used from your experiment, this package must be installed in the Python environment where chaostoolkit already lives.

$ pip install -U chaostoolkit-cloud-foundry

Usage

To use the probes and actions from this package, add a similar payload to your experiment file:

{
    "type": "action",
    "name": "terminate-random-instance",
    "provider": {
        "type": "python",
        "module": "chaoscf.probes",
        "func": "terminate_some_random_instance",
        "arguments": {
            "name": "my-app",
            "org_name": "my-org",
            "space_name": "my-space"
        }
    }
},
{
    "type": "probe",
    "name": "fetch-app-statistics",
    "provider": {
        "type": "python",
        "module": "chaoscf.probes",
        "func": "get_app_stats",
        "arguments": {
            "name": "my-app",
            "org_name": "my-org",
            "space_name": "my-space"
        }
    }
}

That’s it!

Please explore the code to see existing probes and actions.

Discovery

You may use the Chaos Toolkit to discover the capabilities of this extension:

$ chaos discover chaostoolkit-cloud-foundry --no-install

If you have logged in against a Cloud Foundry environment, this will discover information about it along the way.

Configuration

This extension to the Chaos Toolkit need credentials to a Cloud Foundry account with appropriate scopes. Please add the following sections to your experiment file:

{
    "configuration": {
        "cf_api_url": "https://api.local.pcfdev.io",
        "cf_verify_ssl": false
    },
    "secrets": {
        "cloudfoundry": {
            "cf_username": "user",
            "cf_password": "pass"
        }
    }
}

You may leave "cf_verifiy_ssl" out of the configuration when you want to verify TLS certificates. Usually, local environments are self-signed so it may be useful to disable that check in that case.

You may also specify the "cf_client_id" and "cf_client_secret" secrets when you need. Their default values are "cf" and "" respectively. These work well against a local PCF dev install.

Then in your probe or action:

{
    "type": "probe",
    "name": "fetch-app-statistics",
    "provider": {
        "type": "python",
        "secrets": ["cloudfoundry"],
        "module": "chaoscf.probes",
        "func": "get_app_stats",
        "arguments": {
            "name": "my-app",
            "org_name": "my-org",
            "space_name": "my-space"
        }
    }
}

Test

To run the tests for the project execute the following:

$ pip install -r requirements-dev.txt
$ pytest

Contribute

If you wish to contribute more functions to this package, you are more than welcome to do so. Please, fork this project, make your changes following the usual PEP 8 code style, sprinkling with tests and submit a PR for review.

The Chaos Toolkit project requires all contributors must sign a Developer Certificate of Origin on each commit they would like to merge into the master branch of the repository. Please, make sure you can abide by the rules of the DCO before submitting a PR.

Develop

If you wish to develop on this project, make sure to install the development dependencies. But first, create a virtual environment and then install those dependencies.

$ pip install -r requirements-dev.txt -r requirements.txt 

Then, point your environment to this directory:

$ python setup.py develop

Now, you can edit the files and they will be automatically be seen by your environment, even when running from the chaos command locally.

Test

To run the tests for the project execute the following:

$ python setup.py test

Exported Activities

api


call_api

Type
Module chaoscf.api
Name call_api
Return requests.models.Response

Perform a Cloud Foundry API call and return the full response to the caller.

Signature:

def call_api(path: str,
             configuration: Dict[str, Dict[str, str]],
             secrets: Dict[str, Dict[str, str]],
             query: Dict[str, Any] = None,
             body: Dict[str, Any] = None,
             method: str = 'GET',
             headers: Dict[str, str] = None) -> requests.models.Response:
    pass

Arguments:

Name Type Default Required
path string Yes
query mapping null No
body mapping null No
method string “GET” No
headers mapping null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "call_api",
    "type": "python",
    "arguments": {
      "path": ""
    }
  },
  "type": "",
  "name": "call-api"
}
name: call-api
provider:
  arguments:
    path: ''
  func: call_api
  module: chaoscf.api
  type: python
type: ''

get_app_by_name

Type
Module chaoscf.api
Name get_app_by_name
Return mapping

Get the application with the given name.

You may restrict the search by organization and/or space by providing the various according parameters. When passing the names, the function performs a lookup for each of them to fetch their GUID.

See https://apidocs.cloudfoundry.org/280/apps/list_all_apps.html

Signature:

def get_app_by_name(app_name: str,
                    configuration: Dict[str, Dict[str, str]],
                    secrets: Dict[str, Dict[str, str]],
                    space_name: str = None,
                    space_guid: str = None,
                    org_name: str = None,
                    org_guid: str = None) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
app_name string Yes
space_name string null No
space_guid string null No
org_name string null No
org_guid string null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_app_by_name",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "",
  "name": "get-app-by-name"
}
name: get-app-by-name
provider:
  arguments:
    app_name: ''
  func: get_app_by_name
  module: chaoscf.api
  type: python
type: ''

get_app_instances

Type
Module chaoscf.api
Name get_app_instances
Return mapping

Get all the instances of a started application.

See https://apidocs.cloudfoundry.org/280/apps/get_the_instance_information_for_a_started_app.html

Signature:

def get_app_instances(app_name: str,
                      configuration: Dict[str, Dict[str, str]],
                      secrets: Dict[str, Dict[str, str]],
                      space_name: str = None,
                      space_guid: str = None,
                      org_name: str = None,
                      org_guid: str = None) -> Dict[str, Dict[str, Any]]:
    pass

Arguments:

Name Type Default Required
app_name string Yes
space_name string null No
space_guid string null No
org_name string null No
org_guid string null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_app_instances",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "",
  "name": "get-app-instances"
}
name: get-app-instances
provider:
  arguments:
    app_name: ''
  func: get_app_instances
  module: chaoscf.api
  type: python
type: ''

get_app_routes_by_host

Type
Module chaoscf.api
Name get_app_routes_by_host
Return list

Get all routes associated with the provided app and the given host.

See https://apidocs.cloudfoundry.org/280/routes/list_all_routes.html

Signature:

def get_app_routes_by_host(app_name: str,
                           route_host: str,
                           configuration: Dict[str, Dict[str, str]],
                           secrets: Dict[str, Dict[str, str]],
                           space_name: str = None,
                           space_guid: str = None,
                           org_name: str = None,
                           org_guid: str = None) -> List[Dict[str, Any]]:
    pass

Arguments:

Name Type Default Required
app_name string Yes
route_host string Yes
space_name string null No
space_guid string null No
org_name string null No
org_guid string null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_app_routes_by_host",
    "type": "python",
    "arguments": {
      "route_host": "",
      "app_name": ""
    }
  },
  "type": "",
  "name": "get-app-routes-by-host"
}
name: get-app-routes-by-host
provider:
  arguments:
    app_name: ''
    route_host: ''
  func: get_app_routes_by_host
  module: chaoscf.api
  type: python
type: ''

get_apps_for_org

Type
Module chaoscf.api
Name get_apps_for_org
Return None

List all applications available in the specified CF org name.

See https://apidocs.cloudfoundry.org/280/apps/list_all_apps.html to understand the content of the response.

Signature:

def get_apps_for_org(org_name: str, configuration: Dict[str, Dict[str, str]],
                     secrets: Dict[str, Dict[str, str]]):
    pass

Arguments:

Name Type Default Required
org_name string Yes

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_apps_for_org",
    "type": "python",
    "arguments": {
      "org_name": ""
    }
  },
  "type": "",
  "name": "get-apps-for-org"
}
name: get-apps-for-org
provider:
  arguments:
    org_name: ''
  func: get_apps_for_org
  module: chaoscf.api
  type: python
type: ''

get_bind_by_name

Type
Module chaoscf.api
Name get_bind_by_name
Return mapping

Get the service bind with the given name.

You may restrict the search by organization and/or space by providing the various according parameters. When passing the names, the function performs a lookup for each of them to fetch their GUID.

See https://apidocs.cloudfoundry.org/280/apps/list_all_apps.html

Signature:

def get_bind_by_name(bind_name: str,
                     configuration: Dict[str, Dict[str, str]],
                     secrets: Dict[str, Dict[str, str]],
                     app_name: str = None,
                     space_name: str = None,
                     space_guid: str = None,
                     org_name: str = None,
                     org_guid: str = None) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
bind_name string Yes
app_name string null No
space_name string null No
space_guid string null No
org_name string null No
org_guid string null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_bind_by_name",
    "type": "python",
    "arguments": {
      "bind_name": ""
    }
  },
  "type": "",
  "name": "get-bind-by-name"
}
name: get-bind-by-name
provider:
  arguments:
    bind_name: ''
  func: get_bind_by_name
  module: chaoscf.api
  type: python
type: ''

get_org_by_name

Type
Module chaoscf.api
Name get_org_by_name
Return mapping

Get the organization with the given name.

Signature:

def get_org_by_name(org_name: str, configuration: Dict[str, Dict[str, str]],
                    secrets: Dict[str, Dict[str, str]]) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
org_name string Yes

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_org_by_name",
    "type": "python",
    "arguments": {
      "org_name": ""
    }
  },
  "type": "",
  "name": "get-org-by-name"
}
name: get-org-by-name
provider:
  arguments:
    org_name: ''
  func: get_org_by_name
  module: chaoscf.api
  type: python
type: ''

get_routes_by_host

Type
Module chaoscf.api
Name get_routes_by_host
Return mapping

Get all routes with given host.

See https://apidocs.cloudfoundry.org/280/routes/list_all_routes.html

Signature:

def get_routes_by_host(route_host: str,
                       configuration: Dict[str, Dict[str, str]],
                       secrets: Dict[str, Dict[str, str]],
                       org_name: str = None,
                       org_guid: str = None) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
route_host string Yes
org_name string null No
org_guid string null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_routes_by_host",
    "type": "python",
    "arguments": {
      "route_host": ""
    }
  },
  "type": "",
  "name": "get-routes-by-host"
}
name: get-routes-by-host
provider:
  arguments:
    route_host: ''
  func: get_routes_by_host
  module: chaoscf.api
  type: python
type: ''

get_space_by_name

Type
Module chaoscf.api
Name get_space_by_name
Return mapping

Get the space with the given name.

You may restrict the search by organization by providing the various according parameters. When passing the name, the function performs a lookup for the org to fetch its GUID.

Signature:

def get_space_by_name(space_name: str,
                      configuration: Dict[str, Dict[str, str]],
                      secrets: Dict[str, Dict[str, str]],
                      org_name: str = None,
                      org_guid=None) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
space_name string Yes
org_name string null No
org_guid null No

Usage:

{
  "provider": {
    "module": "chaoscf.api",
    "func": "get_space_by_name",
    "type": "python",
    "arguments": {
      "space_name": ""
    }
  },
  "type": "",
  "name": "get-space-by-name"
}
name: get-space-by-name
provider:
  arguments:
    space_name: ''
  func: get_space_by_name
  module: chaoscf.api
  type: python
type: ''

probes


get_app_stats

Type probe
Module chaoscf.probes
Name get_app_stats
Return mapping

Fetch the metrics of the given application.

See https://apidocs.cloudfoundry.org/280/apps/get_detailed_stats_for_a_started_app.html for more information.

Signature:

def get_app_stats(app_name: str,
                  configuration: Dict[str, Dict[str, str]],
                  secrets: Dict[str, Dict[str, str]],
                  org_name: str = None,
                  space_name: str = None) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required
app_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.probes",
    "func": "get_app_stats",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "probe",
  "name": "get-app-stats"
}
name: get-app-stats
provider:
  arguments:
    app_name: ''
  func: get_app_stats
  module: chaoscf.probes
  type: python
type: probe

list_apps

Type probe
Module chaoscf.probes
Name list_apps
Return mapping

List all applications available to the authorized user.

See https://apidocs.cloudfoundry.org/280/apps/list_all_apps.html to understand the content of the response.

Signature:

def list_apps(configuration: Dict[str, Dict[str, str]],
              secrets: Dict[str, Dict[str, str]]) -> Dict[str, Any]:
    pass

Arguments:

Name Type Default Required

Usage:

{
  "provider": {
    "module": "chaoscf.probes",
    "func": "list_apps",
    "type": "python"
  },
  "type": "probe",
  "name": "list-apps"
}
name: list-apps
provider:
  func: list_apps
  module: chaoscf.probes
  type: python
type: probe

actions


delete_app

Type action
Module chaoscf.actions
Name delete_app
Return None

Delete application.

See https://apidocs.cloudfoundry.org/280/apps/delete_a_particular_app.html

Signature:

def delete_app(app_name: str,
               configuration: Dict[str, Dict[str, str]],
               secrets: Dict[str, Dict[str, str]],
               org_name: str = None,
               space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "delete_app",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "action",
  "name": "delete-app"
}
name: delete-app
provider:
  arguments:
    app_name: ''
  func: delete_app
  module: chaoscf.actions
  type: python
type: action

map_route_to_app

Type action
Module chaoscf.actions
Name map_route_to_app
Return list

Map a specific route to a given application.

As Domains are deprecated in the Cloud Foundry API, they are not specified here. See https://apidocs.cloudfoundry.org/280/#domains--deprecated- See https://www.cloudfoundry.org/blog/coming-changes-app-manifest-simplification/

See https://apidocs.cloudfoundry.org/280/apps/remove_route_from_the_app.html

Signature:

def map_route_to_app(app_name: str,
                     host_name: str,
                     configuration: Dict[str, Dict[str, str]],
                     secrets: Dict[str, Dict[str, str]],
                     org_name: str = None,
                     space_name: str = None) -> List[Dict[str, Any]]:
    pass

Arguments:

Name Type Default Required
app_name string Yes
host_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "map_route_to_app",
    "type": "python",
    "arguments": {
      "host_name": "",
      "app_name": ""
    }
  },
  "type": "action",
  "name": "map-route-to-app"
}
name: map-route-to-app
provider:
  arguments:
    app_name: ''
    host_name: ''
  func: map_route_to_app
  module: chaoscf.actions
  type: python
type: action

remove_routes_from_app

Type action
Module chaoscf.actions
Name remove_routes_from_app
Return None

Remove routes from a given application.

See https://apidocs.cloudfoundry.org/280/apps/remove_route_from_the_app.html

Signature:

def remove_routes_from_app(app_name: str,
                           route_host: str,
                           configuration: Dict[str, Dict[str, str]],
                           secrets: Dict[str, Dict[str, str]],
                           org_name: str = None,
                           space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
route_host string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "remove_routes_from_app",
    "type": "python",
    "arguments": {
      "route_host": "",
      "app_name": ""
    }
  },
  "type": "action",
  "name": "remove-routes-from-app"
}
name: remove-routes-from-app
provider:
  arguments:
    app_name: ''
    route_host: ''
  func: remove_routes_from_app
  module: chaoscf.actions
  type: python
type: action

start_all_apps

Type action
Module chaoscf.actions
Name start_all_apps
Return None

Start all applications for the specified org name

See https://apidocs.cloudfoundry.org/280/apps/updating_an_app.html

Signature:

def start_all_apps(org_name: str, configuration: Dict[str, Dict[str, str]],
                   secrets: Dict[str, Dict[str, str]]):
    pass

Arguments:

Name Type Default Required
org_name string Yes

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "start_all_apps",
    "type": "python",
    "arguments": {
      "org_name": ""
    }
  },
  "type": "action",
  "name": "start-all-apps"
}
name: start-all-apps
provider:
  arguments:
    org_name: ''
  func: start_all_apps
  module: chaoscf.actions
  type: python
type: action

start_app

Type action
Module chaoscf.actions
Name start_app
Return None

Start application

See https://apidocs.cloudfoundry.org/280/apps/updating_an_app.html

Signature:

def start_app(app_name: str,
              configuration: Dict[str, Dict[str, str]],
              secrets: Dict[str, Dict[str, str]],
              org_name: str = None,
              space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "start_app",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "action",
  "name": "start-app"
}
name: start-app
provider:
  arguments:
    app_name: ''
  func: start_app
  module: chaoscf.actions
  type: python
type: action

stop_all_apps

Type action
Module chaoscf.actions
Name stop_all_apps
Return None

Stop all application for the specified org name

See https://apidocs.cloudfoundry.org/280/apps/updating_an_app.html

Signature:

def stop_all_apps(org_name: str, configuration: Dict[str, Dict[str, str]],
                  secrets: Dict[str, Dict[str, str]]):
    pass

Arguments:

Name Type Default Required
org_name string Yes

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "stop_all_apps",
    "type": "python",
    "arguments": {
      "org_name": ""
    }
  },
  "type": "action",
  "name": "stop-all-apps"
}
name: stop-all-apps
provider:
  arguments:
    org_name: ''
  func: stop_all_apps
  module: chaoscf.actions
  type: python
type: action

stop_app

Type action
Module chaoscf.actions
Name stop_app
Return None

Stop application

See https://apidocs.cloudfoundry.org/280/apps/updating_an_app.html

Signature:

def stop_app(app_name: str,
             configuration: Dict[str, Dict[str, str]],
             secrets: Dict[str, Dict[str, str]],
             org_name: str = None,
             space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "stop_app",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "action",
  "name": "stop-app"
}
name: stop-app
provider:
  arguments:
    app_name: ''
  func: stop_app
  module: chaoscf.actions
  type: python
type: action

terminate_app_instance

Type action
Module chaoscf.actions
Name terminate_app_instance
Return None

Terminate the application’s instance at the given index.

See https://apidocs.cloudfoundry.org/280/apps/terminate_the_running_app_instance_at_the_given_index.html

Signature:

def terminate_app_instance(app_name: str,
                           instance_index: int,
                           configuration: Dict[str, Dict[str, str]],
                           secrets: Dict[str, Dict[str, str]],
                           org_name: str = None,
                           space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
instance_index integer Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "terminate_app_instance",
    "type": "python",
    "arguments": {
      "app_name": "",
      "instance_index": 0
    }
  },
  "type": "action",
  "name": "terminate-app-instance"
}
name: terminate-app-instance
provider:
  arguments:
    app_name: ''
    instance_index: 0
  func: terminate_app_instance
  module: chaoscf.actions
  type: python
type: action

terminate_some_random_instance

Type action
Module chaoscf.actions
Name terminate_some_random_instance
Return None

Terminate a random application’s instance.

See https://apidocs.cloudfoundry.org/280/apps/terminate_the_running_app_instance_at_the_given_index.html

Signature:

def terminate_some_random_instance(app_name: str,
                                   configuration: Dict[str, Dict[str, str]],
                                   secrets: Dict[str, Dict[str, str]],
                                   org_name: str = None,
                                   space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "terminate_some_random_instance",
    "type": "python",
    "arguments": {
      "app_name": ""
    }
  },
  "type": "action",
  "name": "terminate-some-random-instance"
}
name: terminate-some-random-instance
provider:
  arguments:
    app_name: ''
  func: terminate_some_random_instance
  module: chaoscf.actions
  type: python
type: action

unbind_service_from_app

Type action
Module chaoscf.actions
Name unbind_service_from_app
Return None

Unbind the service from the given application.

See https://apidocs.cloudfoundry.org/280/service_bindings/delete_a_particular_service_binding.html

Signature:

def unbind_service_from_app(app_name: str,
                            bind_name: str,
                            configuration: Dict[str, Dict[str, str]],
                            secrets: Dict[str, Dict[str, str]],
                            org_name: str = None,
                            space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
bind_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "unbind_service_from_app",
    "type": "python",
    "arguments": {
      "bind_name": "",
      "app_name": ""
    }
  },
  "type": "action",
  "name": "unbind-service-from-app"
}
name: unbind-service-from-app
provider:
  arguments:
    app_name: ''
    bind_name: ''
  func: unbind_service_from_app
  module: chaoscf.actions
  type: python
type: action

unmap_route_from_app

Type action
Module chaoscf.actions
Name unmap_route_from_app
Return None

Unmap a specific route from a given application.

As Domains are deprecated in the Cloud Foundry API, they are not specified here. See https://apidocs.cloudfoundry.org/280/#domains--deprecated- See https://www.cloudfoundry.org/blog/coming-changes-app-manifest-simplification/

See https://apidocs.cloudfoundry.org/280/apps/remove_route_from_the_app.html

Signature:

def unmap_route_from_app(app_name: str,
                         host_name: str,
                         configuration: Dict[str, Dict[str, str]],
                         secrets: Dict[str, Dict[str, str]],
                         org_name: str = None,
                         space_name: str = None):
    pass

Arguments:

Name Type Default Required
app_name string Yes
host_name string Yes
org_name string null No
space_name string null No

Usage:

{
  "provider": {
    "module": "chaoscf.actions",
    "func": "unmap_route_from_app",
    "type": "python",
    "arguments": {
      "host_name": "",
      "app_name": ""
    }
  },
  "type": "action",
  "name": "unmap-route-from-app"
}
name: unmap-route-from-app
provider:
  arguments:
    app_name: ''
    host_name: ''
  func: unmap_route_from_app
  module: chaoscf.actions
  type: python
type: action