From aaee1c5a0566f1e36e476cce446365c9a459434e Mon Sep 17 00:00:00 2001
From: Lukasz Nowak <luke@nexedi.com>
Date: Mon, 7 Oct 2019 08:25:21 +0200
Subject: [PATCH] software/kvm: Request real frontend for default software type

Real frontend is always requested.

Additional frontend is requested only if frontend-additional-instance-guid is
not empty. This frontend is published as url-additional and can be used for
access to users from some restricted networks.
---
 software/kvm/README.rst                     |  5 +-
 software/kvm/buildout.hash.cfg              |  2 +-
 software/kvm/instance-kvm-input-schema.json | 25 +++++-
 software/kvm/instance-kvm.cfg.jinja2        | 84 ++++++++++++++++++---
 software/kvm/software.cfg                   |  2 +
 5 files changed, 100 insertions(+), 18 deletions(-)

diff --git a/software/kvm/README.rst b/software/kvm/README.rst
index d3d7e29cc..07f703494 100644
--- a/software/kvm/README.rst
+++ b/software/kvm/README.rst
@@ -35,9 +35,10 @@ See the instance-kvm-input-schema.json file for more instance parameters (cpu-co
 KVM instance parameters:
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- frontend-software-type (default: frontend)
-- frontend-software-url (default: https://lab.nexedi.com/nexedi/slapos/raw/slapos-0.92/software/kvm/software.cfg)
+- frontend-software-type (default: RootSoftwareInstance)
+- frontend-software-url (default: http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg)
 - frontend-instance-guid
+- frontend-addtional-instance-guid
 - frontend-instance-name (default: VNC Frontend)
 - nbd-port (default: 1024)
 - nbd-host
diff --git a/software/kvm/buildout.hash.cfg b/software/kvm/buildout.hash.cfg
index 40987cbf1..ea2dc56f6 100644
--- a/software/kvm/buildout.hash.cfg
+++ b/software/kvm/buildout.hash.cfg
@@ -19,7 +19,7 @@ md5sum = 028b6a6456d744c11b1bb2c51ecd51b2
 
 [template-kvm]
 filename = instance-kvm.cfg.jinja2
-md5sum = 857237f3de9fb42da919a7164a355e4f
+md5sum = dc4dc40f9d950b5f963c22c62ca488a7
 
 [template-kvm-cluster]
 filename = instance-kvm-cluster.cfg.jinja2.in
diff --git a/software/kvm/instance-kvm-input-schema.json b/software/kvm/instance-kvm-input-schema.json
index 118127a23..764f49697 100644
--- a/software/kvm/instance-kvm-input-schema.json
+++ b/software/kvm/instance-kvm-input-schema.json
@@ -336,21 +336,38 @@
     "frontend-instance-guid": {
       "title": "Frontend Instance ID",
       "description": "Unique identifier of the frontend instance, like \"SOFTINST-11031\".",
-      "type": "string",
-      "default": "SOFTINST-11031"
+      "type": "string"
     },
     "frontend-software-type": {
       "title": "Frontend Software Type",
       "description": "Type of the frontend instance, like \"frontend\".",
       "type": "string",
-      "default": "frontend"
+      "default": "RootSoftwareInstance"
     },
     "frontend-software-url": {
       "title": "Frontend Software URL",
       "description": "Software Release URL of the frontend instance, like \"http://example.com/path/to/software.cfg\".",
       "type": "string",
       "format": "uri",
-      "default": "https://lab.nexedi.com/nexedi/slapos/raw/slapos-0.92/software/kvm/software.cfg"
+      "default": "http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg"
+    },
+    "frontend-additional-instance-guid": {
+      "title": "Additional Frontend Instance ID",
+      "description": "Unique identifier of the additional frontend instance, like \"SOFTINST-11031\", if empty won't be requested.",
+      "type": "string"
+    },
+    "frontend-additional-software-type": {
+      "title": "Additional Frontend Software Type",
+      "description": "Type of the frontend instance, like \"frontend\".",
+      "type": "string",
+      "default": "RootSoftwareInstance"
+    },
+    "frontend-additional-software-url": {
+      "title": "Additional Frontend Software URL",
+      "description": "Software Release URL of the frontend instance, like \"http://example.com/path/to/software.cfg\".",
+      "type": "string",
+      "format": "uri",
+      "default": "http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg"
     }
   }
 }
