Programming an iApps LX Config Processor

Prerequisites:

  • Access to a BIG-IP® version 14.0
  • You are a developer responsible for programming the internal iApps LX config processor configuration
  • Familiarity with the iApps® LX concept documentation, with an understanding of iApps LX templates and block instances
  • Knowledge of writing JSON blocks, as defined by the documented structure (see iApps LX Block Reference)
  • Familiar with creating an iControl LX extension (see Creating an iControl Extension)

On the back-end of the API contract interface, the config processor references support behind the scenes with onPost and onDelete API methods. After resolving an external API command, the iApps LX platform creates a new configuration task to complete the action. As a result of the new configuration task, the configuration processor receives an event with a JSON payload. The payload includes a block property and a selfLink resource reference. The selfLink references a specific task and indicates where to patch back to so that the block state can be updated.

Once an event is passed from the block instance to the config processor to be resolved, the config processor sends back an update to the block instance that it got the request (either a POST or DELETE). If it is a POST request to create/update a configuration, the received state will be BINDING. For a DELETE request to delete resources that are managed by the block instance, the received state will be UNBINDING. Setting the state field to BINDING tells the system to invoke the onPOST method or, alternatively, setting the state to UNBINDING tells the system to invoke the onDELETE method of the config processor. Then the config processor proceeds to execute the task. This process is managed internally by the blockConfigurationTaskCollectionWorker. The worker checks the BINDING/UNBINDING event state and then creates and runs a task. When relevant, (most of the time) the task calls the config processor. When done, the config processor sends a PATCH request back to the worker with an updated state. Once the task is completed, the worker updates the block with the resulting end state.

For example, once an external API is applied, the state engine is changed from UNBOUND to BINDING, and then the iApps LX platform takes responsibility for the state engine task, changing the state engine from BINDING to BOUND/ERROR.

The following diagram shows the task sequence flow between an external user, the iApp LX framework (including the worker), and the config processor:

../_images/config_task_sequence.jpg

About writing a JSON block for the Config Processor

The config processor, as the iApps LX controller, is a required component of an iApps LX block template. If not configured, by default the Configuration Processor uses the no-op processor as the iApps LX controller.

When configuring the config processor, the following properties are defined (either by default or manually) in the JSON block template:

  • configurationProcessorReference (required)
  • configProcessorTimeoutSeconds (optional)
  • configProcessorAffinity processor (Policy, affinityProcessorReference) (optional)

Once the template has been instantiated, the embedded block, is managed internally. This means, when the block instance is in a BINDING state, it needs to go through its own internal state engine, in order to process the block instance. The JSON block shows the following properties that monitor this internal task:

Block Configuration Task State Properties
Property Name Description
subStatus The task status states: WAIT_FOR_CONFIG_PROCESSOR_AVAILABLE, POST_TO_CONFIG_PROCESSOR, UPDATE_BLOCK_WITH_RESPONSE
id Unique identifier of an item in the collection
status Indicates the state engine status of the worker: STARTED, WAIT, UPDATED, TIMEOUT
startTime Starting time of configuration task
userReference A link to the user who initiated the task
identityReferences A list of the authenticated identities used to initiate the task

For this internal worker task, the “kind” property references the blockstate object (“shared:iapp:block-configuration-tasks:blockconfigurationtaskstate”) and the selfLink references back to the subStatus ID.

The following JSON block shows the config processor and block worker properties:

