From d9f7c11d2bf5280fd4d50dd9bb0fc6c6c37876ec Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Wed, 9 Apr 2025 19:05:36 -0400
Subject: [PATCH 1/9] feat: Add apache config to accept connections only from
 proxy

---
 ansible/group_vars/all                        |   4 +
 ansible/roles/ood_config/tasks/main.yml       |   6 +
 .../ood_config/templates/ood_proxy.conf.j2    | 206 ++++++++++++++++++
 3 files changed, 216 insertions(+)
 create mode 100644 ansible/roles/ood_config/tasks/main.yml
 create mode 100644 ansible/roles/ood_config/templates/ood_proxy.conf.j2

diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index 46267cd..dd5f8fa 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -89,3 +89,7 @@
   node_exporter_user: node_exporter
   node_exporter_group: node_exporter
   node_exporter_port: 9100
+
+# ood_config
+  ood_internal_ip: OOD_INTERNAL_IP
+  ood_hostname: ood-gpfs5
diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
new file mode 100644
index 0000000..6dfb713
--- /dev/null
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Add apache config to accept connections only from proxy
+  ansible.builtin.template:
+    src: ood_proxy.conf.j2
+    dest: /opt/rh/httpd24/root/etc/httpd/conf.d/ood-proxy.conf
+
diff --git a/ansible/roles/ood_config/templates/ood_proxy.conf.j2 b/ansible/roles/ood_config/templates/ood_proxy.conf.j2
new file mode 100644
index 0000000..d6ef3ad
--- /dev/null
+++ b/ansible/roles/ood_config/templates/ood_proxy.conf.j2
@@ -0,0 +1,206 @@
+#
+# Open OnDemand Portal
+#
+# Generated using ood-portal-generator version 0.8.0
+#
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !!                                    !!
+# !!     DO NOT EDIT THIS FILE          !!
+# !!                                    !!
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#
+# This file is auto-generated by ood-portal-generator and will be over-written
+# in future updates.
+#
+# 1. To modify this file, first update the global configuration file:
+#
+#      /etc/ood/config/ood_portal.yml
+#
+#    You can find more information about the ood-portal-generator configuration
+#    at:
+#
+#      https://osc.github.io/ood-documentation/master/infrastructure/ood-portal-generator.html
+#
+# 2. Then build/install the updated Apache config with:
+#
+#      sudo /opt/ood/ood-portal-generator/sbin/update_ood_portal
+#
+# 3. Finally, restart Apache to have the changes take effect:
+#
+#      # For CentOS 6
+#      sudo service httpd24-httpd condrestart
+#      sudo service httpd24-htcacheclean condrestart
+#
+#      # For CentOS 7
+#      sudo systemctl try-restart httpd24-httpd.service httpd24-htcacheclean.service
+#
+
+
+
+# The Open OnDemand portal VirtualHost
+#
+<VirtualHost {{ ood_internal_ip }}:80>
+  ServerName {{ ood_hostname }}
+
+  ErrorLog  "logs/SERVER_HOSTNAME_error.log"
+  CustomLog "logs/SERVER_HOSTNAME_access.log" combined
+
+  RewriteEngine On
+  RewriteCond %{HTTP_HOST} !^(rc.uab.edu(:80)?)?$ [NC]
+  RewriteRule ^(.*) http://rc.uab.edu:80$1 [R=301,NE,L]
+
+
+  # Lua configuration
+  #
+  LuaRoot "/opt/ood/mod_ood_proxy/lib"
+  LogLevel lua_module:info
+
+  # Log authenticated user requests (requires min log level: info)
+  LuaHookLog logger.lua logger
+
+  # Authenticated-user to system-user mapping configuration
+  #
+  SetEnv OOD_USER_MAP_CMD "/opt/ood/ood_auth_map/bin/user_auth.py"
+  SetEnv OOD_USER_ENV "REMOTE_USER"
+  SetEnv OOD_MAP_FAIL_URI "/account"
+
+  # Per-user Nginx (PUN) configuration
+  # NB: Apache will need sudo privs to control the PUNs
+  #
+  SetEnv OOD_PUN_STAGE_CMD "sudo /opt/ood/nginx_stage/sbin/nginx_stage"
+
+  #
+  # Below is used for sub-uri's this Open OnDemand portal supports
+  #
+
+  # Serve up publicly available assets from local file system:
+  #
+  #     http://SERVER_HOSTNAME:80/public/favicon.ico
+  #     #=> /var/www/ood/public/favicon.ico
+  #
+  Alias "/public" "/var/www/ood/public"
+  <Directory "/var/www/ood/public">
+    Options Indexes FollowSymLinks
+    AllowOverride None
+    Require all granted
+  </Directory>
+
+  # Reverse proxy traffic to backend webserver through IP sockets:
+  #
+  #     http://SERVER_HOSTNAME:80/node/HOST/PORT/index.html
+  #     #=> http://HOST:PORT/node/HOST/PORT/index.html
+  #
+  <LocationMatch "^/node/(?<host>c\d+)/(?<port>\d+)">
+    RewriteCond %{IS_SUBREQ} ^false$
+    RewriteCond %{HTTP:Proxy-user} "([^!]+?)(@uab.edu)?$"
+    RewriteRule . - [E=REMOTE_USER:%1]
+
+    # ProxyPassReverse implementation
+    Header edit Location "^[^/]+//[^/]+" ""
+
+    # ProxyPassReverseCookieDomain implemenation
+    Header edit* Set-Cookie ";\s*(?i)Domain[^;]*" ""
+
+    # ProxyPassReverseCookiePath implementation
+    Header edit* Set-Cookie ";\s*(?i)Path[^;]*" ""
+    Header edit  Set-Cookie "^([^;]+)" "$1; Path=/node/%{MATCH_HOST}e/%{MATCH_PORT}e"
+
+    LuaHookFixups node_proxy.lua node_proxy_handler
+  </LocationMatch>
+
+  # Reverse "relative" proxy traffic to backend webserver through IP sockets:
+  #
+  #     http://SERVER_HOSTNAME:80/rnode/HOST/PORT/index.html
+  #     #=> http://HOST:PORT/index.html
+  #
+  <LocationMatch "^/rnode/(?<host>c\d+)/(?<port>\d+)(?<uri>/.*|)">
+    RewriteCond %{IS_SUBREQ} ^false$
+    RewriteCond %{HTTP:Proxy-user} "([^!]+?)(@uab.edu)?$"
+    RewriteRule . - [E=REMOTE_USER:%1]
+
+    # ProxyPassReverse implementation
+    Header edit Location "^([^/]+//[^/]+)|(?=/)" "/rnode/%{MATCH_HOST}e/%{MATCH_PORT}e"
+
+    # ProxyPassReverseCookieDomain implemenation
+    Header edit* Set-Cookie ";\s*(?i)Domain[^;]*" ""
+
+    # ProxyPassReverseCookiePath implementation
+    Header edit* Set-Cookie ";\s*(?i)Path[^;]*" ""
+    Header edit  Set-Cookie "^([^;]+)" "$1; Path=/rnode/%{MATCH_HOST}e/%{MATCH_PORT}e"
+
+    LuaHookFixups node_proxy.lua node_proxy_handler
+  </LocationMatch>
+
+  # Reverse proxy traffic to backend PUNs through Unix domain sockets:
+  #
+  #     http://SERVER_HOSTNAME:80/pun/dev/app/simulations/1
+  #     #=> unix:/path/to/socket|http://localhost/pun/dev/app/simulations/1
+  #
+  SetEnv OOD_PUN_URI "/pun"
+  <Location "/pun">
+    RewriteCond %{IS_SUBREQ} ^false$
+    RewriteCond %{HTTP:Proxy-user} "([^!]+?)(@uab.edu)?$"
+    RewriteRule . - [E=REMOTE_USER:%1]
+
+    ProxyPassReverse "http://localhost/pun"
+
+    # ProxyPassReverseCookieDomain implementation (strip domain)
+    Header edit* Set-Cookie ";\s*(?i)Domain[^;]*" ""
+
+    # ProxyPassReverseCookiePath implementation (less restrictive)
+    Header edit* Set-Cookie ";\s*(?i)Path\s*=(?-i)(?!\s*/pun)[^;]*" "; Path=/pun"
+
+    SetEnv OOD_PUN_SOCKET_ROOT "/var/run/ondemand-nginx"
+    SetEnv OOD_PUN_MAX_RETRIES "5"
+    LuaHookFixups pun_proxy.lua pun_proxy_handler
+
+  </Location>
+
+  # Control backend PUN for authenticated user:
+  # NB: See mod_ood_proxy for more details.
+  #
+  #    http://SERVER_HOSTNAME:80/nginx/stop
+  #    #=> stops the authenticated user's PUN
+  #
+  SetEnv OOD_NGINX_URI "/nginx"
+  <Location "/nginx">
+    RewriteCond %{IS_SUBREQ} ^false$
+    RewriteCond %{HTTP:Proxy-user} "([^!]+?)(@uab.edu)?$"
+    RewriteRule . - [E=REMOTE_USER:%1]
+
+    LuaHookFixups nginx.lua nginx_handler
+  </Location>
+
+  # Redirect root URI to specified URI
+  #
+  #     http://SERVER_HOSTNAME:80/
+  #     #=> http://SERVER_HOSTNAME:80/pun/sys/dashboard
+  #
+  RedirectMatch ^/$ "/pun/sys/dashboard"
+
+  # Redirect logout URI to specified redirect URI
+  #
+  #     http://SERVER_HOSTNAME:80/logout
+  #     #=> http://SERVER_HOSTNAME:80/pun/sys/dashboard/logout
+  #
+  Redirect "/logout" "/pun/sys/dashboard/logout"
+
+
+
+
+  # Register and/or unregister the mapping of an authenticated-user to a system-user
+  # NB: This is not needed for regular expression mapping
+  #
+  #     http://SERVER_HOSTNAME:80/account
+  #     #=> /var/www/ood/register/
+  #
+  Alias "/account" "/var/www/ood/register"
+  <Directory "/var/www/ood/register">
+    Options Indexes FollowSymLinks
+    AllowOverride None
+
+    RewriteCond %{IS_SUBREQ} ^false$
+    RewriteCond %{HTTP:Proxy-user} "([^!]+?)(@uab.edu)?$"
+    RewriteRule . - [E=REMOTE_USER:%1]
+  </Directory>
+</VirtualHost>
-- 
GitLab