diff --git a/software/kvm/instance-kvm.cfg.jinja2 b/software/kvm/instance-kvm.cfg.jinja2
index cbffc34c6..d4b382435 100644
--- a/software/kvm/instance-kvm.cfg.jinja2
+++ b/software/kvm/instance-kvm.cfg.jinja2
@@ -1,3 +1,4 @@
+{% set additional_frontend = (slapparameter_dict.get('frontend-additional-instance-guid', '').strip() != '') %}
 {% set enable_http = slapparameter_dict.get('enable-http-server', 'False').lower() -%}
 {% set use_tap = slapparameter_dict.get('use-tap', 'True').lower() -%}
 {% set use_nat = slapparameter_dict.get('use-nat', 'True').lower() -%}
@@ -358,20 +359,24 @@ log = ${directory:log}/crond.log
 #--
 #-- Deploy frontend.
 
-[request-slave-frontend]
+[request-slave-frontend-base]
 recipe = slapos.cookbook:requestoptional
-software-url = ${slap-parameter:frontend-software-url}
 server-url = ${slap-connection:server-url}
 key-file = ${slap-connection:key-file}
 cert-file = ${slap-connection:cert-file}
 computer-id = ${slap-connection:computer-id}
 partition-id = ${slap-connection:partition-id}
-name = ${slap-parameter:frontend-instance-name}
-software-type = ${slap-parameter:frontend-software-type}
 slave = true
-config-host = ${novnc-instance:ip}
-config-port = ${novnc-instance:port}
-return = url resource port domainname
+config-https-only = True
+config-type = websocket
+config-url = https://[${novnc-instance:ip}]:${novnc-instance:port}
+return = secure_access domain
+
+[request-slave-frontend]
+<= request-slave-frontend-base
+software-url = ${slap-parameter:frontend-software-url}
+software-type = ${slap-parameter:frontend-software-type}
+name = ${slap-parameter:frontend-instance-name}
 sla-instance_guid = ${slap-parameter:frontend-instance-guid}
 
 [frontend-promise]
@@ -381,6 +386,21 @@ url = ${publish-connection-information:url}
 dash_path = {{ dash_executable_location }}
 curl_path = {{ curl_executable_location }}
 
+{% if additional_frontend %}
+[request-slave-frontend-additional]
+<= request-slave-frontend-base
+software-url = ${slap-parameter:frontend-additional-software-url}
+software-type = ${slap-parameter:frontend-additional-software-type}
+name = ${slap-parameter:frontend-additional-instance-name}
+sla-instance_guid = ${slap-parameter:frontend-additional-instance-guid}
+
+[frontend-additional-promise]
+recipe = slapos.cookbook:check_url_available
+path = ${directory:promises}/frontend_additional_promise
+url = ${publish-connection-information:url-additional}
+dash_path = {{ dash_executable_location }}
+curl_path = {{ curl_executable_location }}
+{% endif %}
 
 {% if enable_http == 'true' %}
 [httpd]
