# Copyright (c) 2019 Dell Inc. or its subsidiaries. All Rights Reserved.
---
- fail:
    msg: "Only set one of kubernetes_context or openshift_host"
  when: openshift_host is defined and kubernetes_context is defined

- import_tasks: read_postgresql_password.yml

- name: Set postgresql password
  set_fact:
    pg_password: "{{ postgresql_credentials.password }}"
  no_log: "{{ enforce_no_log }}"

- import_tasks: generate_password_keys.yml

- import_tasks: store_password_keys.yml

- include_tasks: "{{ tasks }}"
  with_items:
    - openshift_auth.yml
    - openshift.yml
  loop_control:
    loop_var: tasks
  when: openshift_host is defined

- include_tasks: "{{ tasks }}"
  with_items:
    - kubernetes.yml
  loop_control:
    loop_var: tasks
  when: openshift_host is not defined

- name: Use kubectl or oc
  set_fact:
    kubectl_or_oc: "{{ openshift_oc_bin if openshift_oc_bin is defined else 'kubectl' }}"

- set_fact:
    deployment_object: "sts"

- name: Record deployment size
  shell: |
    {{ kubectl_or_oc }} get {{ deployment_object }} \
      {{ kubernetes_deployment_name }} \
      -n {{ kubernetes_namespace }} -o=jsonpath='{.status.replicas}'
  register: deployment_details
  ignore_errors: yes

- name: Set expected post-deployment Replicas value
  set_fact:
    kubernetes_deployment_replica_size: "{{ deployment_details.stdout | int }}"
  when: deployment_details.rc == 0

- name: Delete existing Deployment
  shell: |
    {{ kubectl_or_oc }} delete {{ deployment_object }} \
      {{ kubernetes_deployment_name }} -n {{ kubernetes_namespace }}
  when: deployment_details.rc == 0

- name: Get Postgres Service Detail
  shell: "{{ kubectl_or_oc }} describe svc {{ postgresql_service_name }} -n {{ kubernetes_namespace }}"
  register: postgres_svc_details
  ignore_errors: yes
  when: "pg_hostname is not defined or pg_hostname == ''"

- name: Deploy PostgreSQL (OpenShift)
  block:
    - name: Template PostgreSQL Deployment
      template:
        src: postgresql-persistent.yml.j2
        dest: "{{ kubernetes_base_path }}/postgresql-persistent.yml"
        mode: '0600'

    - name: Deploy and Activate Postgres
      shell: |
        {{ openshift_oc_bin }} new-app --file={{ kubernetes_base_path }}/postgresql-persistent.yml \
          -e MEMORY_LIMIT={{ pg_memory_limit|default('512') }}Mi \
          -e DATABASE_SERVICE_NAME=postgresql  \
          -e POSTGRESQL_MAX_CONNECTIONS={{ pg_max_connections|default(1024) }} \
          -e POSTGRESQL_USER={{ pg_username }} \
          -e POSTGRESQL_PASSWORD={{ pg_password }} \
          -e POSTGRESQL_ADMIN_PASSWORD={{ pg_password }} \
          -e POSTGRESQL_DATABASE={{ pg_database }} \
          -e POSTGRESQL_VERSION=9.5 \
          -n {{ kubernetes_namespace }}
      register: openshift_pg_activate
      no_log: "{{ enforce_no_log }}"
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - postgres_svc_details is defined and postgres_svc_details.rc != 0
    - openshift_host is defined

- name: Deploy and Activate Postgres (Kubernetes)
  shell: |
    helm install --name {{ kubernetes_deployment_name }} --namespace {{ kubernetes_namespace }} \
      --set postgresUser={{ pg_username }} \
      --set postgresPassword={{ pg_password }} \
      --set postgresDatabase={{ pg_database }} \
      --set persistence.size={{ pg_volume_capacity|default('5')}}Gi \
      stable/postgresql
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - postgres_svc_details is defined and postgres_svc_details.rc != 0
    - kubernetes_context is defined
  register: kubernetes_pg_activate
  no_log: "{{ enforce_no_log }}"

- name: Set postgresql hostname to helm package service
  set_fact:
    pg_hostname: "{{ kubernetes_deployment_name }}-postgresql"
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - kubernetes_context is defined

- name: Wait for Postgres to activate
  pause:
    seconds: 60
  when: openshift_pg_activate.changed or kubernetes_pg_activate.changed

