使用ntc-ansible来操作Yamaha的网络设备

一开始

我们在之前的文章中使用Netmiko进行了对Yamaha设备的登录、日志提取和配置更改等操作。
使用Netmiko来操作Yamaha的网络设备。

ntc-ansible是基于Netmiko的第三方Ansible模块。您可以在GitHub上找到它:networktocode/ntc-ansible。如果您需要设置和基本操作方法,请参考以下文章:Ansible的ntc-ansible模块总结(①概述、设置部分),Ansible的ntc-ansible模块总结(②执行确认命令模块部分),Ansible的ntc-ansible模块总结(③执行配置更改模块部分)。

这次我们使用ntc-ansible的以下模块来确认是否可以操作Yamaha设备。
确认的版本是:ntc-ansible=0.1.0、Ansible=2.8.4、Netmiko=2.4.2。

No.モジュール名内容1ntc_show_commandCLIベースのNW機器から構造化されたデータを取得。(showコマンド実行など)2ntc_config_commandCLIベースのNW機器へコマンドを送信。(設定変更など)

请注意!ntc-ansible不支持类似network_cli的连接插件,它使用local。同时,并不能保证幂等性。

修改 ntc-ansible 的现有代码

因为原样的话可能无法运行,且结果不清楚,所以我对各个模块的Python文件进行了部分修改。

# (省略)
def main():
# (省略)
#    cisco_ios以外のTelnetログインを受け付けない実装になっているので、コメントアウトで無効化。
#    if connection in ['netmiko_telnet', 'telnet'] and platform != 'cisco_ios':
#        module.fail_json(msg='only cisco_ios supports '
#                             'telnet/netmiko_telnet connection')

    if platform == 'cisco_ios' and connection in ['netmiko_telnet', 'telnet']:
        device_type = 'cisco_ios_telnet'

    if module.params['port']:
        port = int(module.params['port'])
    else:
#        if device_type == 'cisco_ios_telnet':   # device_typeの代わりにconnectionで使用ポートを判定。
        if connection == 'telnet':   # modify
            port = 23
        else:

            port = 22
# (省略)
    results = {}
    results['response'] = []
    results['response_list'] = []

    if use_templates:
        if rawtxt:
            results['response'] = parse_raw_output(rawtxt, module)
        elif trigger_device_list:
            results['response_list'] = parse_raw_output(commando.results, module)
    elif rawtxt:
        results['response'] = [rawtxt]
        results['response_list'] = rawtxt.split('\n')   # 出力結果をリスト形式で表示できるように修正。
    elif trigger_device_list:
        results['response'] = [commando.results]

    module.exit_json(**results)
# (省略)
# (省略)
def main():
# (省略)
#    cisco_ios以外のTelnetログインを受け付けない実装になっているので、コメントアウトで無効化。
#    if connection == 'telnet' and platform != 'cisco_ios':
#        module.fail_json(msg='only cisco_ios supports '
#                             'telnet connection')
# (省略)

库存

平台基本上与Netmiko的device_type相关联。因此,如果登录方式是SSH,则需指定yamaha;如果是Telnet,则指定yamaha_telnet。请注意,不支持在Ansible的官方模块中使用network_os、ansible_host、ansible_become_method等参数。

[yamaha]
192.168.100.88 hostname=yamaha1 lan1_address=10.1.1.24/24

[yamaha:vars]
# platform=yamaha   # SSHログインの場合
platform=yamaha_telnet   # Telnetログインの場合
ansible_user=yamaha
ansible_password=yamaha
ansible_become_pass=yamaha
ansible_python_interpreter=/home/centos/venv_an2.8.4/bin/python3.6

玩法

本次操作使用Telnet来更改IP地址、获取show命令、保存日志文件以及获取解析后的show命令。如果使用SSH,不需要指定connection选项。connection插件为local,需要指定每个任务的登录信息。

---