@@ -421,12 +441,47 @@ interface-url = {{ slapparameter_dict.get('monitor-interface-url', 'https://moni
 [helper]
 blank-line =
 
+[frontend-port-execute-base]
+recipe = plone.recipe.command
+command =
+  set -e
+  port=$(echo '${request-slave-frontend:connection-secure_access}' | cut -d ':' -f 3 | cut -d '/' -f 1)
+  [ -z $port ] && port=443
+  echo $port > ${:output}
+update-command = ${:command}
+stop-on-error = True
+
+[frontend-port-execute]
+<= frontend-port-execute-base
+secure_access = ${request-slave-frontend:connection-secure_access}
+output = ${directory:var}/frontend_port.txt
+
+[frontend-port]
+recipe = collective.recipe.shelloutput
+filename = ${frontend-port-execute:output}
+commands =
+  port = [ -f '${:filename}' ] && cat '${:filename}' || echo "NotReady"
+
+{% if additional_frontend %}
+[frontend-additional-port-execute]
+<= frontend-port-execute-base
+secure_access = ${request-slave-frontend-additional:connection-secure_access}
+output = ${directory:var}/frontend_additional_port.txt
+
+[frontend-additional-port]
+<= frontend-port
+filename = ${frontend-additional-port-execute:output}
+{% endif %}
+
 [publish-connection-information]
 <= monitor-publish
 recipe = slapos.cookbook:publish
 ipv6 = ${slap-network-information:global-ipv6}
 backend-url = https://[${novnc-instance:ip}]:${novnc-instance:port}/vnc.html?host=[${novnc-instance:ip}]&port=${novnc-instance:port}&encrypt=1&password=${kvm-controller-parameter-dict:vnc-passwd}
-url = ${request-slave-frontend:connection-url}/vnc.html?host=${request-slave-frontend:connection-domainname}&port=${request-slave-frontend:connection-port}&encrypt=1&path=${request-slave-frontend:connection-resource}&password=${kvm-controller-parameter-dict:vnc-passwd}
+url = ${request-slave-frontend:connection-secure_access}/vnc.html?host=${request-slave-frontend:connection-domain}&port=${frontend-port:port}&encrypt=1&password=${kvm-controller-parameter-dict:vnc-passwd}
+{% if additional_frontend %}
+url-additional = ${request-slave-frontend-additional:connection-secure_access}/vnc.html?host=${request-slave-frontend-additional:connection-domain}&port=${frontend-additional-port:port}&encrypt=1&password=${kvm-controller-parameter-dict:vnc-passwd}
+{% endif %}
 {% set disk_number = len(storage_dict) -%}
 maximum-extra-disk-amount = {{ disk_number }}
 {% set iface = 'ens3' -%}
@@ -647,10 +702,14 @@ log = ${directory:public}/ansible/vm-bootstrap.log
 
 [slap-parameter]
 # Default values if not specified
-frontend-software-type = frontend
-frontend-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/tags/slapos-0.92:/software/kvm/software.cfg
+frontend-software-type = RootSoftwareInstance
+frontend-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
 frontend-instance-guid =
-frontend-instance-name = VNC Frontend
+frontend-instance-name = VNC Real Frontend
+frontend-additional-software-type = RootSoftwareInstance
+frontend-additional-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
+frontend-additional-instance-guid =
+frontend-additional-instance-name = VNC Real Frontend Additional
 nbd-port = 1024
 nbd-host =
 nbd2-port = 1024
@@ -762,6 +821,9 @@ parts =
   cron-service
   cron-entry-logrotate
   frontend-promise
+{% if additional_frontend %}
+  frontend-additional-promise
+{% endif %}
 # monitor parts
   monitor-base
 # Complete parts with sections
diff --git a/software/kvm/software.cfg b/software/kvm/software.cfg
index 5a4176dad..e25c88903 100644
--- a/software/kvm/software.cfg
+++ b/software/kvm/software.cfg
@@ -56,6 +56,7 @@ eggs =
   collective.recipe.template
   plone.recipe.command
   ${pycurl:egg}
+  collective.recipe.shelloutput
 
 [http-proxy]
 # https://github.com/nodejitsu/node-http-proxy
@@ -201,6 +202,7 @@ context =
 websockify = 0.5.1
 
 collective.recipe.environment = 0.2.0
+collective.recipe.shelloutput = 0.1
 gitdb = 0.6.4
 pycurl = 7.43.0
 slapos.recipe.template = 4.3
-- 
GitLab