Skip to content
This repository has been archived by the owner on Oct 12, 2020. It is now read-only.

10. webhooks

Khelil Sator edited this page Jun 13, 2017 · 13 revisions

What it is?

Push approach: HTTP POST to push data to StackStorm API from a script or software when an event you are interested in occurs.

ST2 trigger

The ST2 rule engine monitor triggers on the message bus (RabbitMQ).
In ST2, a trigger refers to the internal representation in ST2 of an external event.

With ST2 you can create your own sensors which allow you to define the trigger structure.

We are going to use custom webhook which has already a built-in trigger, so there is no need to define this trigger yourself in that case.

custom webhook versus Rest calls:

What's the diff between a regular rest call (toward ansible tower as example) and a custom webhook in ST2?

  • ST2 webhook is a characterization of an (no ST2) event. You are just transmitting to ST2 some sort of information. Then ST2 rule engine will decide what to do with these details. Because there is a rule engine between events and potential actions, one event can fire off many actions.
  • Using a regular rest call to a system (ansible tower ...) is a more imperative approach where you are requesting an very tool-related thing. Also there is one to one_only relationship between the rest call and the its outcome.

ST2 rule

You need to use an ST2 rule in a yaml file.
You can write a new rule yourself or use an existing one

How to get the list of existing rules from a pack:

$ sudo st2 rule list -p napalm
+--------------------------------------+--------+----------------------------------------------+---------+
| ref                                  | pack   | description                                  | enabled |
+--------------------------------------+--------+----------------------------------------------+---------+
| napalm.bgp_prefix_exceeded           | napalm | Webhook which handles a BGP neighbor         | True    |
|                                      |        | exceeding it's prefix limit                  |         |
| napalm.configuration_change          | napalm | Webhook which handles when a device has been | True    |
|                                      |        | configured and changes commited              |         |
| napalm.interface_down                | napalm | Webhook which handles an interface going     | True    |
|                                      |        | down on a network device.                    |         |
+--------------------------------------+--------+----------------------------------------------+---------+

ST2 rule creation

Let's create a rule that fire off the get_bgp_neighbors_detail action from the Napalm pack.
Get help with the action get_bgp_neighbors_detail from Napalm pack:

$ sudo st2 run napalm.get_bgp_neighbors_detail -h
Get a detailed BGP neighbor from a device using NAPALM.

Required Parameters:
    hostname
        The hostname of the device to connect to. Driver must be specified if
        hostname is not in configuration. Hostname without FQDN can be given
        if device is in configuration.
        Type: string

    neighbor
        The BGP neighbor to get details of.
        Type: string

Optional Parameters:
    driver
        Device driver name for connecting to device, see
        https://napalm.readthedocs.io/en/latest/support/index.html for list.
        Type: string

    port
        port for accessing device
        Type: string

    credentials
        The credentials group which contains the username and password to log
        in
        Type: string

    htmlout
        In addition to the normal output also includes html output.
        Type: boolean

    env
        Environment variables which will be available to the script.
        Type: object

    timeout
        Action timeout in seconds. Action will get killed if it doesn't finish
        in timeout seconds.
        Type: integer
        Default: 600

How to fire off manually this action
Example:

$ sudo st2 run napalm.get_bgp_neighbors_detail hostname=ex4300-9 neighbor=192.168.0.4
...
id: 59392734a374d87a9d505ccb
status: succeeded
parameters: 
  hostname: ex4300-9
  neighbor: 192.168.0.4
result: 
  exit_code: 0
  result:
    raw:
      inet.0:
        '110':
        - accepted_prefix_count: 5
          active_prefix_count: 2
          advertised_prefix_count: 5
          configured_holdtime: 90
          configured_keepalive: 30
          connection_state: Established
          export_policy: bgp-out
          flap_count: 0
          holdtime: 90
          import_policy: bgp-in
          input_messages: 321528
          input_updates: 3
          keepalive: 30
          last_event: RecvKeepAlive
          local_address: 192.168.0.5
          local_address_configured: false
          local_as: 109
          local_as_prepend: true
          local_port: 61847
          messages_queued_out: 0
          multihop: false
          multipath: true
          output_messages: 321494
          output_updates: 2
          previous_connection_state: OpenConfirm
          received_prefix_count: 5
          remote_address: 192.168.0.4
          remote_as: 110
          remote_port: 179
          remove_private_as: false
          router_id: 192.179.0.73
          routing_table: inet.0
          suppress_4byte_as: false
          suppressed_prefix_count: 0
          up: true
  stderr: ''
  stdout: ''

