---
# Webserver to replace calling GitHub for projects.
# https://www.howtoforge.com/how-to-install-http-git-server-with-nginx-on-debian-11/

#TODO: Use gitweb instead??? I knew there was an easier way than apache/nginx/python stuff...
# https://git-scm.com/docs/gitweb

# Gitweb is nice but doesn;t seem like it allowes cloning. 
# Need to figure out how to get git:// to work, fix SSL locally, or somehow use http local and https when external..


## Variables ##

- name: Server | Software | HTTPS Git Server | Check Config Variables
  debug: 
    var: "{{ item }}"
  loop:
    - git_name
    - git_branch
    - git_url
    - git_sep

- name: Server | Software | HTTPS Git Server | Split Config Variables To Array
  set_fact:
    git_names: "{{ git_name.split(git_sep) }}"
    git_branches: "{{ git_branch.split(git_sep) }}"
    git_urls: "{{ git_url.split(git_sep) }}"
    git_projects: []

- name: Server | Software | HTTPS Git Server | Check Arrays
  debug: 
    var: "{{ item }}"
  loop:
    - git_names
    - git_branches
    - git_urls

- name: Server | Software | HTTPS Git Server | Build Dictionary
  set_fact:
    git_projects: "{{ git_projects + [{ 'name': git_names[item], 'branch': git_branches[item], 'url': git_urls[item]  }] }}"
  loop: "{{ range(0, git_names|length) | list }}"

- name: Server | Software | HTTPS Git Server | Display Dictionary
  debug: 
    var: git_projects

- name: Server | Software | HTTPS Git Server | Variables 1
  set_fact: 
    git_web_root: /var/www/html/git
    git_config_file: /etc/nginx/conf.d/git.conf
    git_nginx_user: www-data
    git_ssl_dir: /usr/local/etc/ssl/private
    git_ssl_cert_name: cert.pem
    git_ssl_key_name: key.pem

- name: Server | Software | HTTPS Git Server | Variables 2
  set_fact: 
    git_cron_commands: "git pull --rebase && cd {{ git_web_root }}/ && chown -R {{ git_nginx_user }} . && chmod -R 775 ."
    git_ssl_cert: "{{ git_ssl_dir }}/{{ git_ssl_cert_name }}"
    git_ssl_key: "{{ git_ssl_dir }}/{{ git_ssl_key_name }}"


## Pre-reqs ##

- name: Server | Software | HTTPS Git Server | Install
  package: 
    name:
      - nginx
      - git
      - fcgiwrap
      - apache2-utils
      - unzip
    state: present
  when: ansible_pkg_mgr == "apt"
  
- name: Server | Software | HTTPS Git Server | SSL Certificate
  shell: "{{ item }}"
  loop:
    - mkdir -p {{ git_ssl_dir }} 
    - openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout {{ git_ssl_key }} -out {{ git_ssl_cert }} -subj "/C=XX/ST=STATELESS/L=HOMELAB/O={{ domain }}/OU=Git Server/CN={{ domain }}"


## Repositories ##

- name: Server | Software | HTTPS Git Server | Delete
  file:
    path: "{{ git_web_root }}"
    state: absent

- name: Server | Software | HTTPS Git Server | Download
  git: 
    repo: "{{ item.url }}"
    dest: "{{ git_web_root }}/{{ item.name }}.git"
    version: "{{ item.branch }}"
    clone: yes
    force: yes
  ignore_errors: yes
  loop: "{{ git_projects }}"

- name: Server | Software | HTTPS Git Server | Permissions
  file:
    path: "{{ git_web_root }}/{{ item.name }}.git"
    state: directory
    mode: '755'
    owner: "{{ git_nginx_user }}"
    group: "{{ git_nginx_user }}"
    recurse: yes
  loop: "{{ git_projects }}"


## NGINX ##

- name: Server | Software | HTTPS Git Server | Index
  blockinfile:
    path: "{{ git_web_root }}/index.html"
    block: |
      {{ item.name }}.git is cloned from {{ item.url }} using branch {{ item.branch }}.
    state: present
    mode: '755'
    owner: "{{ git_nginx_user }}"
    group: "{{ git_nginx_user }}"
    create: yes
    backup: yes
    marker: "<!-- {mark} {{ item.name }} -->"
  loop: "{{ git_projects }}"

- name: Server | Software | HTTPS Git Server | Config
  blockinfile:
    path: "{{ git_config_file }}"
    block: |
      server {
        listen 443;
        server_name {{ ansible_hostname }}.{{ domain }};

        ssl_certificate {{ git_ssl_cert }};
        ssl_certificate_key {{ git_ssl_key }};
      
        root {{ git_web_root }};
      
        # Add index.php to the list if you are using PHP
        index index.html;
        #autoindex on;
      
        location / {
          # First attempt to serve request as file, then
          # as directory, then fall back to displaying a 404.
          try_files $uri $uri/ =404;
        }
      
        location ~ (/.*) {
          client_max_body_size 0;
          #auth_basic "Hyperling's Git Login";
          #auth_basic_user_file "{{ git_web_root }}/htpasswd";
          include /etc/nginx/fastcgi_params;
          fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
          fastcgi_param GIT_HTTP_EXPORT_ALL "";
          fastcgi_param GIT_PROJECT_ROOT {{ git_web_root }};
          fastcgi_param REMOTE_USER $remote_user;
          fastcgi_param PATH_INFO $1;
          fastcgi_pass unix:/var/run/fcgiwrap.socket;
        }
      }
    state: present
    mode: '755'
    create: yes
    backup: yes
    marker: "# {mark} Managed By Ansible Git Server Playbook -->"
    
- name: Server | Software | HTTPS Git Server | Service
  service:
    name: nginx
    pattern: nginx
    enabled: yes
    state: restarted


## Cron ##

- name: Server | Software | HTTPS Git Server | Cron | Hourly
  cron:
    name: "{{ item.name }} hourly"
    special_time: hourly
    job: "cd {{ git_web_root }}/{{ item.name }}.git && {{ git_cron_commands }}"
  loop: "{{ git_projects }}"

- name: Server | Software | HTTPS Git Server | Cron | Reboot
  cron:
    name: "{{ item.name }} reboot"
    special_time: reboot
    job: "cd {{ git_web_root }}/{{ item.name }}.git && {{ git_cron_commands }}"
  loop: "{{ git_projects }}"