diff --git a/bundles.yml b/bundles.yml new file mode 100644 index 0000000..5b9120e --- /dev/null +++ b/bundles.yml @@ -0,0 +1,4 @@ +--- + +dependencies: + - url: ../common.git diff --git a/consul/config/service-defaults/diagrams.hcl b/consul/config/service-defaults/diagrams.hcl new file mode 100644 index 0000000..a6d977d --- /dev/null +++ b/consul/config/service-defaults/diagrams.hcl @@ -0,0 +1,3 @@ +Kind = "service-defaults" +Name = "[[ .diagrams.instance ]][[ .consul.suffix ]]" +Protocol = "http" diff --git a/consul/config/service-intentions/diagrams.hcl b/consul/config/service-intentions/diagrams.hcl new file mode 100644 index 0000000..6017f20 --- /dev/null +++ b/consul/config/service-intentions/diagrams.hcl @@ -0,0 +1,15 @@ +Kind = "service-intentions" +Name = "[[ .diagrams.instance ]][[ .consul.suffix ]]" +Sources = [ + { + Name = "[[ .traefik.instance ]]" + Permissions = [ + { + Action = "allow" + HTTP { + PathPrefix = "/" + } + } + ] + } +] diff --git a/diagrams.nomad.hcl b/diagrams.nomad.hcl new file mode 100644 index 0000000..900532f --- /dev/null +++ b/diagrams.nomad.hcl @@ -0,0 +1,89 @@ +[[ $c := merge .diagrams . -]] +job [[ .diagrams.instance | toJSON ]] { + +[[ template "common/job_start.tpl" $c ]] + + group "diagrams" { + network { + mode = "bridge" + } + + service { + name = "[[ .diagrams.instance ]][[ .consul.suffix ]]" + port = 8282 + +[[ template "common/connect.tpl" $c ]] + + check { + type = "http" + path = "/health" + expose = true + interval = "1m" + timeout = "8s" + + check_restart { + limit = 4 + grace = "1m" + } + } + + tags = [ + "[[ $c.traefik.instance ]].enable=[[ $c.traefik.enabled ]]", + + # Define a middleware to set custom CSP headers + "[[ $c.traefik.instance ]].http.middlewares.[[ .diagrams.instance ]]-headers[[ .consul.suffix ]].headers.contentsecuritypolicy=[[ range $k, $v := $c.traefik.csp ]][[ $k ]] [[ $v ]];[[ end ]]", + +[[- if not (regexp.Match "^/?$" (urlParse $c.public_url).Path) ]] + # Diagrams exposed by traefik on a subpath. Define a middleware to strip the prefix before passing the request to the backend + "[[ $c.traefik.instance ]].http.middlewares.[[ .diagrams.instance ]]-prefix[[ .consul.suffix ]].stripprefix.prefixes=[[ (urlParse .diagrams.public_url).Path ]]", +[[- end ]] + + # Main app router + "[[ $c.traefik.instance ]].http.routers.[[ .diagrams.instance ]][[ .consul.suffix ]].rule=Host(`[[ (urlParse $c.public_url).Hostname ]]`) + [[- if not (regexp.Match "^/?$" (urlParse $c.public_url).Path) ]] && PathPrefix(`[[ (urlParse $c.public_url).Path ]]`)[[ end ]]", + "[[ $c.traefik.instance ]].http.routers.[[ .diagrams.instance ]][[ .consul.suffix ]].entrypoints=[[ join $c.traefik.entrypoints "," ]]", +[[- if not (regexp.Match "^/?$" (urlParse $c.public_url).Path) ]] + "[[ $c.traefik.instance ]].http.routers.[[ .diagrams.instance ]][[ .consul.suffix ]].middlewares=[[ .diagrams.instance ]]-prefix[[ $c.consul.suffix ]],[[ .diagrams.instance ]]-headers[[ .consul.suffix ]],[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", +[[- else ]] + "[[ $c.traefik.instance ]].http.routers.[[ .diagrams.instance ]][[ .consul.suffix ]].middlewares=[[ .diagrams.instance ]]-headers[[ .consul.suffix ]],[[ template "common/traefik_middlewares.tpl" $c.traefik ]]", +[[- end ]] + ] + } + + task "diagrams" { + driver = [[ $c.nomad.driver | toJSON ]] + + config { + image = [[ $c.image | toJSON ]] + pids_limit = 100 + readonly_rootfs = true + volumes = [ + "local/PreConfig.js:/opt/tomcat/webapps/draw/js/PreConfig.js", + "local/PostConfig.js:/opt/tomcat/webapps/draw/js/PostConfig.js" + ] + } + + env { + JAVA_OPTS = "-Djava.io.tmpdir=/local" + TOMCAT_ADDRESS = "127.0.0.1" + } + + template { + data =<<_EOT +[[ template "diagrams/PreConfig.js.tpl" $c ]] +_EOT + destination = "local/PreConfig.js" + } + + template { + data =<<_EOT +[[ template "diagrams/PostConfig.js.tpl" $c ]] +_EOT + destination = "local/PostConfig.js" + } + +[[ template "common/file_env.tpl" $c.env ]] +[[ template "common/resources.tpl" $c.resources ]] + } + } +} diff --git a/images/diagrams/Dockerfile b/images/diagrams/Dockerfile new file mode 100644 index 0000000..c8df6d0 --- /dev/null +++ b/images/diagrams/Dockerfile @@ -0,0 +1,36 @@ +FROM [[ .docker.repo ]][[ .docker.base_images.java17.image ]] +MAINTAINER [[ .docker.maintainer ]] + +ARG TOMCAT_VERSION=9.0.83 \ + DIAGRAMS_VERSION=22.1.5 + +ENV CATALINA_HOME=/opt/tomcat \ + TOMCAT_PORT=8282 \ + TOMCAT_ADDRESS=0.0.0.0 + +RUN set -euxo pipefail &&\ + cd /tmp &&\ + apk --no-cache update &&\ + apk --no-cache add bash &&\ + curl -sSLO https://dlcdn.apache.org/tomcat/tomcat-9/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz &&\ + curl -sSLO https://dlcdn.apache.org/tomcat/tomcat-9/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz.sha512 &&\ + sha512sum -c < apache-tomcat-${TOMCAT_VERSION}.tar.gz.sha512 &&\ + mkdir -p /opt/tomcat &&\ + tar xvzf apache-tomcat-${TOMCAT_VERSION}.tar.gz --strip-components 1 --directory ${CATALINA_HOME} &&\ + find /opt/tomcat -type d -exec chmod 755 "{}" \; &&\ + find /opt/tomcat -type f -exec chmod 644 "{}" \; &&\ + chmod +x /opt/tomcat/bin/* &&\ + rm -f apache-tomcat-${TOMCAT_VERSION}.tar.gz.sha512 apache-tomcat-${TOMCAT_VERSION}.tar.gz &&\ + curl -sSLO https://github.com/jgraph/drawio/releases/download/v${DIAGRAMS_VERSION}/draw.war &&\ + unzip draw.war -d ${CATALINA_HOME}/webapps/draw &&\ + rm draw.war &&\ + addgroup --gid 8282 diagrams &&\ + adduser --system --ingroup diagrams --disabled-password --uid 8282 --home ${CATALINA_HOME} --shell /sbin/nologin diagrams + +COPY root/ / + +WORKDIR ${CATALINA_HOME} +EXPOSE ${TOMCAT_PORT} +USER diagrams +CMD ["/opt/tomcat/bin/catalina.sh", "run"] + diff --git a/images/diagrams/root/entrypoint.d/91-diagrams-java-opts.env b/images/diagrams/root/entrypoint.d/91-diagrams-java-opts.env new file mode 100755 index 0000000..f3d2297 --- /dev/null +++ b/images/diagrams/root/entrypoint.d/91-diagrams-java-opts.env @@ -0,0 +1,5 @@ +#!/bin/sh + +set -eu + +export CATALINA_OPTS="${JAVA_OPTS} -Dtomcat.port=${TOMCAT_PORT} -Dtomcat.address=${TOMCAT_ADDRESS}" diff --git a/images/diagrams/root/opt/tomcat/conf/logging.properties b/images/diagrams/root/opt/tomcat/conf/logging.properties new file mode 100644 index 0000000..471e556 --- /dev/null +++ b/images/diagrams/root/opt/tomcat/conf/logging.properties @@ -0,0 +1,16 @@ +handlers = java.util.logging.ConsoleHandler + +.handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINE +java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter +java.util.logging.ConsoleHandler.encoding = UTF-8 + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = java.util.logging.ConsoleHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = java.util.logging.ConsoleHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = java.util.logging.ConsoleHandler diff --git a/images/diagrams/root/opt/tomcat/conf/server.xml b/images/diagrams/root/opt/tomcat/conf/server.xml new file mode 100644 index 0000000..102f97a --- /dev/null +++ b/images/diagrams/root/opt/tomcat/conf/server.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/images/diagrams/root/opt/tomcat/webapps/draw/js/PostCOnfig.js b/images/diagrams/root/opt/tomcat/webapps/draw/js/PostCOnfig.js new file mode 100644 index 0000000..5182b3b --- /dev/null +++ b/images/diagrams/root/opt/tomcat/webapps/draw/js/PostCOnfig.js @@ -0,0 +1,5 @@ +window.VSD_CONVERT_URL = null; +window.ICONSEARCH_PATH = null; +EditorUi.enableLogging = false; //Disable logging +window.EMF_CONVERT_URL = null; +App.prototype.isDriveDomain = function() { return true; } diff --git a/images/diagrams/root/opt/tomcat/webapps/draw/js/PreConfig.js b/images/diagrams/root/opt/tomcat/webapps/draw/js/PreConfig.js new file mode 100644 index 0000000..b51241b --- /dev/null +++ b/images/diagrams/root/opt/tomcat/webapps/draw/js/PreConfig.js @@ -0,0 +1,22 @@ +(function() { + try { + var s = document.createElement('meta'); + s.setAttribute('content', 'default-src \'self\'; script-src \'self\' https://storage.googleapis.com https://apis.google.com https://docs.google.com https://code.jquery.com \'unsafe-inline\'; connect-src \'self\' https://*.dropboxapi.com https://api.trello.com https://api.github.com https://raw.githubusercontent.com https://*.googleapis.com https://*.googleusercontent.com https://graph.microsoft.com https://*.1drv.com https://*.sharepoint.com https://gitlab.com https://*.google.com https://fonts.gstatic.com https://fonts.googleapis.com; img-src * data:; media-src * data:; font-src * about:; style-src \'self\' \'unsafe-inline\' https://fonts.googleapis.com; frame-src \'self\' https://*.google.com;'); + s.setAttribute('http-equiv', 'Content-Security-Policy'); + var t = document.getElementsByTagName('meta')[0]; + t.parentNode.insertBefore(s, t); + } catch (e) {} // ignore +})(); +window.DRAWIO_BASE_URL = 'http://localhost:8080'; +window.DRAWIO_SERVER_URL = window.DRAWIO_BASE_URL + '/'; +window.DRAWIO_VIEWER_URL = ''; +window.DRAWIO_LIGHTBOX_URL = ''; +window.DRAW_MATH_URL = 'math/es5'; +window.DRAWIO_CONFIG = null; +urlParams['sync'] = 'manual'; //Disable Real-Time +urlParams['db'] = '0'; //dropbox +urlParams['gh'] = '0'; //github +urlParams['tr'] = '0'; //trello +urlParams['gapi'] = '0'; //Google Drive +urlParams['od'] = '0'; //OneDrive +urlParams['gl'] = '0'; //Gitlab diff --git a/prep.d/10-mv-conf.sh b/prep.d/10-mv-conf.sh new file mode 100755 index 0000000..50c339d --- /dev/null +++ b/prep.d/10-mv-conf.sh @@ -0,0 +1 @@ +[[ template "common/mv_conf.sh.tpl" dict "ctx" . "services" (dict "diagrams" .diagrams.instance) ]] diff --git a/templates/PostConfig.js.tpl b/templates/PostConfig.js.tpl new file mode 100644 index 0000000..5182b3b --- /dev/null +++ b/templates/PostConfig.js.tpl @@ -0,0 +1,5 @@ +window.VSD_CONVERT_URL = null; +window.ICONSEARCH_PATH = null; +EditorUi.enableLogging = false; //Disable logging +window.EMF_CONVERT_URL = null; +App.prototype.isDriveDomain = function() { return true; } diff --git a/templates/PreConfig.js.tpl b/templates/PreConfig.js.tpl new file mode 100644 index 0000000..c588b43 --- /dev/null +++ b/templates/PreConfig.js.tpl @@ -0,0 +1,13 @@ +window.DRAWIO_BASE_URL = '[[ .diagrams.public_url ]]'; +window.DRAWIO_SERVER_URL = '[[ .diagrams.public_url | regexp.Replace "/$" "" ]]/'; +window.DRAWIO_VIEWER_URL = '[[ .diagrams.public_url | regexp.Replace "/$" "" ]]/js/viewer.min.js'; +window.DRAWIO_LIGHTBOX_URL = ''; +window.DRAW_MATH_URL = 'math/es5'; +window.DRAWIO_CONFIG = null; +urlParams['sync'] = 'manual'; //Disable Real-Time +urlParams['db'] = '0'; //dropbox +urlParams['gh'] = '0'; //github +urlParams['tr'] = '0'; //trello +urlParams['gapi'] = '0'; //Google Drive +urlParams['od'] = '0'; //OneDrive +urlParams['gl'] = '0'; //Gitlab diff --git a/templates/server.xml.tpl b/templates/server.xml.tpl new file mode 100644 index 0000000..8bd6b9e --- /dev/null +++ b/templates/server.xml.tpl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/variables.yml b/variables.yml new file mode 100644 index 0000000..fea2e09 --- /dev/null +++ b/variables.yml @@ -0,0 +1,21 @@ +--- + +diagrams: + instance: diagrams + image: danielberteaud/diagrams:latest + env: {} + public_url: https://draw.example.org + traefik: + enabled: true + csp: + default-src: "'self'" + script-src: "'self' https://storage.googleapis.com https://apis.google.com https://docs.google.com https://code.jquery.com 'unsafe-inline'" + connect-src: "'self' https://*.dropboxapi.com https://api.trello.com https://api.github.com https://raw.githubusercontent.com https://*.googleapis.com https://*.googleusercontent.com https://graph.microsoft.com https://*.1drv.com https://*.sharepoint.com https://gitlab.com https://*.google.com https://fonts.gstatic.com https://fonts.googleapis.com" + img-src: " * data:" + media-src: "* data:" + font-src: "* about:" + style-src: "'self' 'unsafe-inline' https://fonts.googleapis.com" + frame-src: "'self' https://*.google.com" + resources: + cpu: 200 + memory: 256