Home

Awesome

cfenv - easy access to your Cloud Foundry application environment

The cfenv package provides functions to parse Cloud Foundry-provided environment variables. Provides easy access to your port, http binding host name/ip address, URL of the application, etc. Also provides useful default values when you're running locally.

The package determines if you are running "locally" versus running as a Cloud Foundry app, based on whether the VCAP_APPLICATION environment variable is set. If not set, the functions run in "local" mode, otherwise they run in "cloud" mode.

quick start

var cfenv = require("cfenv")

var appEnv = cfenv.getAppEnv()
...
// start the server on the given port and binding host, and print
// url to server when it starts

server.listen(appEnv.port, appEnv.bind, function() {
    console.log("server starting on " + appEnv.url)
})

This code snippet above will get the port, binding host, and full URL to your HTTP server and use them to bind the server and print the server URL when starting.

running in Cloud Foundry vs locally

This package makes use of a number of environment variables that are set when your application is running in Cloud Foundry. These include:

If these aren't set, the getAppEnv() API will still return useful values, as appropriate. This means you can use this package in your program and it will provide useful values when you're running in Cloud Foundry AND when you're running locally. You can supply local versions of VCAP_SERVICES and/or VCAP_APPLICATION by using the vcap and vcapFile options described below.

api

The cfenv package exports the following function:

getAppEnv(options)

Get the core bits of Cloud Foundry data as an object.

The options parameter is optional, and can contain the following properties:

return value

The getAppEnv() function returns an object with the following properties:

The returned object also has the following methods available:

If no value can be determined for port, and the name property on the options parameter is not set and cannot be determined, a port of 3000 will be used.

If no value can be determined for port, and the name property on the options parameter is set or can otherwise be determined, that name will be passed to the ports package getPort() function to get a default port.

The protocol used for the URLs will be http: if the app is running locally, and https: otherwise; you can force a particular protocol by using the protocol property on the options parameter.

When running in Cloud Foundry, the url and urls values will have localhost as their hostname, if the actual hostnames cannot be determined.

AppEnv methods

The following methods are also available on the object returned by cfenv.getAppEnv().

appEnv.getServices()

Return all services, in an object keyed by service name.

Note that this is different than the services property returned from getAppEnv().

For example, assume VCAP_SERVICES was set to the following:

{
    "user-provided": [
        {
            "name": "cf-env-test",
            "label": "user-provided",
            "tags": [],
            "credentials": {
                "database": "database",
                "password": "passw0rd",
                "url": "https://example.com/",
                "username": "userid"
            },
            "syslog_drain_url": "http://example.com/syslog"
        }
    ]
}

In this case, appEnv.services would be set to that same object, but appEnv.getServices() would return

{
    "cf-env-test": {
        "name": "cf-env-test",
        "label": "user-provided",
        "tags": [],
        "credentials": {
            "database": "database",
            "password": "passw0rd",
            "url": "https://example.com/",
            "username": "userid"
        },
        "syslog_drain_url": "http://example.com/syslog"
    }
}

appEnv.getService(spec)

Return a service object by name.

The spec parameter should be a regular expression, or a string which is the exact name of the service. For a regular expression, the first service name which matches the regular expression will be returned.

Returns the service object from VCAP_SERVICES or null if not found.

appEnv.getServiceURL(spec, replacements)

Returns a service URL by name.

The spec parameter should be a regular expression, or a string which is the exact name of the service. For a regular expression, the first service name which matches the regular expression will be returned.

The replacements parameter is an object with the properties used in node's url function url.format().

Returns a URL generated from VCAP_SERVICES or null if not found.

To generate the URL, processing first starts with a url property in the service credentials. You can override the url property in the service credentials (if no such property exists), with a replacements property of url, and a value which is the name of the property in the service credentials whose value contains the base URL.

That url is parsed with node's url function url.parse() to get a set of initial url properties. These properties are then overridden by entries in replacements, using the following operation, for a given replacement key and value.

 url[key] = service.credentials[value]

The URL auth replacement is a bit special, in that it's value should be a two-element array of [userid, password], where those values are keys in the service.credentials

For example, assume VCAP_SERVICES was set to the following:

{
    "user-provided": [
        {
            "name": "cf-env-test",
            "label": "user-provided",
            "tags": [],
            "credentials": {
                "database": "database",
                "password": "passw0rd",
                "url": "https://example.com/",
                "username": "userid"
            },
            "syslog_drain_url": "http://example.com/syslog"
        }
    ]
}

Assume you run the following code:

url = appEnv.getServiceURL("cf-env-test", {
    pathname: "database",
    auth:     ["username", "password"]
})

The url result will be https://userid:passw0rd@example.com/database

Note that there MUST be a url property in the credentials, or replacement for it, in the service, or the call will return null. Also, because the url is parsed first with url.parse(), there will be a host property in the result, so you won't be able to use the hostname and port values directly. You can ONLY set the resultant hostname and port with the host property.

Note that url.parse() and the later url.format() calls to construct the result, will not produce pleasing results for "unusual" URLs, especially those which do not use http: or https: protocols. The url parse() and format() methods will not be used though, if you have no replacement values, or the only replacement property is url, and so are safe to use in that case.

Since the appEnv.getServiceURL() method operates against the appEnv.services property, you can fudge this object if that makes your life easier.

appEnv.getServiceCreds(spec)

Returns the credentials object of a service by name.

The spec parameter is the same as that used by the appEnv.getServiceURL() method. If there is no service that matches the spec parameter, this method will return null.

If there is a service that matches the spec parameter, the value of it's credentials property will be returned. If for some reason, there is no credentials property on the service, an empty object - {} - will be returned.

testing with Cloud Foundry

You can push this project as a Cloud Foundry project to try it out.

First, create a service name cf-env-test with the following command:

cf cups cf-env-test -p "url, username, password, database"

You will be prompted for these values; enter something reasonable like:

url>      http://example.com
username> userid
password> passw0rd
database> the-db

Next, push the app with cf push.

When you visit the site, you'll see the output of various cfenv calls.

changes

1.2.4 - 2021/04/03

1.2.3 - 2020/07/24

1.2.2 - 2019/03/26

1.2.1 - 2019/03/25

1.2.0 - 2019/02/21

1.1.0 - 2018/04/18

1.0.4 - 2017/01/13

1.0.3 - 2014/10/02

1.0.2 - 2014/09/29

1.0.1 - 2014/09/29

1.0.0 - 2014/09/03

contributing

See the CONTRIBUTING.md doc for more information on contributing to this project.

license

Apache License, Version 2.0

http://www.apache.org/licenses/LICENSE-2.0.html