From cef5a3432760252b537fabf64d4d85fa20849a50 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Wed, 9 Apr 2025 19:11:53 -0400
Subject: [PATCH 2/9] feat: Parameterize OOD shell app default host

---
 ansible/group_vars/all                  | 5 +++++
 ansible/roles/ood_config/tasks/main.yml | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index dd5f8fa..c57babd 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -93,3 +93,8 @@
 # ood_config
   ood_internal_ip: OOD_INTERNAL_IP
   ood_hostname: ood-gpfs5
+  ood_domain: https://rc.uab.edu
+  login_hostname: login-gpfs5
+  account_app: account
+  account_app_port: 8000
+  account_app_bind_address: ["0.0.0.0:{{account_app_port}}"]
diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index 6dfb713..760d8aa 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -4,3 +4,10 @@
     src: ood_proxy.conf.j2
     dest: /opt/rh/httpd24/root/etc/httpd/conf.d/ood-proxy.conf
 
+- name: Point shell app to login node
+  ansible.builtin.replace:
+    path: /etc/ood/config/clusters.d/SLURM_CLUSTER.yml
+    regexp: '^(\s+host:).*'
+    replace: '\1 "{{ login_hostname }}"'
+    backup: yes
+
-- 
GitLab


From 962384e2fbcd70f55b2efc767e76c3744efd9f70 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Wed, 9 Apr 2025 19:13:20 -0400
Subject: [PATCH 3/9] feat: Deploy patched version of shell app to avoid short
 timeouts