lets create this new rule

$ pwd
/opt/stackstorm/packs/napalm/rules
$ more rule_get_bgp_neighbors_details.yaml 
---
# once the rule is created (using the "st2 rule create" command, this rule reference will be generated napalm.rule_get_bgp_neighbors_detail)
  name: "rule_get_bgp_neighbors_detail"
  pack: "napalm"
  enabled: true
  description: "Webhook which get and display the BGP neighbors detail"

# this is required
# the rule engine watches triggers in Rabbit MQ. 
# this rule has core.st2.webhook trigger type. 
# which means, this rule get fired when an HTTP POST toward the url http://ST2:9101/v1/webhooks/napalm_get_bgp_neighbors_detail is received.
# when the POST is received, nginx generates a trigger_instance that has core.st2.webhook type with the details from the POST. 
# Then the rule engine can use this trigger_instance to fire off the action
  trigger:
    type: "core.st2.webhook"
    parameters:
      url: "napalm_get_bgp_neighbors_details"

# this is optionnal. you can use this section to introduce additionnal matching conditions (using http headers or http body).
  criteria: {}

# first select the action ref you want to use 
# define how to pass action parameters, i.e define how trigger_instance data (which come initially from HTTP POST headers and body) are passed as action´s paramters.
# the a
  action:
    ref: napalm.get_bgp_neighbors_detail
    parameters:
      hostname: "{{trigger.body.hostname}}"
      neighbor: "{{trigger.body.neighbor}}"

we also need to register the rule:

$ sudo st2 rule create rule_get_bgp_neighbors_details.yaml
+-------------+----------------------------------------------------------+
| Property    | Value                                                    |
+-------------+----------------------------------------------------------+
| id          | 5937bfa3a374d84239058e10                                 |
| name        | rule_get_bgp_neighbors_detail                            |
| pack        | napalm                                                   |
| description | Webhook which get and display the BGP neighbors detail   |
| action      | {                                                        |
|             |     "ref": "napalm.get_bgp_neighbors_detail",            |
|             |     "parameters": {                                      |
|             |         "hostname": "{{trigger.body.hostname}}",         |
|             |         "neighbor": "{{trigger.body.neighbor}}"          |
|             |     }                                                    |
|             | }                                                        |
| criteria    |                                                          |
| enabled     | True                                                     |
| ref         | napalm.rule_get_bgp_neighbors_detail                     |
| tags        |                                                          |
| trigger     | {                                                        |
|             |     "type": "core.st2.webhook",                          |
|             |     "ref": "core.a3951df7-edf3-4019-ac7e-51811465aa1f",  |
|             |     "parameters": {                                      |
|             |         "url": "napalm_get_bgp_neighbors_details"        |
|             |     }                                                    |
|             | }                                                        |
| type        | {                                                        |
|             |     "ref": "standard",                                   |
|             |     "parameters": {}                                     |
|             | }                                                        |
| uid         | rule:napalm:rule_get_bgp_neighbors_detail                |
+-------------+----------------------------------------------------------+
$ sudo st2 rule get napalm.rule_get_bgp_neighbors_detail
+-------------+----------------------------------------------------------+
| Property    | Value                                                    |
+-------------+----------------------------------------------------------+
| id          | 5937bfa3a374d84239058e10                                 |
| uid         | rule:napalm:rule_get_bgp_neighbors_detail                |
| ref         | napalm.rule_get_bgp_neighbors_detail                     |
| pack        | napalm                                                   |
| name        | rule_get_bgp_neighbors_detail                            |
| description | Webhook which get and display the BGP neighbors detail   |
| enabled     | True                                                     |
| action      | {                                                        |
|             |     "ref": "napalm.get_bgp_neighbors_detail",            |
|             |     "parameters": {                                      |
|             |         "hostname": "{{trigger.body.hostname}}",         |
|             |         "neighbor": "{{trigger.body.neighbor}}"          |
|             |     }                                                    |
|             | }                                                        |
| criteria    |                                                          |
| tags        |                                                          |
| trigger     | {                                                        |
|             |     "type": "core.st2.webhook",                          |
|             |     "ref": "core.a3951df7-edf3-4019-ac7e-51811465aa1f",  |
|             |     "parameters": {                                      |
|             |         "url": "napalm_get_bgp_neighbors_details"        |
|             |     }                                                    |
|             | }                                                        |
| type        | {                                                        |
|             |     "ref": "standard",                                   |
|             |     "parameters": {}                                     |
|             | }                                                        |
+-------------+----------------------------------------------------------+
$ sudo st2 rule list -p napalm
+--------------------------------------+--------+----------------------------------------------+---------+
| ref                                  | pack   | description                                  | enabled |
+--------------------------------------+--------+----------------------------------------------+---------+
| napalm.bgp_prefix_exceeded           | napalm | Webhook which handles a BGP neighbor         | True    |
|                                      |        | exceeding it's prefix limit                  |         |
| napalm.configuration_change          | napalm | Webhook which handles when a device has been | True    |
|                                      |        | configured and changes commited              |         |
| napalm.interface_down                | napalm | Webhook which handles an interface going     | True    |
|                                      |        | down on a network device.                    |         |
| napalm.rule_get_bgp_neighbors_detail | napalm | Webhook which get and display the BGP        | True    |
|                                      |        | neighbors detail                             |         |
+--------------------------------------+--------+----------------------------------------------+---------+

