---
version: '2.0'
name: tripleo.access.v1
description: TripleO administration access workflows

workflows:

  enable_ssh_admin:
    description: >-
      This workflow creates an admin user on the overcloud nodes,
      which can then be used for connecting for automated
      administrative or deployment tasks, e.g. via Ansible. The
      workflow can be used both for Nova-managed and split-stack
      deployments, assuming the correct input values are passed
      in. The workflow defaults to Nova-managed approach, for which no
      additional parameters need to be supplied. In case of
      split-stack, temporary ssh connection details (user, key, list
      of servers) need to be provided -- these are only used
      temporarily to create the actual ssh admin user for use by
      Mistral.
    tags:
      - tripleo-common-managed
    input:
      - ssh_private_key: null
      - ssh_user: null
      - ssh_servers: []
      - overcloud_admin: tripleo-admin
      - queue_name: tripleo
      - plan_name: overcloud

    tasks:
      get_pubkey:
        action: tripleo.validations.get_pubkey
        on-success: get_blacklisted_ip_addresses
        publish:
          pubkey: <% task().result %>

      get_blacklisted_ip_addresses:
        action: heat.stacks_output_show
        input:
          stack_id: <% $.plan_name %>
          output_key: BlacklistedIpAddresses
        publish:
          blacklisted_ip_addresses: <% task().result.output.output_value %>
        on-success: get_ssh_servers_not_blacklisted
        publish-on-error:
          status: FAILED
          message: <% task().result %>

      get_ssh_servers_not_blacklisted:
        publish:
          ssh_servers_not_blacklisted: <% let(blacklisted=>$.blacklisted_ip_addresses, ssh_servers=>$.ssh_servers) -> $ssh_servers.where(not $ in $blacklisted) %>
        on-success: generate_playbook
        publish-on-error:
          status: FAILED
          message: <% task().result %>

      generate_playbook:
        on-success:
          - create_admin_via_nova: <% $.ssh_private_key = null %>
          - create_admin_via_ssh: <% $.ssh_private_key != null %>
        publish:
          create_admin_tasks:
            - name: create user <% $.overcloud_admin %>
              user:
                name: '<% $.overcloud_admin %>'
            - name: grant admin rights to user <% $.overcloud_admin %>
              copy:
                dest: /etc/sudoers.d/<% $.overcloud_admin %>
                content: |
                  <% $.overcloud_admin %> ALL=(ALL) NOPASSWD:ALL
                mode: 0440
            - name: ensure .ssh dir exists for user <% $.overcloud_admin %>
              file:
                path: /home/<% $.overcloud_admin %>/.ssh
                state: directory
                owner: <% $.overcloud_admin %>
                group: <% $.overcloud_admin %>
                mode: 0700
            - name: ensure authorized_keys file exists for user <% $.overcloud_admin %>
              file:
                path: /home/<% $.overcloud_admin %>/.ssh/authorized_keys
                state: touch
                owner: <% $.overcloud_admin %>
                group: <% $.overcloud_admin %>
                mode: 0700
            - name: authorize TripleO Mistral key for user <% $.overcloud_admin %>
              lineinfile:
                path: /home/<% $.overcloud_admin %>/.ssh/authorized_keys
                line: <% $.pubkey %>
                regexp: "Generated by TripleO"

      # Nova variant
      create_admin_via_nova:
        workflow: tripleo.access.v1.create_admin_via_nova
        input:
          queue_name: <% $.queue_name %>
          ssh_servers: <% $.ssh_servers_not_blacklisted %>
          tasks: <% $.create_admin_tasks %>
          overcloud_admin: <% $.overcloud_admin %>

      # SSH variant
      create_admin_via_ssh:
        workflow: tripleo.access.v1.create_admin_via_ssh
        input:
          ssh_private_key: <% $.ssh_private_key %>
          ssh_user: <% $.ssh_user %>
          ssh_servers: <% $.ssh_servers_not_blacklisted %>
          tasks: <% $.create_admin_tasks %>

  create_admin_via_nova:
    input:
      - tasks
      - queue_name: tripleo
      - ssh_servers: []
      - overcloud_admin: tripleo-admin
      - ansible_extra_env_variables:
            ANSIBLE_HOST_KEY_CHECKING: 'False'
    tags:
      - tripleo-common-managed
    tasks:
      get_servers:
        action: nova.servers_list
        with-items: server in <% $.ssh_servers %>
        input:
          search_opts:
            ip: <% $.server %>
        publish:
          servers: <% task().result._info %>
        on-success: create_admin

      create_admin:
        workflow: tripleo.deployment.v1.deploy_on_server
        on-success: get_privkey
        with-items: server in <% $.servers.flatten() %>
        input:
          server_name: <% $.server.name %>
          server_uuid: <% $.server.id %>
          queue_name: <% $.queue_name %>
          config_name: create_admin
          group: ansible
          config: |
            - hosts: localhost
              connection: local
              tasks: <% json_pp($.tasks) %>

      get_privkey:
        action: tripleo.validations.get_privkey
        on-success: wait_for_occ
        publish:
          privkey: <% task().result %>

      wait_for_occ:
        action: tripleo.ansible-playbook
        input:
          inventory:
            overcloud:
              hosts: <% $.ssh_servers.toDict($, {}) %>
          remote_user: <% $.overcloud_admin %>
          ssh_private_key: <% $.privkey %>
          extra_env_variables: <% $.ansible_extra_env_variables %>
          playbook:
            - hosts: overcloud
              gather_facts: no
              tasks:
                - name: wait for connection
                  wait_for_connection:
                    sleep: 5
                    timeout: 300
          execution_id: <% execution().id %>

  create_admin_via_ssh:
    input:
      - tasks
      - ssh_private_key
      - ssh_user
      - ssh_servers
      - ansible_extra_env_variables:
            ANSIBLE_HOST_KEY_CHECKING: 'False'

    tags:
      - tripleo-common-managed
    tasks:
      write_tmp_playbook:
        action: tripleo.ansible-playbook
        input:
          inventory:
            overcloud:
              hosts: <% $.ssh_servers.toDict($, {}) %>
          remote_user: <% $.ssh_user %>
          ssh_private_key: <% $.ssh_private_key %>
          extra_env_variables: <% $.ansible_extra_env_variables %>
          become: true
          become_user: root
          playbook:
            - hosts: overcloud
              tasks: <% $.tasks %>
          execution_id: <% execution().id %>
