在Docker容器上运行的Stackstorm的工作流可以通过使用Ansible的Playbook结果通知到Slack中[junos_command模块使用]

首先

因为需要确认是否可以从Stackstorm的工作流中执行Ansible的Playbook来操作Juniper设备的QFX,所以我不得不进行调查(不顾新年假期)。

st2_deumo_junos.gif

我使用了Juniper vLabs,这是一个可以免费快速验证Juniper设备的平台,但由于设置方面遇到了一些困难,所以我会将设置备忘录记录在本文中。

我很随意地研究了一下,在Docker容器上设置的Stackstorm工作流中,能否执行针对Juniper QFX的Ansible Playbook,并将结果发送到Slack。

通过执行本文所述设定,您可以将Ansible Playbook的执行结果通知到Slack。

post_msg.png

1. 章节目录

    • 2. 構成図/環境/バージョン情報

 

    • 3. Juniper vLabsの設定

 

    • 4. Ansible環境の構築

 

    5. AnsibleのPlaybookの結果をslackに通知するWorkflowの解説

Ansible环境的构建是通过使用sed命令替换Juniper设备的IP地址等信息来创建Ansible的inventory/hosts文件,为了方便起见,本文将从Juniper vLabs的配置开始讲解。如果您拥有自己的任意网络设备,请根据实际情况进行相应的调整。

2. 构成图/环境/版本信息 tú//

构图

st2_docker_ansible.png

在draw.io上创建

环境/版本信息

我从我发布的以下文章中节选出来的。
– 从Docker开始重新学习StackStorm 1/3(从环境搭建到使用Orquesta编写工作流程并通知到Slack)。

AWS(EC2、VPC、EIP,等等)

Ubuntu 18.04.3 LTS
t2.large
只有一个公共子网
启用公共IP(自动分配公共IP)
存储为通用用途SSD(gp2),大小为8(选择t2.large时的默认值)
安全组仅允许本地连接ssh,HTTP和HTTPS全开放
(HTTP允许从应用容器访问,HTTPS允许从web访问Stackstorm)

(省略图表等)

Stackstorm的版本

Stackstorm:3.1.0,使用Python 2.7.6 #为了使用orquesta,Stackstorm的版本必须3.0以上。
RabbitMQ:3.6
MongoDB:3.4
Redis:4.0
Postgresql:9.6
Docker版本19.03.5,构建633a0ea838
docker-compose版本1.24.1,构建4667896b

    • 今回扱うトポロジーのStandalone vQFX Light

Single vQFX (RE only)
Junos OS 15.1X53-D63.9

valbs_login.png

3. Juniper vLabs的配置

    • ルーティング、スイッチング、セキュリティを無料で検証することができるJuniper社のサービス

Juniper vLabs – Juniper Networks ログインURL

利用するうえで必要なことはアカウントの開設と検証したいトポロジーの選択だけ
トポロジーの選択画面から選択した機器に対して3時間だけsshコンソール画面から、あるいは手元のPCからssh接続できる

关于基本设置的内容

由于@akira6592的文章很有参考价值,请务必查看!写作变得很麻烦

    Juniper 機器が検証できるリモートラボサービス「Juniper vLabs」の利用方法

知道访问设备的用户名和密码的方法

    • トポロジーを選択すると届く、Your Juniper vLab “Standalone vQFX-Light” is now availableという表題のメールに下記のとおり記載されている

Device login credentials: /

在从手头的电脑进行SSH连接所需的设置。

    手元のpcからsshする場合、Add Allowed Network Prefixesに接続時に使うアクセス元IPアドレス(xxx.xxx.xxx.xxx/32)などと入力
juniper_valbs.png

上のとおり、IPアドレスを入力すると届く、Update about Direct Access to the resources in your vLab “Standalone vQFX-Light”という表題のメールに下記のとおり記載されている

Abstract Resource Name Protocol Public IP Address Public Port

vQFX_Light SSH

vQFX_Light NETCONF yyy.yyy.yyy.yyy bbbb

我尝试从终端连接到SSH。

$ ssh <username>@<ip> -p <port>
(略)
Password:
--- JUNOS 15.1X53-D63.9 built 2017-04-01 20:45:26 UTC
{master:0}
jcluser@Template-vQFX-Light> show version | no-more 
fpc0:
--------------------------------------------------------------------------
Hostname: Template-vQFX-Light
Model: vqfx-10000
Junos: 15.1X53-D63.9
JUNOS Base OS boot [15.1X53-D63.9]
JUNOS Base OS Software Suite [15.1X53-D63.9]
JUNOS Online Documentation [15.1X53-D63.9]
JUNOS Crypto Software Suite [15.1X53-D63.9]
JUNOS Packet Forwarding Engine Support (qfx-10-f) [15.1X53-D63.9]
JUNOS Kernel Software Suite [15.1X53-D63.9]
JUNOS Web Management [15.1X53-D63.9]
JUNOS Enterprise Software Suite [15.1X53-D63.9]
JUNOS SDN Software Suite [15.1X53-D63.9]
JUNOS Routing Software Suite [15.1X53-D63.9]
JUNOS py-base-i386 [15.1X53-D63.9]

