---
# TODO: add ability to configure certificates given either a local file to
#       point to or certificate contents, set in default cert locations.

# Authentication Variable Validation
# TODO: validate the different identity provider kinds as well
- fail:
    msg: >
      Invalid OAuth grant method: {{ openshift_master_oauth_grant_method }}
  when:
  - openshift_master_oauth_grant_method not in openshift_master_valid_grant_methods

- import_tasks: pre_pull.yml

- name: Open up firewall ports
  import_tasks: firewall.yml

- name: Prepare static pod scripts
  import_tasks: static_shim.yml

- name: Create r_openshift_master_data_dir
  file:
    path: "{{ r_openshift_master_data_dir }}"
    state: directory
    mode: 0755
    owner: root
    group: root

- import_tasks: registry_auth.yml

- name: Create config parent directory if it does not exist
  file:
    path: "/etc/origin/master"
    state: directory

- name: Copy recycler pod to config directory
  template:
    src: "recycler_pod.yaml.j2"
    dest: "/etc/origin/master/recycler_pod.yaml"

- name: Create flexvolume directory when on atomic hosts
  file:
    state: directory
    path: "/etc/origin/kubelet-plugins/volume/exec"
    mode: '0750'
  when: openshift_is_atomic | bool

- name: Flex volume directory on non-atomic host
  file:
    state: directory
    path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/"
    mode: '0750'
  when: not openshift_is_atomic | bool

- name: Create openshift audit log directory
  file:
    state: directory
    path: "/var/log/origin"
    mode: 0700
  when:
  - openshift.master.audit_config is defined
  - openshift.master.audit_config.auditFilePath is defined
  - '"/var/log/origin" in openshift.master.audit_config.auditFilePath'

- name: Copy openshift audit policy file
  copy:
    src: "{{ openshift.master.audit_policyfile }}"
    dest: "{{ openshift.master.audit_config.policyFile }}"
    mode: 0644
  when:
  - openshift.master.audit_config is defined
  - openshift.master.audit_policyfile is defined
  - openshift.master.audit_config.policyFile is defined
  - '"/etc/origin/master" in openshift.master.audit_config.policyFile'

