- name: Use Aliyun mirror
  when: ansible_distribution == 'Ubuntu' and ansible_distribution_major_version == '20'
  ansible.builtin.copy:
    src: files/sources.list
    dest: /etc/apt/sources.list
    mode: '0644'

- name: Apt update
  ansible.builtin.apt:
    update_cache: yes

- name: Apt install packages
  ansible.builtin.apt:
    update_cache: yes
    pkg:
      - git
      - python3-pip
      - golang-go
      - golint

- name: Creates ~/.pip dir exists
  ansible.builtin.file:
    path: $HOME/.pip
    state: directory
    mode: '0644'

- name: Use PyPI mirror
  ansible.builtin.copy:
    src: files/pip.conf
    dest: $HOME/.pip/pip.conf
    mode: '0644'

- name: Check that the k3s-install.sh exists
  ansible.builtin.stat:
    path: /tmp/k3s-install.sh
  register: k3s_install_stat

- name: Download k3s-install.sh
  when: not k3s_install_stat.stat.exists
  ansible.builtin.get_url:
    url: https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh
    dest: /tmp/k3s-install.sh
    mode: '0700'

- name: Creates /var/lib/rancher/k3s/server/manifests/ directory
  ansible.builtin.file:
    path: /var/lib/rancher/k3s/server/manifests/
    state: directory
    mode: '0644'

- name: Copy traefik-config.yaml from local to remote
  ansible.builtin.copy:
    src: files/traefik-config.yaml
    dest: /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
    mode: '0644'

- name: Install k3s
  when: not k3s_install_stat.stat.exists
  changed_when: false
  ansible.builtin.command: /tmp/k3s-install.sh --write-kubeconfig-mode 644
  environment:
    INSTALL_K3S_MIRROR: cn
    INSTALL_K3S_SKIP_START: "true"
    INSTALL_K3S_VERSION: 'v1.20.15+k3s1'

- name: Start k3s
  ansible.builtin.systemd:
    name: k3s
    state: started
    enabled: true

- name: Check that the config.toml.tmpl exists
  ansible.builtin.stat:
    path: /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl
  register: containerd_config_stat

- name: Copy containerd config.toml
  when: not containerd_config_stat.stat.exists
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /var/lib/rancher/k3s/agent/etc/containerd/config.toml
    dest: /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl
    mode: '0644'

- name: Edit config.toml.tmpl
  when: not containerd_config_stat.stat.exists
  ansible.builtin.blockinfile:
    path: /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl
    block: |
      [plugins.cri.registry.mirrors]
        [plugins.cri.registry.mirrors."docker.io"]
          endpoint = ["https://mirror.ccs.tencentyun.com"]

- name: Restart k3s
  when: not containerd_config_stat.stat.exists
  ansible.builtin.systemd:
    name: k3s
    state: restarted
    enabled: true

- name: Check that the Helm exists
  ansible.builtin.stat:
    path: /usr/local/bin/helm
  register: helm_stat

- name: Download helm-v3.5.2-linux-amd64.tar.gz
  when: not helm_stat.stat.exists
  ansible.builtin.get_url:
    url: https://repo.huaweicloud.com/helm/v3.5.2/helm-v3.5.2-linux-amd64.tar.gz
    dest: /tmp/helm-v3.5.2-linux-amd64.tar.gz
    mode: '0700'

- name: Unarchive helm-v3.5.2-linux-amd64.tar.gz
  when: not helm_stat.stat.exists
  ansible.builtin.unarchive:
    src: /tmp/helm-v3.5.2-linux-amd64.tar.gz
    dest: /tmp
    remote_src: yes

- name: Copy Helm binary to /usr/local/bin/helm
  when: not helm_stat.stat.exists
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /tmp/linux-amd64/helm
    dest: /usr/local/bin/helm
    mode: '0700'

- name: Create Helm plugin path
  ansible.builtin.file:
    path: $HOME/.local/share/helm/plugins
    state: directory
    mode: '0644'

- name: Check that the local helm diff exists
  delegate_to: localhost
  ansible.builtin.stat:
    path: roles/laravel/files/helm-diff/bin/diff
  register: local_helm_diff_stat

- name: Copy helm diff from local to remote
  when: local_helm_diff_stat.stat.exists
  ansible.builtin.copy:
    src: files/helm-diff
    dest: $HOME/.local/share/helm/plugins
    mode: '0644'

- name: Check that the remote helm diff exists
  ansible.builtin.stat:
    path: $HOME/.local/share/helm/plugins/helm-diff
  register: remote_helm_diff_stat

- name: Git clone helm-diff
  when: not remote_helm_diff_stat.stat.exists
  ansible.builtin.git:
    repo: 'https://gitee.com/baijunyao/helm-diff.git'
    dest: /tmp/helm-diff
    version: v3.4.2
    depth: 3
    force: yes

