Skip to content
This repository has been archived by the owner on Jul 14, 2022. It is now read-only.

Configuration

Will Witman edited this page Feb 13, 2015 · 12 revisions

Configuring Apigee-127

The Apigee-127 configuration system provides a powerful, flexible way to configure projects for whatever deployment use case you can imagine.

Through a set of hierarchical configuration files, and a strict precedence order for loading and resolving them, you can inject individual values and complex objects into your project's Swagger file at the time you start or deploy your project. You can also create account-specific configurations, giving you added flexibility depending on where you wish to deploy your project.

About Apigee-127 configuration

Using the anchor/alias feature supported by YAML, Apigee-127 can reference and replace config values (and complex objects) in the Swagger file when it is loaded.

In the following diagram, a single value from a config file is injected into the Swagger file. Note that you can replace complex objects as well as single values.

alt text

For example, if the following key/value pairs are added to one of the supported config files:

   apigeeProxyKey: 7nXWZAbque9n38IOdG2ZIbET1
   apigeeProxyUri: 'http://jdoe-test.apigee.net/apigee-remote-proxy'

...you can configure corresponding "anchors" (denoted by &) in the Swagger file through the x-a127-config vendor extension. Note that elements apigeeProxyKey and apigeeProxyUri exactly match the key names from the config file:

  x-a127-config:
      apigeeProxyKey: &apigeeProxyKeyAnchor CONFIGURED   # default value
      apigeeProxyUri: &apigeeProxyUriAnchor CONFIGURED   # default value

...you can reference those anchors anywhere in the Swagger file with aliases (denoted by *), like this:

oauth2:
    provider: volos-oauth-apigee
    options:
      key: *apigeeProxyKeyAnchor
      uri: *apigeeProxyUriAnchor

...effectively, after the substitutions are made the result is this:

  oauth2:
    provider: volos-oauth-apigee
    options:
      key: 7nXWZAbque9n38IOdG2ZIbET1
      uri: 'http://jdoe-test.apigee.net/apigee-remote-proxy'

You can do a lot more than replace simple values with the Apigee-127 configuration system. This topic discusses other use cases and examples. In effect, almost everything in an Apigee-127 project is configurable!

How configuration works

Apigee-127 Swagger files are YAML documents. YAML has the ability to use anchors and aliases that are resolved at load-time.

Note: From the YAML specification -- An anchor is denoted by the “&” indicator. It marks a node for future reference. An alias node (denoted by "*") can then be used to indicate additional inclusions of the anchored node.

This YAML feature allows Apigee-127 to make substitutions in the Swagger file before the YAML resolution happens. Thus YAML, in combination with the configuration system of Apigee-127, gives you the ability to resolve or replace configured elements at load-time throughout the Swagger document.

Location of configuration files

You have the option to store configuration key/value pairs in three locations within an Apigee-127 project:

The key/value pairs are read by Apigee-127 and used to replace anchors in the Swagger file at load-time. They are loaded by a specific order of precedence.

Apigee-127 account

You create an a127 account with the a127 account create command. At that time, you specify which account provider you wish to use (amazon, apigee, or local are the current choices).

Account values are, by default, stored in ~/.a127/accounts as a JSON object. For example, here is the configuration for an Apigee account. It includes information needed by the API to interact with certain Apigee Edge features. For example, the volos-management-apigee module requires the username, password, and organization to perform functions like creating developers and developer apps on Apigee Edge.

  {
    "accounts": {
        "wwitman-01": {
            "baseuri": "https://api.enterprise.apigee.com",
            "organization": "docs",
            "username": "wwitman@apigee.com",
            "password": "mypassword",
            "environment": "prod",
            "virtualhosts": "default,secure",
            "provider": "apigee"
        }
    },
    "selected": "wwitman-01"
}

When you start a project with a127 project start, values from this configuration file are put into your project's ./config/.a127_secrets file.

Note: There's never any reason to edit this file; it is recreated each time you restart your project. This data is saved with your project so that it is available to the project wherever it's deployed.

When you start or deploy a project, the values configured for the currently selected account are processed and substituted in corresponding anchors that are configured in your Swagger.yaml file's x-a127-config section.

Let's look at an example. Below, the values for organization, username, and password come directly from the account (an account created with the Apigee provider). The other two values, myremoteproxy678.key and myremoteproxy678.uri, come from the default.yaml config file.

   x-a127-config:
      myremoteproxy678.key: &apigeeProxyKey CONFIGURED
      myremoteproxy678.uri: &apigeeProxyUri CONFIGURED
      organization: &organization CONFIGURED
      username: &username CONFIGURED
      password: &password CONFIGURED