{  
    "block":{  
        "id":"a8a7a790-7b0d-4533-9075-8883dc79a90c",
        "name":"hello-world-app",
        "inputProperties":[  
            {  
                "id":"Hello",
                "type":"STRING",
                "value":"iApp World",
                "metaData":{  
                    
                }
            }
        ],
        "configurationProcessorReference":{  
            "link":"https://localhost/mgmt/shared/iapp/processors/hello-world-js"
        },
        "audit":{  
            "intervalSeconds":0,
            "policy":"NOTIFY_ONLY"
        },
        "configProcessorTimeoutSeconds":30,
        "statsProcessorTimeoutSeconds":15,
        "configProcessorAffinity":{  
            "processorPolicy":"LOAD_BALANCED",
            "affinityProcessorReference":{  
                "link":"https://localhost/mgmt/shared/iapp/processors/affinity/load-balanced"
            }
        },
        "state":"BINDING",
        "baseReference":{  
            "link":"https://localhost/mgmt/shared/iapp/blocks/3d546c81-1b1d-3838-b32b-a59d08020d28"
        },
        "generation":1,
        "lastUpdateMicros":1515706324295120,
        "kind":"shared:iapp:blocks:blockstate",
        "selfLink":"https://localhost/mgmt/shared/iapp/blocks/a8a7a790-7b0d-4533-9075-8883dc79a90c"
    },
    "subStatus":"POST_TO_CONFIG_PROCESSOR",
    "id":"c79719cc-f3c2-4868-afb9-3bcb6c34d991",
    "status":"STARTED",
    "startTime":"2018-01-11T13:32:04.306-0800",
    "userReference":{  
        "link":"https://localhost/mgmt/shared/authz/users/admin"
    },
    "identityReferences":[  
        {  
            "link":"https://localhost/mgmt/shared/authz/users/admin"
        }
    ],
    "ownerMachineId":"361a9678-12d0-408d-8081-a6e28b98b8fb",
    "generation":3,
    "lastUpdateMicros":1515706324324070,
    "kind":"shared:iapp:block-configuration-tasks:blockconfigurationtaskstate",
    "selfLink":"https://localhost/mgmt/shared/iapp/block-configuration-tasks/c79719cc-f3c2-4868-afb9-3bcb6c34d991"
}

Note

Another way to program the config processor state is to use configTaskUtil.js.

Editing the config processor properties

Using a REST API, you can edit the config processor properties in an iApps LX template/block instance.

  1. Open the /var/config/rest/iapps/<name of template>/nodejs/<name of template>ConfigProcessor.js
  2. Using a text editor, edit the code.
  3. Restart the restnoded deamon, with the following command: bigstart restart restnoded

You can also configure and edit the config processor properties from the BIG-IP GUI (Main > iApps > Templates > Templates LX > Advanced view). To edit the config processor, edit the link for the configurationProcessorReference:

"configurationProcessorReference": {
  "link": "https://localhost/<processor-path>"

Using the Default No-op Processor

By default the Configuration Processor uses the no-op processor as the iApps LX controller, and by default, enables the iApps LX template to be instantiated, no matter what IP Address is entered.

The following example shows an iApps LX template with the default no-op config processor (configurationProcessorReference property link) and the configProcessorTimeoutSeconds property default value of 30 seconds. For more information on these properties, see iApps LX Block Reference.

{
  "id": "d2c075d6-9570-31d1-9dfd-92cf4bf80703",
  "name": "QuickStart",
  "inputProperties": [
    {
      "id": "IPAddress",
      "type": "STRING",
      "value": "10.10.10.10",
      "metaData": {
        "type": "IPV4"
      }
    }
  ],
  "configurationProcessorReference": {
    "link": "https://localhost/mgmt/shared/iapp/processors/noop"
  },
  "audit": {
    "intervalSeconds": 0,
    "policy": "NOTIFY_ONLY"
  },
  "configProcessorTimeoutSeconds": 30,
  "statsProcessorTimeoutSeconds": 15,
  "state": "TEMPLATE",
  "generation": 1,
  "lastUpdateMicros": 1438640202797402,
  "kind": "shared:iapp:blocks:blockstate",
  "selfLink": "https://localhost/mgmt/shared/iapp/blocks/d2c075d6-9570-31d1-9dfd-92cf4bf80703"
}

To instantiate the block:

  1. Change the state property from TEMPLATE to BINDING before you make a POST request.
  2. Send a POST request using the URI shown here and include the JSON block as the payload.
POST https://<IP address>/mgmt/shared/iapp/blocks

 You can use cURL to make a POST request and provide the payload as an input file to the cURL command.
Result:After you POST the block, the response from the iApps LX state engine shows the original inputProperties from the template and an auto-generated UUID (item 1) as well as a selfLink to the block that includes the UUID in the path. You can use the selfLink path to query the state of the block instance, although you must replace the string localhost with the IP address of the BIG-IP system.
  1. To query the state of the task, make a GET request using the selfLink property.
GET https://<IP address>/mgmt/shared/iapp/blocks/d2c075d6-9570-31d1-9dfd-92cf4bf80703
Result:The inputProperties of the block remain unchanged from the POST request and the state of the block still appears as BINDING. The remaining properties at the bottom of the response include a generation property that represents a version number for the block object, a lastUpdateMicros property that reflects the timestamp of the request, and a kind property that refers to the blockstate object.
  1. At this phase, the blockConfigurationTaskCollectionWorker takes over as can be seen in the subStatus property and the selfLink property that refers back to the id of the task worker. The full task is completed once the**state** shows as BOUND or ERROR.

Todo

Add in code for step 4, asked Ted for it.