Generate a token for nginx authentication

$ st2 auth st2admin -p Juniper123
+----------+----------------------------------+
| Property | Value                            |
+----------+----------------------------------+
| user     | st2admin                         |
| token    | a2bb65e6095145df9dedd51c017d9dfa |
| expiry   | 2017-06-08T09:03:57.135100Z      |
+----------+----------------------------------+

Generate an HTTP POST

get the list of last executed actions:

$ sudo st2 execution list -n 5
+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+
| id                       | action.ref                   | context.user | status                 | start_timestamp              | end_timestamp                 |
+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+
| 5936dc57a374d80941ef662e | ansible.playbook             | st2admin     | succeeded (3s elapsed) | Tue, 06 Jun 2017 16:46:15    | Tue, 06 Jun 2017 16:46:18 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5936dc6ea374d80941ef6631 | ansible.playbook             | st2admin     | succeeded (2s elapsed) | Tue, 06 Jun 2017 16:46:38    | Tue, 06 Jun 2017 16:46:40 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5936dc9da374d80941ef6634 | ansible.playbook             | st2admin     | succeeded (5s elapsed) | Tue, 06 Jun 2017 16:47:25    | Tue, 06 Jun 2017 16:47:30 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5936dcaca374d80941ef6637 | ansible.playbook             | st2admin     | succeeded (5s elapsed) | Tue, 06 Jun 2017 16:47:40    | Tue, 06 Jun 2017 16:47:45 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5937b0faa374d84239058e0d | napalm.get_bgp_neighbors_det | st2admin     | succeeded (3s elapsed) | Wed, 07 Jun 2017 07:53:30    | Wed, 07 Jun 2017 07:53:33 UTC |
|                          | ail                          |              |                        | UTC                          |                               |
+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+

Generate this HTTP POST

$ curl -k -H "Content-Type:application/json" -H "X-Auth-Token:a2bb65e6095145df9dedd51c017d9dfa" -d '{"hostname":"ex4300-9","neighbor":"192.168.0.4"}' http://localhost:9101/v1/webhooks/napalm_get_bgp_neighbors_details

This fire off this action st2 run napalm.get_bgp_neighbors_detail hostname=ex4300-9 neighbor=192.168.0.4

Verify the POST enforced the rule:

$ sudo st2 rule-enforcement list -n 1
+--------------------------+------------------------------------+--------------------------+--------------------------+-------------------------------+
| id                       | rule.ref                           | trigger_instance_id      | execution_id             | enforced_at                   |
+--------------------------+------------------------------------+--------------------------+--------------------------+-------------------------------+
| 5937c2d8a374d80669723c7a | napalm.rule_get_bgp_neighbors_deta | 5937c2d8a374d80669723c76 | 5937c2d8a374d80669723c79 | Wed, 07 Jun 2017 09:09:44 UTC |
|                          | il                                 |                          |                          |                               |
+--------------------------+------------------------------------+--------------------------+--------------------------+-------------------------------+

Lets check the origin of the event (using trigger_instance_id)