- name: Set image names if using custom registry
  block:
    - name: Set task image name
      set_fact:
        kubernetes_task_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ task_image }}"
      when: kubernetes_task_image is not defined

    - name: Set web image name
      set_fact:
        kubernetes_web_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ web_image }}"
      when: kubernetes_web_image is not defined
  when: docker_registry is defined


- block:
  - name: AWX Credentials | Define Random generated password in CAM environment
    ngci_pass_gen:
      chars: ["digits", "lowercasealpha", "uppercasealpha"]
    register: random_password
    no_log: "{{ enforce_no_log }}"

  - name: Set users fact
    set_fact:
      awx_admin_password: "{{ random_password.generated_password }}"
    no_log: "{{ enforce_no_log }}"
  when: env_setup_type == 'cam'

- name: Define AWX admin credentials in FAM environment
  set_fact:
    awx_admin_password: password
  when: env_setup_type == 'fam'

- name: Render deployment templates
  set_fact:
    "{{ item }}": "{{ lookup('template', item + '.yml.j2') }}"
  with_items:
    - 'configmap'
    - 'deployment'
    - 'secret'
    - 'pvc'
  no_log: "{{ enforce_no_log }}"

- name: Apply Deployment
  shell: |
    echo {{ item | quote }} | {{ kubectl_or_oc }} apply -f -
  with_items:
    - "{{ configmap }}"
    - "{{ deployment }}"
    - "{{ secret }}"
    - "{{ pvc }}"
  no_log: "{{ enforce_no_log }}"

- name: Delete any existing management pod
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      delete pod {{ kubernetes_deployment_name }}-management --grace-period=0 --ignore-not-found

- name: Template management pod
  set_fact:
    management_pod: "{{ lookup('template', 'management-pod.yml.j2') }}"

- name: Create management pod
  shell: |
    echo {{ management_pod | quote }} | {{ kubectl_or_oc }} apply -f -

- name: Wait for management pod to start
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      get pod {{ kubernetes_deployment_name }}-management -o jsonpath="{.status.phase}"
  register: result
  until: result.stdout == "Running"
  retries: 60
  delay: 10

- name: Wait for AWX/Postgres to settle (temporary workaround until ESNG-16476 addressed)
  pause:
    seconds: 500


- name: Migrate database
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec {{ kubernetes_deployment_name }}-management -- \
      bash -c "awx-manage migrate --noinput"

- name: Check for Tower Super users
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec {{ kubernetes_deployment_name }}-management -- \
      bash -c "echo 'from django.contrib.auth.models import User; nsu = User.objects.filter(is_superuser=True).count(); exit(0 if nsu > 0 else 1)' | awx-manage shell"
  register: super_check
  ignore_errors: yes
  changed_when: super_check.rc > 0

- name: create django super user if it does not exist
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec {{ kubernetes_deployment_name }}-management -- \
      bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('{{ admin_user }}', '{{ admin_email }}', '{{ awx_admin_password }}')\" | awx-manage shell"
  no_log: "{{ enforce_no_log }}"
  when: super_check.rc > 0

- name: update django super user password
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec {{ kubernetes_deployment_name }}-management -- \
      bash -c "awx-manage update_password --username='{{ admin_user }}' --password='{{ awx_admin_password }}'"
  no_log: "{{ enforce_no_log }}"
  register: result
  changed_when: "'Password updated' in result.stdout"

- import_tasks: save_admin_user_vault.yml

  #- name: Create the default organization if it is needed.
  #shell: |
  #  {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec {{ kubernetes_deployment_name }}-management -- \
  #    bash -c "awx-manage create_preload_data"
  #register: cdo
  #changed_when: "'added' in cdo.stdout"

- name: Delete management pod
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      delete pod {{ kubernetes_deployment_name }}-management --grace-period=0 --ignore-not-found

- name: Scale up deployment
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      scale {{ deployment_object }} {{ kubernetes_deployment_name }} --replicas=0
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      scale {{ deployment_object }} {{ kubernetes_deployment_name }} --replicas={{ kubernetes_deployment_replica_size }}

- name: Create cluster role and binding entries for awx ServiceAccount
  k8s:
    state: present
    definition: "{{ lookup('template', item) }}"
    namespace: "{{ awx_namespace }}"
  loop:
    - "awx_cluster_role.yml.j2"
    - "awx_cluster_role_binding.yml.j2"

- name: Deploy FAM AWX Service
  k8s:
    state: present
    definition: "{{ lookup('template', 'fam-service.yml.j2') }}"
  when: env_setup_type == 'fam'