{master:0}
jcluser@Template-vQFX-Light> 

4. 构建Ansible环境

如果您不想使用Stackstorm,只使用Ansible来执行的话,请直接配置inventory/hosts文件。

    Dockerで始めるStackstorm再入門1/3(環境構築からOrquestaで書いたWorkflowの結果をslackに通知する)

使用ansible所需的必要文件

    • /opt/stackstorm/packs/ansible/inventory/hosts

/st2-docker/opt/reload.sh内でsedコマンドで書き換えている

[localhost]
127.0.0.1

[junos]
<JUNOS_IP>  # export JUNOS_IP='<ip>'
    • /opt/stackstorm/packs/ansible/inventory/group_vars/junos

/st2-docker/opt/reload.sh内でsedコマンドで書き換えている

---
ansible_connection: network_cli 
ansible_network_os: junos
ansible_port: <JUNOS_PORT>       # export JUNOS_PORT='<port>'
ansible_ssh_user: <JUNOS_USER>   # export JUNOS_USER='<username>'
ansible_ssh_pass: <JUNOS_PASS>   # JUNOS_PASS='<password>'
    • /opt/stackstorm/packs/ansible/ansible.cfg

https://github.com/gkzz/st2-docker-gkz.gitをクローンしていれば、設定済

[defaults]
host_key_checking = False
    • /opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml

https://github.com/gkzz/st2-docker-gkz.gitをクローンしていれば、設定済

---
- hosts: junos
  connection: network_cli
  gather_facts: no
  become: yes

  tasks:
    - name: show version
      junos_command:
        commands:
          - show version
          - show interface terse
      when: ansible_network_os == "junos"
      register: result
    - debug: 
        msg: "{{ result.stdout_lines }}"

使用st2命令执行Ansible的Playbook。

root@$HOSTNAME:/# st2 run ansible.playbook \
inventory_file=/opt/stackstorm/packs/ansible/inventory/hosts \
playbook=/opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml

5. 解释如何将Ansible Playbook的结果通知到Slack的工作流程。

    Workflow


description: playbook-demo-junos

input:
  - playbook
  - inventory_file

output:
  - failed: <% ctx().failed %>
  - action_name: <% ctx().action_name %>

tasks:
  init:
    action: core.noop
    next:
    - publish:
        - failed: False
        - action_name: 'playbook-demo-junos'
      do: playbook

  playbook:
    action: ansible.playbook
    input:
      playbook: <% ctx().playbook %>
      inventory_file: <% ctx().inventory_file %>
    next:
      - when: <% succeeded() and (result().stderr = '') %>     
        do: last
        publish:
          - action_result: |-
              [succeeded] <% result().succeeded %>
              [return_code] <% result().return_code %>
              [stdout] <% result().stdout %>
              [stderr] <% result().stderr %>
      - when: <% succeeded() and (result().stderr != '') %> # AnsibleからのWARNINGメッセージなどが出力されることがあったので、stderr != ''のときもlackに通知するようにした
        do: post_msg
        publish:
          - action_result: |-
              [succeeded] <% result().succeeded %>
              [return_code] <% result().return_code %>
              [stdout] <% result().stdout %>
              [stderr] <% result().stderr %>
      - when: <% failed() %>
        do: post_msg
        publish:
          - failed: True
          - action_result: |-  
              [succeeded] <% result().succeeded %>
              [return_code] <% result().return_code %>
              [stdout] <% result().stdout %>
              [stderr] <% result().stderr %>

  post_msg:
    action: slack.post_message
    input:
      message: <% ctx().action_result %>
    next:
      - do: last

  last:
    action: core.noop
    next:
      - when: <% ctx().failed %>
        do: fail
    Workflowのメタファイル(Workflowを実行するうえで必要な引数やエントリーポイントの定義ファイル)
---
name: "playbook-demo-junos"
pack: "mydemo_pack"
description: "Playbook Demo of junos"
runner_type: "orquesta"
entry_point: "workflows/playbook-demo-junos.yaml"
enabled: true
parameters:
  playbook:
    type: "string"
    required: true
    default: "/opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml"
  inventory_file:
    type: "string"
    required: true
    default: "/opt/stackstorm/packs/ansible/inventory/hosts"