- hosts: yamaha
  gather_facts: no
  connection: local

  tasks:
    - name: change configuration on remote devices
      ntc_config_command:
        connection: telnet   # 今回はログイン方式としてtelnetを指定。デフォルト値はssh
        commands:
          - ip lan1 address "{{ lan1_address }}"
          - save
        provider: "{{ cli }}"
        platform: "{{ platform }}"

    - name: run show command and store config file
      ntc_show_command:
        connection: telnet
        command: show status lan1
        use_templates: false   # パース用のTextFSM templateの使用有無を指定。デフォルト値はtrue
        provider: "{{ cli }}"
        local_file: "./{{ hostname }}_log.txt"   # 保存先のディレクトリ・ファイル名を指定
      register: result

    - name: display show command
      debug:
        var: result.response_list

    - name: run show command and get parsed data
      ntc_show_command:
        connection: telnet
        command: show environment
        template_dir: "/home/centos/ntc-templates/templates"   # Specifies where to search templates
        provider: "{{ cli }}"
      register: result2

    - name: display parsed show command
      debug:
        var: result2.response

  vars:
    cli:
      host: "{{ inventory_hostname }}"
      username: "{{ ansible_user }}"
      password: "{{ ansible_password }}"
      secret: "{{ ansible_become_pass }}"
      platform: "{{ platform }}"   # 対象機器のOSに合わせて指定する必要あり

执行结果

查看[display show command]时,可以正常确认到IP地址10.1.1.24/24已经正确配置。使用[display parsed show command]可以成功进行show environment的解析。虽然省略了具体内容,但文件保存也是正常的。只不过,在这两个操作中都出现了警告信息。

$ ansible-playbook -i inventory playbook_yamaha1.yml
 [WARNING]: Skipping plugin (/home/centos/venv_an2.8.4/ntc-ansible/filter_plugins/split.py) as it seems to be invalid: invalid
syntax (split.py, line 7)


PLAY [yamaha] ***********************************************************************************************************************

TASK [change configuration on remote devices] ***************************************************************************************
changed: [192.168.100.88]

TASK [run show command and store config file] ***************************************************************************************
 [WARNING]: The value 1 (type int) in a string field was converted to '1' (type string). If this does not look like what you expect,
quote the entire value to ensure it does not change.

ok: [192.168.100.88]

TASK [display show command] *********************************************************************************************************
ok: [192.168.100.88] => {
    "result.response_list": [
        "LAN1",
        "Description:                    ",
        "IP Address:                     10.1.1.24/24 ",
        "Ethernet Address:               00:a0:de:00:00:00",
        "Operation mode setting:         Type (Link status)",
        "               PORT1:           Auto Negotiation (Link Down)",
        "               PORT2:           Auto Negotiation (Link Down)",
        "               PORT3:           Auto Negotiation (Link Down)",
        "               PORT4:           Auto Negotiation (Link Down)",
        "Maximum Transmission Unit(MTU): 1500 octets",
        "Promiscuous mode:               OFF",
        "Transmitted:                    0 packet (0 octet)",
        "  IPv4(all/fastpath):           0 packet / 0 packet",
        "  IPv6(all/fastpath):           0 packet / 0 packet",
        "Received:                       0 packet (0 octet)",
        "  IPv4:                         0 packet",
        "  IPv6:                         0 packet"
    ]
}

TASK [run show command and get parsed data] *****************************************************************************************
ok: [192.168.100.88]

TASK [display parsed show command] **************************************************************************************************
ok: [192.168.100.88] => {
    "result2.response": [
        {
            "buffer_huge": "0",
            "buffer_large": "5",
            "buffer_middle": "0",
            "buffer_small": "0",
            "cpu_1_min": "1",
            "cpu_5_min": "0",
            "cpu_5_sec": "0",
            "date": "2019/10/05",
            "forget": "ON",
            "hardware": "RTX810",
            "mac": [
                "00:a0:de:00:00:00",
                "00:a0:de:aa:aa:aa"
            ],
            "mem": "7",
            "sec_class": "1",
            "serial": "S3KXXXXXX",
            "telnet": "OFF",
            "temperature": "",
            "time": "23:43:53",
            "timezone": "+09:00",
            "uptime": "4days 01:43:36",
            "version": "11.01.33"
        }
    ]
}

PLAY RECAP **************************************************************************************************************************
192.168.100.88             : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

最后

总体上来说,我们确认了即使是在雅马哈设备上也可以运行。与官方模块相比,它存在一些缺点,如幂等性和登录信息的指定等。但是,它在能够将官方未支持的供应商纳入到Ansible中以及在不得不使用Telnet的情况下是很有用的。

广告
将在 10 秒后关闭
bannerAds