---
 ansible/roles/ood_config/tasks/main.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index 760d8aa..cb9c4ef 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -4,6 +4,11 @@
     src: ood_proxy.conf.j2
     dest: /opt/rh/httpd24/root/etc/httpd/conf.d/ood-proxy.conf
 
+- name: Download patched shell app with shell timeout fix
+  ansible.builtin.get_url:
+    url: https://s3.lts.rc.uab.edu/ood-proxy-file/ood-proxy.conf
+    dest: /var/www/ood/apps/sys/shell/app.js 
+
 - name: Point shell app to login node
   ansible.builtin.replace:
     path: /etc/ood/config/clusters.d/SLURM_CLUSTER.yml
-- 
GitLab


From 360f616fe1739017a502175a5af32e45fa0f55ba Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Wed, 9 Apr 2025 19:17:06 -0400
Subject: [PATCH 4/9] feat: Set origin to OOD for shell app to avoid CORS

---
 ansible/roles/ood_config/tasks/main.yml             | 5 +++++
 ansible/roles/ood_config/templates/shell_app.env.j2 | 1 +
 2 files changed, 6 insertions(+)
 create mode 100644 ansible/roles/ood_config/templates/shell_app.env.j2

diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index cb9c4ef..c020e50 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -9,6 +9,11 @@
     url: https://s3.lts.rc.uab.edu/ood-proxy-file/ood-proxy.conf
     dest: /var/www/ood/apps/sys/shell/app.js 
 
