shantanoo-desai / komponist

A Composer for your favorite IoT/ IIoT container stacks with Ansible + Jinja2 + Docker Compose v2
GNU Affero General Public License v3.0
25 stars 2 forks source link

[node-red] Provide plugin to export the flows along with credentials #109

Closed shantanoo-desai closed 11 months ago

shantanoo-desai commented 1 year ago

Description

Based credentials_secret settings in Node-RED, it possible to work with flows and configurations with credentials and export the flow using the /flows API. The credentials however for some or majority of nodes won't be exported by design. Assuming the credentials_secret is set stays the same for multiple devices, it is possible to extract the flows_cred.json file from /data directory either in the container or maybe potentially mounting it on the host.

An adapted flow file would look like:

{
  "rev": "",
  "credentials": {
    "$": "",
  },
  "flows": [
  ]
}
shantanoo-desai commented 1 year ago

Playbook Implementation

---
- hosts: localhost
  gather_facts: false
  vars_files:
    - "{{ playbook_dir }}/../vars/creds.yml"
  module_defaults:
    ansible.builtin.uri:
      method: POST
      headers:
        Content-Type: application/json
  tasks:

    - name: Get Node-RED user with all Privileges
      set_fact:
        nodered_creds: "{{ item }}"
      when: "item.permissions is defined and item['permissions'] == '*'"
      loop: "{{ credentials.nodered.users }}"

    - name: Obtain Authentication Token
      ansible.builtin.uri:
        url: http://localhost/nodered/auth/token
        body:
          client_id: node-red-admin
          grant_type: password
          scope: "{{ nodered_creds.permissions }}"
          username: "{{ nodered_creds.username }}"
          password: "{{ nodered_creds.password }}"
        body_format: json
        status_code: 200
      register: auth_token
      when: nodered_creds is defined

    - name: lookup flows from Node-RED instance
      set_fact:
        main_flow: "{{ lookup('ansible.builtin.url', 'http://localhost/nodered/flows', headers=headers) }}"
      vars:
        headers:
          Content-Type: application/json
          Authorization: "{{ auth_token.json.token_type }} {{ auth_token.json.access_token }}"
          Node-RED-API-Version: v2

    - community.docker.docker_container_exec:
        container: komponist_nodered
        command: /bin/bash -c "cat /data/flows_cred.json"
      register: flows_cred

    - set_fact:
        final_flow: "{{ main_flow | combine({'credentials': flows_cred.stdout | from_json }) | ansible.utils.remove_keys(['rev']) | trim }}"

    # - debug: var="{{ final_flow | to_nice_json }}"
    - copy:
        dest: /tmp/flows.json
        content: "{{ final_flow | to_nice_json }}"

the rev key needs to be deleted in order to force push the flows at the moment.