- name: Build helm diff
  when: not remote_helm_diff_stat.stat.exists
  changed_when: false
  ansible.builtin.shell: |
    export GOPROXY=https://mirrors.aliyun.com/goproxy/
    cd /tmp/helm-diff
    make bootstrap
    make install/helm3

- name: Copy helm-diff bin
  when: not remote_helm_diff_stat.stat.exists
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /tmp/helm-diff/bin
    dest: $HOME/.local/share/helm/plugins/helm-diff
    mode: '0644'

- name: Copy plugin.yaml
  when: not remote_helm_diff_stat.stat.exists
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /tmp/helm-diff/plugin.yaml
    dest: $HOME/.local/share/helm/plugins/helm-diff/plugin.yaml
    mode: '0644'

- name: Change helm diff bin permissions
  ansible.builtin.file:
    path: $HOME/.local/share/helm/plugins/helm-diff/bin/diff
    mode: '0700'

- name: Check that the .kube/config exists
  ansible.builtin.stat:
    path: ~/.kube/config
  register: kube_config_stat

- name: Create kube path
  ansible.builtin.file:
    path: ~/.kube/
    state: directory
    mode: '0644'

- name: Generate kube config
  when: not kube_config_stat.stat.exists
  changed_when: false
  ansible.builtin.shell: kubectl config view --raw > ~/.kube/config

- name: Create laravel-bjyblog path
  ansible.builtin.file:
    path: '{{ item }}'
    state: directory
    mode: '0777'
  loop:
    - /laravel-bjyblog/mysql
    - /laravel-bjyblog/grafana
    - /laravel-bjyblog/prometheus
    - /laravel-bjyblog/elasticsearch
    - /laravel-bjyblog/backup/database
    - /laravel-bjyblog/backup/site

- name: Check that the site exists
  ansible.builtin.stat:
    path: /laravel-bjyblog/site
  register: site_stat

- name: Git clone laravel-bjyblog
  when: inventory_hostname != 'local'
  ansible.builtin.git:
    repo: 'https://gitee.com/baijunyao/laravel-bjyblog.git'
    dest: /laravel-bjyblog/site
    version: develop
    depth: 3
    force: yes

- name: Create Helm custom.yaml
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /laravel-bjyblog/site/deploy/helm/values.yaml
    dest: /laravel-bjyblog/site/deploy/helm/custom.yaml
    mode: '0644'

- name: Edit host of Helm custom.yaml
  ansible.builtin.lineinfile:
    path: /laravel-bjyblog/site/deploy/helm/custom.yaml
    regexp: '^host: '
    line: 'host: {{ app_host }}'

- name: Check that the ssl key exists
  delegate_to: localhost
  ansible.builtin.stat:
    path: roles/laravel/files/ssl/{{ inventory_hostname }}.key
  register: ssl_key_stat

- name: Copy ssl key from local to remote
  when: ssl_key_stat.stat.exists
  ansible.builtin.copy:
    src: files/ssl/{{ inventory_hostname }}.key
    dest: /laravel-bjyblog/site/deploy/helm/files/tls.key
    mode: '0644'

- name: Check that the ssl pem exists
  delegate_to: localhost
  ansible.builtin.stat:
    path: roles/laravel/files/ssl/{{ inventory_hostname }}.pem
  register: ssl_pem_stat

- name: Copy ssl pem from local to remote
  when: ssl_pem_stat.stat.exists
  ansible.builtin.copy:
    src: files/ssl/{{ inventory_hostname }}.pem
    dest: /laravel-bjyblog/site/deploy/helm/files/tls.pem
    mode: '0644'

- name: Edit tls of Helm custom.yaml
  when: ssl_key_stat.stat.exists and ssl_pem_stat.stat.exists
  ansible.builtin.lineinfile:
    path: /laravel-bjyblog/site/deploy/helm/custom.yaml
    regexp: '^tls: '
    line: 'tls: true'

- name: Remove /laravel-bjyblog/prometheus/lock
  ansible.builtin.file:
    path: /laravel-bjyblog/prometheus/lock
    state: absent

- name: Helm install
  kubernetes.core.helm:
    release_name: blog
    release_namespace: blog
    create_namespace: true
    binary_path: /usr/local/bin/helm
    chart_ref: /laravel-bjyblog/site/deploy/helm/
    values_files:
      - /laravel-bjyblog/site/deploy/helm/custom.yaml

- name: Install OpenShift
  ansible.builtin.pip:
    name: openshift

- name: Read /laravel-bjyblog/site/deploy/helm/custom.yaml
  ansible.builtin.command: cat /laravel-bjyblog/site/deploy/helm/custom.yaml
  register: helm_custom_value
  changed_when: false

