skydive-project / skydive

An open source real-time network topology and protocols analyzer
https://skydive.network
Apache License 2.0
2.66k stars 400 forks source link

ansible: support multi-threading #1484

Closed pierrecregut closed 5 years ago

pierrecregut commented 5 years ago

When skydive_node.py or skydive_edge.py are used in an ansible playbook, it is necessary to set --fork=1

safchain commented 5 years ago

can you give a example of a such playbook ?

safchain commented 5 years ago

what kind of error do you get without fork=1 ?

pierrecregut commented 5 years ago

It hangs. Here is the playbook. To use it, you can use any of the vagrant configurations from https://github.com/Juniper/vqfx10k-vagrant :

---

- name: Skydive Ansible
  hosts: vqfx10k
  gather_facts: no
  connection: local
  tasks:

    - name: Collect device Facts and Configuration
      junos_facts:
        config_format: json
      register: result

    - name: Configuration in JSON (converted from XML)
      debug: var=result

    - name: Create TOR
      skydive_node:
        name: "{{ inventory_hostname }}"
        type: "fabric"
        metadata:
          Model:  "{{ result.ansible_facts.ansible_net_model }}"
      register: tor_result

    - name: Create ports
      skydive_node:
        name: "{{item.key}}"
        seed: "{{item.value.type}}-{{inventory_hostname}}-{{item.key}}"
        type: 'fabric'
        metadata:
          State: "{{item.value['oper-status'] | upper}}"
          MacAddress: "{{item.value.macaddress}}"
      register: port_result
      with_dict: "{{ result.ansible_facts.ansible_net_interfaces }}"

    - name: Link TOR and port
      skydive_edge:
        node1: "{{ tor_result.UUID }}"
        node2: "{{ item.UUID }}"
        relation_type: ownership
        metadata:
          Type: unknown
      loop: "{{port_result.results}}"
pierrecregut commented 5 years ago

This is basically your code from the blog post slightly adapted but used in a configuration with multiple hosts (a good environment is full-ipfabric-2S-3L that creates five switch).

pierrecregut commented 5 years ago

There is an error on the server that I missed: 2018-11-27T11:18:29.788+0100 ERROR websocket/server.go:84 (*Server).serveMessages master: host_id(analyzer) conflict, same host_id used by 192.168.122.1:45162

In fact there are several errors (3, I expected 4 because of the default value of fork).

I have tried to set host to {{inventory_hostname}} in the calls to skydive_node or skydive_edge. But this is not enough.

safchain commented 5 years ago

Ok I do understand this error now. thx

So the host_id passed in the WSClient is always the same :( https://github.com/skydive-project/skydive/blob/master/contrib/ansible/library/skydive_node.py#L168 https://github.com/skydive-project/skydive/blob/master/contrib/python/api/skydive/websocket/client.py#L146

It should be something unique per host/connection. I would use "ansible-" + hostname.

Tell me if you want to fix this or I will try to fix it

pierrecregut commented 5 years ago

Yes, reached the same conclusion. I used module.params["host"] instead of "analyzer"

pierrecregut commented 5 years ago

Probably better with "ansible-" as a prefix.

pierrecregut commented 5 years ago

To help new users, I suggest adding the following as notes in the ansible documentation:

The default value of seed may be unsufficient to disambiguate nodes. Because the default strategy of ansible is to spawn one thread per host, you should set host to the name of the target of the task (eg inventory_hostname).

Is it the right place ? is it readable ?