+- name: Shell app configuration env
+  ansible.builtin.template:
+    src: shell_app.env.j2
+    dest: /etc/ood/config/apps/shell/env
+
 - name: Point shell app to login node
   ansible.builtin.replace:
     path: /etc/ood/config/clusters.d/SLURM_CLUSTER.yml
diff --git a/ansible/roles/ood_config/templates/shell_app.env.j2 b/ansible/roles/ood_config/templates/shell_app.env.j2
new file mode 100644
index 0000000..b078fe8
--- /dev/null
+++ b/ansible/roles/ood_config/templates/shell_app.env.j2
@@ -0,0 +1 @@
+OOD_SHELL_ORIGIN_CHECK='{{ ood_domain }}'
-- 
GitLab


From c8750b56f0715abc13f0cd9e5489485c1209ac82 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Wed, 9 Apr 2025 19:20:35 -0400
Subject: [PATCH 5/9] feat: Restart software collections(SCL) httpd

---
 ansible/roles/ood_config/tasks/main.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index c020e50..7e2949e 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -21,3 +21,8 @@
     replace: '\1 "{{ login_hostname }}"'
     backup: yes
 
+- name: Restart httpd24-httpd
+  ansible.builtin.service:
+    name: httpd24-httpd
+    state: restarted
+
-- 
GitLab


From d7317589399522bdae874d67a8ba8149f02b040c Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Thu, 10 Apr 2025 10:31:25 -0400
Subject: [PATCH 6/9] feat: Add role ood_config to playbook cluster.yml

---
 ansible/cluster.yml    | 2 ++
 ansible/group_vars/all | 1 +
 2 files changed, 3 insertions(+)

diff --git a/ansible/cluster.yml b/ansible/cluster.yml
index 9664bf9..d940e1b 100644
--- a/ansible/cluster.yml
+++ b/ansible/cluster.yml
@@ -14,3 +14,5 @@
     - { name: 'rewrite_map', tags: 'rewrite_map', when: enable_rewrite_map }
     - { name: 'fail2ban', tags: 'fail2ban', when: enable_fail2ban }
     - { name: 'install_node_exporter', tags: 'install_node_exporter', when: enable_node_exporter }