How are these values used?

The key and uri values are required by the OAuth 2.0 provider, and are specified in the OAuth declaration under x-volos-resources. These values are required by the volos-oauth-apigee module.

    x-volos-resources:
      oauth2:
          provider: volos-oauth-apigee
          options:
            tokenLifetime: 300000
            key: *apigeeProxyKey
            uri: *apigeeProxyUri
            validGrantTypes:
              - client_credentials
              - authorization_code
              - implicit_grant
              - password
            passwordCheck:
              helper: volos
              function: passwordCheck
            tokenPaths:  # These will be added to your paths section for you
              authorize: /authorize
              token: /accesstoken
              invalidate: /invalidate
              refresh: /refresh

The organization, username, and password values are required if you use the apigee-volos-management module. For example:

    x-volos-resources:
      management:
        provider: volos-management-apigee
        options:
          organization: *organization
          user: *username
          password: *password

When you start the project, the values in the a127-config section are substituted in the x-volos-resources configurations.

organization: &organization CONFIGURED is plugged into: organization: *organization

config/default.yaml

The default.yaml file provides another option for storing config keys/values that are loaded into Swagger at load-time. The default default.yaml config is always loaded no matter which account is active. This option may allow flexibility in specifying certain default values, for example.

Note: While you can only store key/value pairs (strings or numbers) in your Apigee-127 account, you can store entire complex objects in this YAML file, and they will be substituted in the Swagger file when it is loaded. For an example, see Example 3: Replacing an entire declaration.

config/[ACCOUNT_NAME].yaml

For yet another option, you can store config in config/[ACCOUNT_NAME].yaml. In this case, you can store configuration values that are account-specific. If you're running your project under an account named 'apigee', then the apigee.yaml config file will be loaded. This config file gives you another opportunity to design your configuration with maximum flexibility.

Note: While you can only store key/value pairs (strings or numbers) in your Apigee-127 account, you can store entire complex objects in this YAML file, and they will be substituted in the Swagger file when it is loaded. For an example, see Example 3: Replacing an entire declaration.

Configuration file precedence

During application start or deploy, configuration is loaded and resolved according to specificity as follows:

config/default.yaml < config/[NAME].yaml < active Apigee-127 account

Configuration elements on the right override elements with the same name to their left.

So, for example, if a value for the key myConfigElement is specified in both default.yaml and in the active Apigee-127 account, the account value takes precedence -- it will be the replacement value used in the Swagger file.

Setting config values in your account

You can set key/value pairs in your currently active account using the a127 account setValue key value command.

Example:

a127 account setValue myConfigElement foo

This command adds the key value pair to your active account:

Account
=======
organization: jdoe
username: jdoe@example.com
password: '******'
environment: test
apigeeProxyKey: 7nXWZAbque9n38IoDfxdG2ZIbET1
apigeeProxyUri: 'http://jdoe-test.apigee.net/apigee-remote-proxy'
baseuri: 'https://api.enterprise.apigee.com'
virtualhosts: 'default,secure'
provider: apigee
myConfigElement: foo

Now, the key/value pair can be referenced in the Swagger document at load-time.

More examples

Here are several examples demonstrating the use and flexibility of Apigee-127 configuration.

Example 1: Replacing a provider

The Volos.js provider is replaced by the "cacheProvider" key in the config file when the project is started:

x-a127-config:
  cacheProvider: &cacheProvider volos-cache-memory  # replaced by "cacheProvider" key in config
x-a127-services:
  cache:
    provider: *cacheProvider

In this case, note that the volos-cache-memory provider is the default. Be sure to include any potential modules required by the resolved provider in the project's package.json.

Example 2: Replacing an entire declaration

The x-a127-config extension also allows for complex objects in the configuration file to be "aliased" in the Swagger file.

Let's say the configuration file default.yaml includes a complex declaration like this:

oauth:
    provider: volos-oauth-apigee
    options:
    key: xyz123
    uri: 'http://example.com'

Then, you can reference this complex declaration in the Swagger file, in the same way you reference specific values:

x-a127-config:
  oauth: &volosOAuth        # replaced by "oauth" key in config
    provider: volos-oauth-apigee
    options:
      key: VNE6pxpoHxR3PeGCAb8tUk05TTg5R
      uri: 'http://my-test.apigee.net/apigee-remote-proxy'