- name: Set elasticsearch_value variable
  ansible.builtin.set_fact:
    elasticsearch_value: "{{ (helm_custom_value.stdout | from_yaml_all).0.elasticsearch }}"

- name: Get Elasticsearch pod name
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
  kubernetes.core.k8s_info:
    api_version: v1
    kind: Pod
    namespace: blog
    wait: yes
    wait_timeout: 1200
    wait_condition:
      type: Ready
      status: "True"
    label_selectors:
      - app = elasticsearch
  register: elasticsearch_deployment

- name: Elasticsearch setup passwords
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ elasticsearch_deployment.resources.0.metadata.name }}'
    command: /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto -b
  register: elasticsearch_setup_passwords

- name: Set elasticsearch_value variable
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
  ansible.builtin.set_fact:
    elasticsearch_password: "{{ elasticsearch_setup_passwords.stdout | regex_search('(?<=PASSWORD elastic = )\\w+') | trim }}"

- name: Set elasticsearch.password
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
    - elasticsearch_password != 'None'
  ansible.builtin.replace:
    path: /laravel-bjyblog/site/deploy/helm/custom.yaml
    regexp: "^  username: elastic\n  password: ''"
    replace: '  username: elastic\n  password: {{ elasticsearch_password }}'

- name: Change kibana.enabled to true
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
    - elasticsearch_password != 'None'
  ansible.builtin.replace:
    path: /laravel-bjyblog/site/deploy/helm/custom.yaml
    regexp: "^kibana:\n  enabled: false"
    replace: 'kibana:\n  enabled: true'

- name: Change fluentd.enabled to true
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
    - elasticsearch_password != 'None'
  ansible.builtin.replace:
    path: /laravel-bjyblog/site/deploy/helm/custom.yaml
    regexp: "^fluentd:\n  enabled: false"
    replace: 'fluentd:\n  enabled: true'

- name: Helm upgrade
  when:
    - elasticsearch_value.enabled
    - not elasticsearch_value.password
    - elasticsearch_password != 'None'
  kubernetes.core.helm:
    release_name: blog
    release_namespace: blog
    create_namespace: true
    binary_path: /usr/local/bin/helm
    chart_ref: /laravel-bjyblog/site/deploy/helm/
    values_files:
      - /laravel-bjyblog/site/deploy/helm/custom.yaml

- name: Get PHP pod name
  kubernetes.core.k8s_info:
    api_version: v1
    kind: Pod
    namespace: blog
    wait: yes
    wait_timeout: 600
    wait_condition:
      type: Ready
      status: "True"
    label_selectors:
      - app = php
  register: php_deployment

- name: Composer install
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: composer install

- name: Create .env
  ansible.builtin.copy:
    remote_src: yes
    force: no
    src: /laravel-bjyblog/site/.env.k8s
    dest: /laravel-bjyblog/site/.env
    mode: '0644'

- name: Edit .env
  ansible.builtin.lineinfile:
    path: /laravel-bjyblog/site/.env
    regexp: '^APP_URL='
    line: 'APP_URL={{ app_url }}'

- name: Get Laravel APP_KEY
  ansible.builtin.lineinfile:
    path: /laravel-bjyblog/site/.env
    state: absent
    regexp: '^APP_KEY=\w+'
  check_mode: yes
  changed_when: false
  register: app_key_result

- name: Execute key:generate
  when: not app_key_result.found
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan key:generate

- name: Execute php artisan migrate
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan migrate --force

- name: Execute php artisan db:seed
  when: inventory_hostname != 'production'
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan db:seed

- name: Execute php artisan bjyblog:update
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan bjyblog:update

- name: Execute php artisan cache:clear
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan cache:clear

- name: Execute php artisan storage:link
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan storage:link

- name: Check that the oauth-private.key exists
  ansible.builtin.stat:
    path: /laravel-bjyblog/site/storage/oauth-private.key
  register: oauth_key_stat

- name: Execute php artisan passport:keys
  when: not oauth_key_stat.stat.exists
  kubernetes.core.k8s_exec:
    namespace: blog
    pod: '{{ php_deployment.resources.0.metadata.name }}'
    command: php artisan passport:keys

- name: Change path ownership and group to www-data
  ansible.builtin.file:
    path: /laravel-bjyblog/site
    owner: www-data
    group: www-data
    recurse: true

- name: Ensure directories are 0755
  ansible.builtin.command: find /laravel-bjyblog/site -type d -exec chmod -c 0755 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""

- name: Ensure files are 0644
  ansible.builtin.command: find /laravel-bjyblog/site -type f -exec chmod -c 0644 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""

- name: Ensure public are 0775
  ansible.builtin.file:
    state: directory
    path: /laravel-bjyblog/site/public
    owner: www-data
    group: www-data
    mode: '0775'