- name: Create the policy file if it does not already exist
  command: >
    {{ openshift_client_binary }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig
      adm create-bootstrap-policy-file
      --filename={{ openshift_master_policy }}
  args:
    creates: "{{ openshift_master_policy }}"

- name: Create the scheduler config
  copy:
    content: "{{ scheduler_config | to_nice_json }}"
    dest: "{{ openshift_master_scheduler_conf }}"
    backup: true

- name: Generate encryption config
  copy:
    content: "{{ openshift_encryption_config }}"
    dest: "{{ openshift_encryption_config_file }}"
  when: openshift_encryption_config is defined

- import_tasks: htpass_provider.yml

- name: Create AWS Custom CA if specified
  copy:
    dest: "/etc/origin/master/aws_ca_bundle.crt"
    src: "{{ openshift_cloudprovider_aws_ca_bundle }}"
  when: openshift_cloudprovider_aws_ca_bundle is defined

- name: Create the ldap ca file if needed
  copy:
    dest: "/etc/origin/master/{{ item.name }}_ldap_ca.crt"
    content: "{{ openshift.master.ldap_ca }}"
    mode: 0600
    backup: yes
  when:
  - openshift.master.ldap_ca is defined
  - item.kind == 'LDAPPasswordIdentityProvider'
  with_items: "{{ openshift_master_identity_providers }}"

- name: Create the openid ca file if needed
  copy:
    dest: "/etc/origin/master/{{ item.name }}_openid_ca.crt"
    content: "{{ openshift.master.openid_ca }}"
    mode: 0600
    backup: yes
  when:
  - openshift.master.openid_ca is defined
  - item.kind == 'OpenIDIdentityProvider'
  with_items: "{{ openshift_master_identity_providers }}"

- name: Create the GitHub (Enterprise) ca file if needed
  copy:
    dest: "/etc/origin/master/{{ item.name }}_github_ca.crt"
    content: "{{ openshift.master.github_ca }}"
    mode: 0600
    backup: yes
  when:
  - openshift.master.github_ca is defined
  - item.kind == 'GitHubIdentityProvider'
  with_items: "{{ openshift_master_identity_providers }}"

- name: Create the request header ca file if needed
  copy:
    dest: "/etc/origin/master/{{ item.name }}_request_header_ca.crt"
    content: "{{ openshift_master_request_header_ca }}"
    mode: 0600
    backup: yes
  when:
  - openshift_master_request_header_ca != l_osm_request_header_none
  - item.kind == 'RequestHeaderIdentityProvider'
  with_items: "{{ openshift_master_identity_providers }}"

- name: Set fact of all etcd host IPs
  openshift_facts:
    role: common
    system_facts: "{{ vars_openshift_facts_system_facts }}"
    local_facts:
      no_proxy_etcd_host_ips: "{{ openshift_no_proxy_etcd_host_ips }}"

- name: Create session secrets file
  template:
    dest: "{{ openshift_master_session_secrets_file }}"
    src: sessionSecretsFile.yaml.v1.j2
    owner: root
    group: root
    mode: 0600

- set_fact:
    # translate_idps is a custom filter in role lib_utils
    translated_identity_providers: "{{ openshift_master_identity_providers | translate_idps('v1') }}"

# TODO: add the validate parameter when there is a validation command to run
- name: Create master config
  template:
    dest: "{{ openshift_master_config_file }}"
    src: master.yaml.v1.j2
    backup: true
    owner: root
    group: root
    mode: 0600

- import_tasks: set_loopback_context.yml

- name: Create the master service env file
  template:
    src: "master.env.j2"
    dest: /etc/origin/master/master.env
    backup: true

- import_tasks: static.yml

- name: Establish the default bootstrap kubeconfig for masters
  copy:
    remote_src: true
    src: "/etc/origin/master/admin.kubeconfig"
    dest: "{{ item }}"
    mode: 0600
  with_items:
  # bootstrap as an admin
  - /etc/origin/node/bootstrap.kubeconfig
  # copy to this location to bypass initial bootstrap request
  - /etc/origin/node/node.kubeconfig

- import_tasks: pre_pull_poll.yml

- name: Start and enable self-hosting node
  systemd:
    name: "{{ openshift_service_type }}-node"
    state: restarted
    enabled: yes
  register: node_start
  ignore_errors: yes

- when: node_start is failed
  block:
  - name: Get node logs
    command: journalctl --no-pager -n 300 -u {{ openshift_service_type }}-node
    register: logs_node
    ignore_errors: true
  - debug:
      msg: "{{ logs_node.stdout_lines }}"
  - fail:
      msg: Node start failed.

- name: Wait for all control plane pods to come up and become ready
  oc_obj:
    state: list
    kind: pod
    name: "master-{{ item }}-{{ l_kubelet_node_name | lower }}"
    namespace: kube-system
  register: control_plane_pods
  until:
  - control_plane_pods.module_results is defined
  - control_plane_pods.module_results.results is defined
  - control_plane_pods.module_results.results | length > 0
  - control_plane_pods.module_results.results[0].status is defined
  - control_plane_pods.module_results.results[0].status.conditions is defined
  - control_plane_pods.module_results.results[0].status.conditions | selectattr('type', 'match', '^Ready$') | map(attribute='status') | join | bool == True
  retries: 72  # 6 minutes
  delay: 5
  with_items:
  - "{{ 'etcd' if inventory_hostname in groups['oo_etcd_to_config'] else '' }}"
  - api
  - controllers
  when:
  - item != ''
  ignore_errors: true

- when: control_plane_pods is failed
  block:
  - name: Check status in the kube-system namespace
    command: >
      {{ openshift_client_binary }} status --config={{ openshift.common.config_base }}/master/admin.kubeconfig -n kube-system
    register: control_plane_status
    ignore_errors: true
  - name: Output status in the kube-system namespace
    debug:
      msg: "{{ control_plane_status.stdout_lines }}"

  - name: Get pods in the kube-system namespace
    command: >
      {{ openshift_client_binary }} get pods --config={{ openshift.common.config_base }}/master/admin.kubeconfig -n kube-system -o wide
    register: control_plane_pods_list
    ignore_errors: true
  - name: Output pods in the kube-system namespace
    debug:
      msg: "{{ control_plane_pods_list.stdout_lines }}"

  - name: Get events in the kube-system namespace
    command: >
      {{ openshift_client_binary }} get events --config={{ openshift.common.config_base }}/master/admin.kubeconfig -n kube-system
    register: control_plane_events
    ignore_errors: true
  - name: Output events in the kube-system namespace
    debug:
      msg: "{{ control_plane_events.stdout_lines }}"

  - name: Get node logs
    command: journalctl --no-pager -n 300 -u {{ openshift_service_type }}-node
    register: logs_node
    ignore_errors: true
  - name: Output node logs
    debug:
      msg: "{{ logs_node.stdout_lines }}"

  - name: Get API logs
    command: >
      /usr/local/bin/master-logs api api
    register: control_plane_logs_api
    ignore_errors: true
  - name: Output API logs
    debug:
      msg: "{{ control_plane_logs_api.stderr_lines }}"

  - name: Get controllers logs
    command: >
      /usr/local/bin/master-logs controllers controllers
    register: control_plane_logs_controllers
    ignore_errors: true
  - name: Output controllers logs
    debug:
      msg: "{{ control_plane_logs_controllers.stderr_lines }}"

  - name: Get etcd logs
    command: >
      /usr/local/bin/master-logs etcd etcd
    register: control_plane_logs_etcd
    when: inventory_hostname in groups['oo_etcd_to_config']
    ignore_errors: true
  - name: Output etcd logs
    debug:
      msg: "{{ control_plane_logs_etcd.stderr_lines }}"
    when: inventory_hostname in groups['oo_etcd_to_config']

  - name: Report control plane errors
    fail:
      msg: Control plane pods didn't come up and become ready

- import_tasks: check_master_api_is_ready.yml

- name: Remove oc cache to refresh a list of APIs
  file:
    path: "~/.kube/cache"
    state: absent
