diff --git a/nomad/api/app.py b/nomad/api/app.py index 8eb1fe28db7cfb3dee1880915674846021d4bb93..b23bc69a19b25476addf5b211147ca53536259f2 100644 --- a/nomad/api/app.py +++ b/nomad/api/app.py @@ -31,6 +31,21 @@ from nomad import config, utils base_path = config.services.api_base_path """ Provides the root path of the nomad APIs. """ + +@property +def specs_url(self): + """ + Fixes issue where swagger-ui makes a call to swagger.json over HTTP. + This can ONLY be used on servers that actually use HTTPS. On servers that use HTTP, + this code should not be used at all. + """ + return flask.url_for(self.endpoint('specs'), _external=True, _scheme='https') + + +if config.services.https: + Api.specs_url = specs_url + + app = Flask( __name__, static_url_path='/docs', diff --git a/nomad/api/upload.py b/nomad/api/upload.py index acfa3a8c50ead256e1b9489c422e32b75fc04913..5348ab3fb6baea2b52b1a24f1a4bc01871c7e753 100644 --- a/nomad/api/upload.py +++ b/nomad/api/upload.py @@ -392,10 +392,7 @@ class UploadCommandResource(Resource): @login_really_required def get(self): """ Get url and example command for shell based uploads. """ - upload_url = 'http://%s:%s%s/uploads/' % ( - config.services.api_host, - config.services.api_port, - config.services.api_base_path) + upload_url = '%s/uploads' % config.api_url() upload_command = 'curl -X PUT -H "X-Token: %s" "%s" -F file=@<local_file>' % ( g.user.get_auth_token().decode('utf-8'), upload_url) diff --git a/nomad/config.py b/nomad/config.py index 2ff76cee40aeaefa4635ccfa03caa9a96915d7dd..6422bba105954bf3d710c734bf8c26645a22f61e 100644 --- a/nomad/config.py +++ b/nomad/config.py @@ -108,7 +108,8 @@ services = NomadConfig( api_secret='defaultApiSecret', admin_password='password', disable_reset=True, - not_processed_value='not processed' + not_processed_value='not processed', + https=False ) tests = NomadConfig( @@ -116,8 +117,12 @@ tests = NomadConfig( ) -def upload_url(): - return 'http://%s:%s/%s/uploads' % (services.api_host, services.api_port, services.api_base_path[:-3]) +def api_url(): + return '%s://%s%s/%s' % ( + 'https' if services.https else 'http', + services.api_host, + ':%s' % services.api_port if services.api_port != 80 else '', + services.api_base_path) migration_source_db = NomadConfig( diff --git a/nomad/processing/data.py b/nomad/processing/data.py index 933c9b93d12d29fa0559f57576882d0251d72ef7..e3aafb994e20a32b6286cb1c26078f32965e2249 100644 --- a/nomad/processing/data.py +++ b/nomad/processing/data.py @@ -645,7 +645,7 @@ class Upload(Proc): '', 'your data %suploaded %s has completed processing.' % ( self.name if self.name else '', self.upload_time.isoformat()), - 'You can review your data on your upload page: %s' % config.upload_url() + 'You can review your data on your upload page: %s/uploads' % config.api_url()[:-3] ]) try: infrastructure.send_mail( diff --git a/ops/helm/nomad/templates/api-deployment.yaml b/ops/helm/nomad/templates/api-deployment.yaml index 1864cef8e3ce0698a1e80eb3dcc3f9bcdc08eb49..8d0b59d3e03b31d32cf48171d4829af2dc7898c2 100644 --- a/ops/helm/nomad/templates/api-deployment.yaml +++ b/ops/helm/nomad/templates/api-deployment.yaml @@ -8,45 +8,47 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} data: + gunicorn.conf: | + secure_scheme_headers = {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'} gunicorn.log.conf: | [loggers] keys=root, gunicorn.error, gunicorn.access - + [handlers] keys=console, access, error - + [formatters] keys=generic - + [logger_root] level=INFO handlers=console - + [logger_gunicorn.error] level=INFO handlers=error qualname=gunicorn.error - + [logger_gunicorn.access] level=INFO handlers=access qualname=gunicorn.access - + [handler_console] class=StreamHandler formatter=generic args=(sys.stdout, ) - + [handler_access] class=StreamHandler formatter=generic args=(sys.stdout, ) - + [handler_error] class=StreamHandler formatter=generic args=(sys.stdout, ) - + [formatter_generic] format=%(asctime)s [%(process)d] [%(levelname)s] %(message)s datefmt=%Y-%m-%d %H:%M:%S @@ -83,6 +85,9 @@ spec: - mountPath: /app/gunicorn.log.conf name: gunicorn-log-conf subPath: gunicorn.log.conf + - mountPath: /app/gunicorn.conf + name: gunicorn-conf + subPath: gunicorn.conf - mountPath: /app/.volumes/fs/public name: public-volume - mountPath: /app/.volumes/fs/staging @@ -96,7 +101,7 @@ spec: value: "{{ .Values.api.console_loglevel }}" - name: NOMAD_LOGSTASH_LEVEL value: "{{ .Values.api.logstash_loglevel }}" - command: ["python", "-m", "gunicorn.app.wsgiapp", "--timeout", "3600", "--log-config", "gunicorn.log.conf", "-w", "{{ .Values.api.worker }}", "-b 0.0.0.0:8000", "nomad.api:app"] + command: ["python", "-m", "gunicorn.app.wsgiapp", "--timeout", "3600", "--config", "gunicorn.conf", "--log-config", "gunicorn.log.conf", "-w", "{{ .Values.api.worker }}", "-b 0.0.0.0:8000", "nomad.api:app"] livenessProbe: httpGet: path: "{{ .Values.proxy.external.path }}/api/alive" @@ -118,6 +123,9 @@ spec: - name: gunicorn-log-conf configMap: name: {{ include "nomad.fullname" . }}-api-gunicorn-log-config + - name: gunicorn-conf + configMap: + name: {{ include "nomad.fullname" . }}-api-gunicorn-config - name: nomad-conf configMap: name: {{ include "nomad.fullname" . }}-configmap diff --git a/ops/helm/nomad/templates/nomad-configmap.yml b/ops/helm/nomad/templates/nomad-configmap.yml index 08775d10c4dd6d606902def70bbaac37cf7e8539..445db2e3e8a9a17dfc20513c688d9299596b8c23 100644 --- a/ops/helm/nomad/templates/nomad-configmap.yml +++ b/ops/helm/nomad/templates/nomad-configmap.yml @@ -24,6 +24,7 @@ data: api_secret: "{{ .Values.api.secret }}" admin_password: "{{ .Values.api.adminPassword }}" disable_reset: {{ .Values.api.disableReset }} + https: {{ .Values.api.https }} rabbitmq: host: "{{ .Release.Name }}-rabbitmq" elastic: diff --git a/ops/helm/nomad/values.yaml b/ops/helm/nomad/values.yaml index 9c3c9a802ae721d0dd2cd0fd0fce69614ab8d8f1..50ff57690fc5873330c32b5d7d0525384a040dbf 100644 --- a/ops/helm/nomad/values.yaml +++ b/ops/helm/nomad/values.yaml @@ -27,9 +27,11 @@ images: ## Everthing concerning the nomad api api: replicas: 1 + https: true ## Number of gunicorn worker. Recommendation is 2xnum_cores+1 worker: 10 - port: 8000 + ## The external port to connect to the api + port: 80 console_loglevel: INFO logstash_loglevel: INFO ## Secret used as cryptographic seed