root@$HOSTNAME:/# st2 run mydemo_pack.playbook-demo-junos
.......
id: 5e0f63c87b2fca012e129850
action.ref: mydemo_pack.playbook-demo-junos
parameters: None
status: succeeded
start_timestamp: Fri, 03 Jan 2020 15:54:48 UTC
end_timestamp: Fri, 03 Jan 2020 15:55:00 UTC
result: 
  output:
    action_name: playbook-demo-junos
    failed: false
+--------------------------+-------------------------+----------+------------+-----------------+
| id                       | status                  | task     | action     | start_timestamp |
+--------------------------+-------------------------+----------+------------+-----------------+
| 5e0f63c87b2fca00372f716d | succeeded (0s elapsed)  | init     | core.noop  | Fri, 03 Jan     |
|                          |                         |          |            | 2020 15:54:48   |
|                          |                         |          |            | UTC             |
| 5e0f63c97b2fca00372f7170 | succeeded (10s elapsed) | playbook | ansible.pl | Fri, 03 Jan     |
|                          |                         |          | aybook     | 2020 15:54:48   |
|                          |                         |          |            | UTC             |
| 5e0f63d37b2fca00372f7173 | succeeded (0s elapsed)  | post_msg | slack.post | Fri, 03 Jan     |
|                          |                         |          | _message   | 2020 15:54:59   |
|                          |                         |          |            | UTC             |
| 5e0f63d47b2fca00372f7176 | succeeded (0s elapsed)  | last     | core.noop  | Fri, 03 Jan     |
|                          |                         |          |            | 2020 15:55:00   |
|                          |                         |          |            | UTC             |
+--------------------------+-------------------------+----------+------------+-----------------+
    • ansible.playbookの結果をst2 execution get $IDで確認

stderrにpython2.7のサポート終了に伴うバージョン引き上げの注意メッセージが出力されていることが確認できる。

标准错误输出:”支持您的Python版本已过时。密码学的下一个版本将会移除对此版本的支持。请尽快升级到支持hmac.compare_digest的版本(2.7.7+)。”

root@c5f23c2ec76d:~# st2 execution get 5e0f63c97b2fca00372f7170
id: 5e0f63c97b2fca00372f7170
status: succeeded (10s elapsed)
parameters: 
  cwd: /opt/stackstorm/packs/mydemo_pack
  inventory_file: /opt/stackstorm/packs/ansible/inventory/hosts
  playbook: /opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml
result: 
  failed: false
  return_code: 0
  stderr: "/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/cryptography/hazmat/primitives/constant_time.py:26: CryptographyDeprecationWarning: Support for your Python version is deprecated. The next version of cryptography will remove support. Please upgrade to a release (2.7.7+) that supports hmac.compare_digest as soon as possible.
  utils.PersistentlyDeprecated2018,
[WARNING]: arguments wait_for, match, rpcs are not supported when using
transport=cli"
  stdout: "
PLAY [junos] *******************************************************************

TASK [show version] ************************************************************
ok: [<ip>]

TASK [debug] *******************************************************************
ok: [<ip>] => {
    "msg": [
        [
            "fpc0:", 
            "--------------------------------------------------------------------------", 
            "Hostname: Template-vQFX-Light", 
            "Model: vqfx-10000", 
            "Junos: 15.1X53-D63.9", 
            (略)
            "", 
            "{master:0}"
        ], 
        [
            "show interfaces terse ", 
            "Interface               Admin Link Proto    Local                 Remote", 
            "gr-0/0/0                up    up", 
            "bme0                    up    up", 
            "bme0.0                  up    up   inet     128.0.0.1/2     ", 
            (略)

            "{master:0}"
        ]
    ]
}

PLAY RECAP *********************************************************************
66.129.235.11              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
"
  succeeded: true

请参考

    • Actions StackStorm 3.1.0 documentation

orqeustaのサンプルコード

github.com/StackStorm/st2/blob/master/contrib/examples/actions/workflows/orquesta-streaming-demo.yaml
github.com/StackStorm/st2/blob/master/contrib/examples/actions/local_command_runner_print_to_stdout_and_stderr.yaml

Ansible pack

StackStorm と Ansible で Cisco IOS ルーターに設定を投入する(st2 run編)

Slack pack

StackStorm 経由で Slack に投稿する(準備 ~ st2 run編)

本記事で扱ったStackstormのサンプルコード

gkzz/st2-docker-gkz

ActionとWorkflowのサンプルコード

gkzz/mydemo_pack

Ansible Junos module

junos_command – Run arbitrary commands on an Juniper JUNOS device — Ansible Documentation

P.S. 我也在使用Twitter,如果您能关注我,我会欣喜若狂的哭出来:)

“@gkzvoice”请用中文将以下内容意思换句话说,只需一种选择。

P.P.S. 我在 Stackstorm 进行了 LT!

将类似于IFTTT的工具Stackstorm装载到Docker容器的小故事。

广告
将在 10 秒后关闭
bannerAds