x-a127-services:
  oauth: *oauth

In this case, the entire "oauth" object from the config file is substituted into the Swagger. After resolution, you'd effectively have this configuration:

  x-a127-services:
    oauth:
        provider: volos-oauth-apigee
        options:
            key: xyz123
            uri: 'http://example.com'

Configuring arbitrary values

In the previous examples, we used the flexible a127 config system to replace values specific to Volos.js-based policies. For example, we replaced key/parameter values for the cache policy and the provider for an OAuth policy.

But, you can use a127 config to replace any arbitrary values in the swagger.yaml file (not just values related to Volos modules like caching or OAuth). For example, you might want to use configuration to set a value depending on whether the project is deployed to Apigee Edge or is running locally.

Let's configure a variable foo with value bar in ./config/default.yaml.

    foo: "bar"

Then, declare the configured value in your Swagger file's x-a127-config section, like this:

  x-a127-config:
    foo: &foovalue SOMEDEFAULT   # default value 

Now, you can use foovalue to replace any arbitrary value in the Swagger file. Here, we make the value of a controller variable. In this example, when the /hello_config path is called, it will execute a controller file called bar. It's a simple replacement made when the Swagger is processed:

    /hello_config:
      # binds a127 app logic to a route
      x-swagger-router-controller: *foovalue 

As explained in previous examples, you aren't limited to replacing just strings. You can also configure and replace complex objects.

Accessing configuration values programmatically

You can access configuration values programmatically in your project's main Node.js file (app.js) and in controller and helper functions. This section explains the basic patterns.

You can access values that are set in a configuration file in your project's main app.js source file. Let's say you have this value defined in the project's ./config/default.yaml file:

    aValueFromConfig: "foo"

Then, this config definition in your swagger.yaml grabs the value from the default.yaml file and puts it in a variable, which can be used later in the Swagger file:

   x-a127-config:
      aValueFromConfig: &myVariableName "A Default Value"

However, you can also retrieve that configured value in your project's main application file from the config object, like this:

    'use strict';

    var a127 = require('a127-magic');
    var express = require('express');
    var app = express();

    module.exports = app; // for testing

    a127.init(function(config) {
      app.use(a127.middleware(config));

      var myConfig = config['aValueFromConfig'];
      console.log("Configured value: " + myConfig); // Prints "foo"

      app.listen(process.env.PORT || 10010);
      console.log('try this:\ncurl http://127.0.0.1:10010/hello?name=Scott');
    });

If you want to access config values in a controller or helper, it's easy to do. In the main app, put the configured value in the request, like this:

    a127.init(function(config) {

      // add config to the request
      app.use(function(req, res, next) {
        req.config = config;
        next();
      });

      app.use(a127.middleware(config));

Then, in your controller or helper, you can access the config value (or any value in config) like this:

var myConfig = req.config.aValueFromConfig;

Concealing your Apigee account password

When you create an a127 account and specify the "apigee" provider, you are required to provide your Apigee Edge account information, including password.

When you start an a127 project, your Apigee account information is stored in the project config file ./config/.a127_secrets. The values in this file are available to your project through the configuration system:

    baseuri: 'https://api.enterprise.apigee.com'
    organization: jdoe
    username: jdoe@example.com
    environment: prod
    virtualhosts: 'default,secure'
    provider: apigee
    name: myaccount
    _a127_start_config:
       debug: null
       mock: null

Note that by default, your password is omitted from this file. However, if your project uses the Volos.js management API to interact with Apigee Edge, a user, password, and organization are required parameters, and you can access them in your a127 code. You can find docs on this API in the apigee127/volos project on GitHub.

To override the default and store the password in .a127_secrets, set the includePasswordInSecrets parameter to true in one of your configuration files (like ./config/default.yaml).

For an example, see the security-apikey-apigee sample project on GitHub.

In many cases, there is no need to store this password with your project.

Important: Open ./config/default.yaml. Notice that it has one configuration setting in it: includePasswordInSecrets: true This setting is false by default. When set to true, the password that you specified when you created your a127 account is stored in ./config/.a127_secrets. This file is generated each time you start your a127 project, and the values in it are available to your project through the configuration system. To use the Management API, a user, password, and organization are required parameters, and in this implementation, they are obtained automatically from this configuration system.

Clone this wiki locally