$ sudo st2 trigger-instance get 5937c2d8a374d80669723c76
+-----------------+--------------------------------------------------------------+
| Property        | Value                                                        |
+-----------------+--------------------------------------------------------------+
| id              | 5937c2d8a374d80669723c76                                     |
| trigger         | core.a3951df7-edf3-4019-ac7e-51811465aa1f                    |
| occurrence_time | 2017-06-07T09:09:44.310000Z                                  |
| payload         | {                                                            |
|                 |     "body": {                                                |
|                 |         "hostname": "ex4300-9",                              |
|                 |         "neighbor": "192.168.0.4"                            |
|                 |     },                                                       |
|                 |     "headers": {                                             |
|                 |         "Content-Length": "48",                              |
|                 |         "X-Request-Id": "15b71e1a-                           |
|                 | c9c2-47b2-a4b0-b9f34b464854",                                |
|                 |         "Accept": "*/*",                                     |
|                 |         "X-Auth-Token": "a2bb65e6095145df9dedd51c017d9dfa",  |
|                 |         "Host": "localhost:9101",                            |
|                 |         "User-Agent": "curl/7.35.0",                         |
|                 |         "Content-Type": "application/json"                   |
|                 |     }                                                        |
|                 | }                                                            |
| status          | processed                                                    |
+-----------------+--------------------------------------------------------------+

This is action that has been automatically triggered (execution_id 5937c2d8a374d80669723c79)

$ sudo st2 execution get 5937c2d8a374d80669723c79
id: 5937c2d8a374d80669723c79
status: succeeded (4s elapsed)
parameters:
  hostname: ex4300-9
  neighbor: 192.168.0.4
result:
  exit_code: 0
  result:
    raw:
      inet.0:
        '110':
        - accepted_prefix_count: 5
          active_prefix_count: 2
          advertised_prefix_count: 5
          configured_holdtime: 90
          configured_keepalive: 30
          connection_state: Established
          export_policy: bgp-out
          flap_count: 0
          holdtime: 90
          import_policy: bgp-in
          input_messages: 318159
          input_updates: 3
          keepalive: 30
          last_event: RecvKeepAlive
          local_address: 192.168.0.5
          local_address_configured: false
          local_as: 109
          local_as_prepend: true
          local_port: 61847
          messages_queued_out: 0
          multihop: false
          multipath: true
          output_messages: 318125
          output_updates: 2
          previous_connection_state: OpenConfirm
          received_prefix_count: 5
          remote_address: 192.168.0.4
          remote_as: 110
          remote_port: 179
          remove_private_as: false
          router_id: 192.179.0.73
          routing_table: inet.0
          suppress_4byte_as: false
          suppressed_prefix_count: 0
          up: true
  stderr: ''
  stdout: ''

stanley is a user for all the event driven actions.

$ sudo st2 execution list -n 5

+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+
| id                       | action.ref                   | context.user | status                 | start_timestamp              | end_timestamp                 |
+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+
| 5936dc6ea374d80941ef6631 | ansible.playbook             | st2admin     | succeeded (2s elapsed) | Tue, 06 Jun 2017 16:46:38    | Tue, 06 Jun 2017 16:46:40 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5936dc9da374d80941ef6634 | ansible.playbook             | st2admin     | succeeded (5s elapsed) | Tue, 06 Jun 2017 16:47:25    | Tue, 06 Jun 2017 16:47:30 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5936dcaca374d80941ef6637 | ansible.playbook             | st2admin     | succeeded (5s elapsed) | Tue, 06 Jun 2017 16:47:40    | Tue, 06 Jun 2017 16:47:45 UTC |
|                          |                              |              |                        | UTC                          |                               |
| 5937b0faa374d84239058e0d | napalm.get_bgp_neighbors_det | st2admin     | succeeded (3s elapsed) | Wed, 07 Jun 2017 07:53:30    | Wed, 07 Jun 2017 07:53:33 UTC |
|                          | ail                          |              |                        | UTC                          |                               |
| 5937c2d8a374d80669723c79 | napalm.get_bgp_neighbors_det | stanley      | succeeded (4s elapsed) | Wed, 07 Jun 2017 09:09:44    | Wed, 07 Jun 2017 09:09:48 UTC |
|                          | ail                          |              |                        | UTC                          |                               |
+--------------------------+------------------------------+--------------+------------------------+------------------------------+-------------------------------+