+    - { name: 'ood_config', tags: 'ood_config', when: enable_ood_config }
+
diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index c57babd..3e57753 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -91,6 +91,7 @@
   node_exporter_port: 9100
 
 # ood_config
+  enable_ood_config: false
   ood_internal_ip: OOD_INTERNAL_IP
   ood_hostname: ood-gpfs5
   ood_domain: https://rc.uab.edu
-- 
GitLab


From 6d47445e39661d378ac2f831e87a0eb51b238858 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Fri, 11 Apr 2025 13:20:27 -0400
Subject: [PATCH 7/9] feat: Install missing pkg required during deploy

NetworkManager is restarted during cloud-init final module but it fails
because the package was not available. So install it during build
process to make it available during deploy
---
 openstack-ood/nodeimage.pkr.hcl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openstack-ood/nodeimage.pkr.hcl b/openstack-ood/nodeimage.pkr.hcl
index 1a13744..6ade3c0 100644
--- a/openstack-ood/nodeimage.pkr.hcl
+++ b/openstack-ood/nodeimage.pkr.hcl
@@ -60,7 +60,7 @@ build {
 
   provisioner "shell" {
     inline = [
-      "sudo yum install -y libselinux-python3 python3 python3-pip tmux vim git bash-completion curl wget unzip",
+      "sudo yum install -y libselinux-python3 python3 python3-pip tmux vim git bash-completion curl wget unzip NetworkManager",
       "sudo python3 -m pip install --upgrade pip",
       "sudo pip3 install s3cmd==2.3.0 ansible==4.10.0 python-openstackclient==5.8.0"
     ]
-- 
GitLab


From 12498b55a264ab22407750ecae1dd8ccffd3eb64 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Tue, 6 May 2025 20:14:22 -0400
Subject: [PATCH 8/9] feat: Create a dir for shell app env config

---
 ansible/roles/ood_config/tasks/main.yml | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index 7e2949e..75d140e 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -7,7 +7,13 @@
 - name: Download patched shell app with shell timeout fix
   ansible.builtin.get_url:
     url: https://s3.lts.rc.uab.edu/ood-proxy-file/ood-proxy.conf
-    dest: /var/www/ood/apps/sys/shell/app.js 
+    dest: /var/www/ood/apps/sys/shell/app.js
+
+- name: Create a directory if it does not exist
+  ansible.builtin.file:
+    path: /etc/ood/config/apps/shell
+    state: directory
+    mode: "0755"
 
 - name: Shell app configuration env
   ansible.builtin.template:
@@ -25,4 +31,3 @@
   ansible.builtin.service:
     name: httpd24-httpd
     state: restarted
-
-- 
GitLab


From 81eca6c5f6487bdc69c329c11074dbdd2de04c75 Mon Sep 17 00:00:00 2001
From: Eesaan Atluri <atlurie@uab.edu>
Date: Tue, 3 Jun 2025 16:20:09 -0500
Subject: [PATCH 9/9] feat: Modify account app binding to listen to http-proxy

Closes https://gitlab.rc.uab.edu/rc/hpc-factory/-/issues/248
With this change you can define multiple bind addresses for account app
Gunicorn allows defining multiple bind addresses.
---
 ansible/roles/ood_config/tasks/main.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ansible/roles/ood_config/tasks/main.yml b/ansible/roles/ood_config/tasks/main.yml
index 75d140e..0219d77 100644
--- a/ansible/roles/ood_config/tasks/main.yml
+++ b/ansible/roles/ood_config/tasks/main.yml
@@ -27,6 +27,12 @@
     replace: '\1 "{{ login_hostname }}"'
     backup: yes
 
+- name: Modify account app binding to listen to http-proxy
+  ansible.builin.lineinfile:
+    path: /var/www/ood/register/{{account_app}}/{{account_app}}.ini
+    regexp: '^(bind\s=).*'
+    replace: '\1 {{ account_app_bind_address }}'
+
 - name: Restart httpd24-httpd
   ansible.builtin.service:
     name: httpd24-httpd
-- 
GitLab