diff --git a/Angular2/angular.json b/Angular2/angular.json index 4e53047aa..87f8c907e 100644 --- a/Angular2/angular.json +++ b/Angular2/angular.json @@ -141,8 +141,8 @@ } } }, - "defaultProject": "Angular2", +// "defaultProject": "Angular2", "cli": { "analytics": false } -} \ No newline at end of file +} diff --git a/Angular2/src/app/pages/labs/view/view.component.ts b/Angular2/src/app/pages/labs/view/view.component.ts index a9c6526b5..0d5f8c578 100644 --- a/Angular2/src/app/pages/labs/view/view.component.ts +++ b/Angular2/src/app/pages/labs/view/view.component.ts @@ -109,7 +109,7 @@ export class LabViewComponent implements OnInit Swal.queue([ { title: 'Lab deployment URL', - text: this.lab, + html: '' + this.lab + '', confirmButtonText: 'Close', confirmButtonColor: '#8184B2', showLoaderOnConfirm: true, diff --git a/Docker/alpine-cloud/api/Dockerfile b/Docker/alpine-cloud/api/Dockerfile index 6bb50ff34..95b3b0a84 100644 --- a/Docker/alpine-cloud/api/Dockerfile +++ b/Docker/alpine-cloud/api/Dockerfile @@ -5,7 +5,7 @@ # base image FROM python:3.7-slim-stretch -LABEL maintainer="glenn.ten.cate@owasp.org" +RUN echo "deb http://archive.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list RUN apt-get update &&\ apt-get install -y --no-install-recommends \ @@ -25,26 +25,30 @@ RUN groupadd --gid 1000 user_api && useradd --uid 1000 --gid user_api -m user_ap WORKDIR /home/user_api USER user_api -RUN mkdir .kube .config .config/pip +RUN mkdir .kube .config .config/pip /home/user_api/.local /home/user_api/.local/bin + +ENV PATH="$PATH:/home/user_api/.local/bin" RUN echo "[global]\nextra-index-url=https://www.piwheels.org/simple" >> .config/pip/pip.conf -RUN pip3 install --upgrade pip --no-cache-dir &&\ - pip3 install --user nltk --no-cache-dir &&\ - pip3 install --user cython --no-cache-dir +RUN pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --upgrade pip --no-cache-dir +RUN pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user nltk --no-cache-dir +RUN pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user cython --no-cache-dir # Enrich ntlk data sets RUN python3 -m nltk.downloader punkt stopwords # Magic below for PI docker image speeding up -RUN if [ `ps auwxf | grep qemu-arm | wc -l` = 4 ]; \ -then \ - pip3 install --user numpy==1.19.0rc2 scipy==1.5.0rc2 --no-cache-dir; \ -else \ - pip3 install --user numpy scipy --no-cache-dir; \ -fi +#RUN if [ `ps auwxf | grep qemu-arm | wc -l` = 4 ]; \ +#then \ +# pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user numpy==1.19.0rc2 scipy==1.5.0rc2 --no-cache-dir; \ +#else \ +# pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user numpy scipy --no-cache-dir; \ +#fi + +RUN pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user numpy scipy --no-cache-dir # Intall packages from requirements.txt COPY --chown=user_api:user_api ./requirements.txt /home/user_api/requirements.txt -RUN pip3 install --user -r requirements.txt --no-cache-dir +RUN pip3 install --trusted-host www.piwheels.org --trusted-host pypi.org --trusted-host pypi.python.org --user -r requirements.txt --no-cache-dir COPY --chown=user_api:user_api ./Docker/alpine-cloud/api/entrypoint.sh /home/user_api/entrypoint.sh diff --git a/Docker/alpine-cloud/api/skf-api.sh b/Docker/alpine-cloud/api/skf-api.sh index b7a29ef29..79bd4fdb1 100755 --- a/Docker/alpine-cloud/api/skf-api.sh +++ b/Docker/alpine-cloud/api/skf-api.sh @@ -9,11 +9,11 @@ then export KUBECONFIG=/home/user_api/.kube/config fi -if [ "$GOOGLE_CREDENTIALS" -gt 10 ] -then - echo $GOOGLE_CREDENTIALS | base64 -d > /home/user_api/.kube/gsa-key.json - export GOOGLE_APPLICATION_CREDENTIALS=/home/user_api/.kube/gsa-key.json -fi +#if [ "$GOOGLE_CREDENTIALS" -gt 10 ] +#then +# echo $GOOGLE_CREDENTIALS | base64 -d > /home/user_api/.kube/gsa-key.json +# export GOOGLE_APPLICATION_CREDENTIALS=/home/user_api/.kube/gsa-key.json +#fi #to get the base64 string of your .kube/config run: #cat ~/.kube/config | base64 @@ -26,4 +26,4 @@ export PYTHONPATH=. /home/user_api/.local/bin/flask initdb # Start the SKF Python API -/home/user_api/.local/bin/gunicorn --bind 0.0.0.0:8888 --workers=6 --threads=3 wsgi:app \ No newline at end of file +/home/user_api/.local/bin/gunicorn --bind 0.0.0.0:8888 --workers=6 --threads=3 wsgi:app diff --git a/README.md b/README.md index 7918dd4cf..cc139d69c 100755 --- a/README.md +++ b/README.md @@ -1,9 +1,32 @@ -# OLD and archived Security Knowledge Framework +# OWASP Security Knowledge Framework +[![SKF Logo](https://github.com/blabla1337/skf-www/blob/master/images/site-skf/logo_github.png?raw=true)](https://www.securityknowledgeframework.org/) -Please note that this is the archived version of SKF, we are busy building a brand new Security Knowledge Framework. For more updates please visit this github repo: -- **https://github.com/Security-Knowledge-Framework/Platform** -- **https://github.com/Security-Knowledge-Framework/SKF-requirements-tool** -- **https://github.com/Security-Knowledge-Framework/Labs** +
Project status details:
+[![Build Travis CI main](https://travis-ci.org/blabla1337/skf-flask.svg?branch=main)](https://travis-ci.org/blabla1337/skf-flask) +[![Join the chat at https://gitter.im/Security-Knowledge-Framework/Lobby](https://badges.gitter.im/Security-Knowledge-Framework/Lobby.svg)](https://gitter.im/Security-Knowledge-Framework/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Join the chat at https://owasp.slack.com/messages/C0F7L9X6V](https://img.shields.io/badge/chat-on%20slack-blueviolet)](https://owasp.slack.com/messages/C0F7L9X6V) +[![OWASP Flagship](https://img.shields.io/badge/owasp-flagship%20project-orange.svg)](https://www.owasp.org/index.php/OWASP_Security_Knowledge_Framework) +[![OSSF Working group: Best Practices for Open Source Developers](https://img.shields.io/badge/openssf-Learning%20Platform%20Project-orange.svg)](https://openssf.org) + +
Quality testing:
+[![Known Vulnerabilities](https://snyk.io/test/github/blabla1337/skf-flask/badge.svg)](https://snyk.io/test/github/blabla1337/skf-flask) +[![Coverage Status](https://coveralls.io/repos/blabla1337/skf-flask/badge.svg?branch=main)](https://coveralls.io/repos/blabla1337/skf-flask/badge.svg?branch=main) +[![Requirements Status](https://requires.io/github/blabla1337/skf-flask/requirements.svg?branch=main)](https://requires.io/github/blabla1337/skf-flask/requirements/?branch=main) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/133/badge)](https://bestpractices.coreinfrastructure.org/projects/133) + +The OWASP Security Knowledge Framework is an open source web application that explains secure coding principles in multiple programming languages. The goal of OWASP-SKF is to help you learn and integrate security by design in your software development and build applications that are secure by design. OWASP-SKF does this through manageable software development projects with checklists (using OWASP-ASVS/OWASP-MASVS or custom security checklists) and labs to practice security verification (using SKF-Labs, OWASP Juice-shop, and best practice code examples from SKF and the OWASP-Cheatsheets). + +## Table of Contents +* [Introduction](#introduction) +* [Installing](#installing) +* [Updating Database](#updating-db) +* [Updating Chatbot](#updating-dataset) +* [Usage](#usage) +* [CI-Pipeline](#ci-pipeline) +* [Development / Contributing](CONTRIBUTING.md) +* [Scrum Board](#scrum-board) +* [License](#license) +* [Contributors](#contributors) ## Introduction @@ -15,6 +38,108 @@ Because of this we decided to develop a framework in order to create a guide-sys [![SKF Flow](https://raw.githubusercontent.com/blabla1337/skf-www/master/images/site-skf/skf_flow.gif)](https://www.securityknowledgeframework.org/) +## Installing + +### [Kubernetes installation how to](installations/Kubernetes) +### [Docker-compose local how to](installations/docker) +### [SKF K8s Raspberry pi cluster how to](installations/pi-cluster) +### [SKF Chatbot installation how to](https://github.com/blabla1337/skf-bot) +### [Bare metal / on premise installation how to DEPRECATED](installations/local) + +## Updating Database + +There is a method available to update the content of the SKF application. + +When you have modified or created new Knowledge base items, code examples or checklist you need to run the following commands in the SKF root directory: +``` +export FLASK_APP=skf/app.py +export PYTHONPATH=.:$PYTHONPATH +flask updatedb +``` + +## Updating chatbot + +There is a method available to update the dataset of the SKF chatbot application. + +When you have modified or created new Knowledge base items, code examples or checklist you need to run the following commands in the SKF root directory: +``` +export FLASK_APP=skf/app.py +export PYTHONPATH=.:$PYTHONPATH +flask initdataset +``` + +## Usage + +For more detailed information such as setting up an admin account and user guides please see the extended documentation that can be found below: + +[Readme: extended documentation](https://skf.readme.io/) + +## CI-Pipeline + +### Travis-ci.org: +``` +Test and Deploy with Confidence. Easily sync your GitHub projects with Travis CI and you'll be testing your code in minutes! +SKF Build details: +``` +https://travis-ci.org/blabla1337/skf-flask + +### Coveralls.io Python: +``` +DELIVER BETTER CODE. We help developers deliver code confidently by showing which parts of your code aren't covered by your test suite. +SKF Coveralls details: +``` +https://coveralls.io/r/blabla1337/skf-flask + +### codecov.io for Angular: +``` +Code coverage done right. Highly integrated with GitHub, Bitbucket and GitLab. +SKF codecov details: +``` +https://codecov.io/gh/blabla1337/skf-flask + +### Requires.io pip packages: +``` +Stay Up-to-date! Stay secure! Requires.io monitors your Python projects dependencies, and notify you whenever any of your dependency is out-of-date. +SKF Requires details: +``` +https://requires.io/github/blabla1337/skf-flask/requirements/ + +### uptimerobot.com: +``` +Monitor HTTP(s), Ping, Port and check Keywords. Get alerted via e-mail, SMS, Twitter, web-hooks or push. View uptime, downtime and response times. +``` + +### ssllabs.com & sslbadge.org: +``` +ssllabs.org: +Bringing you the best SSL/TLS and PKI testing tools and documentation. + +sslbadge.org: +Creates a nice badge for your website SSL/TLS security settings based on the Qualys SSL Labs testing. +``` +[![SSL Rating](http://sslbadge.org/?domain=securityknowledgeframework.org)](https://www.ssllabs.com/ssltest/analyze.html?d=securityknowledgeframework.org) + + +## License + Copyright (C) 2021 Glenn ten Cate, Riccardo ten Cate + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +### OWASP: + +* [Owasp](http://owasp.com/index.php/Main_Page) +Licensed under the [creative commons](http://creativecommons.org/licenses/by-nd/3.0/nl/) license ## Contributors - [Imanuel Febie](https://github.com/tuffgniuz) diff --git a/requirements.txt b/requirements.txt index 4d6362b05..9a98b2f1e 100755 --- a/requirements.txt +++ b/requirements.txt @@ -12,8 +12,8 @@ Flask-SQLAlchemy==2.5.1 google-api-python-client==2.0.2 google-auth==1.28.0 google-auth-httplib2==0.1.0 +itsdangerous==2.0.1 Jinja2==2.11.3 -kubernetes==12.0.1 MarkupSafe==1.1.1 #pandas==1.0.5 pika==1.1.0 @@ -29,3 +29,5 @@ selenium==3.141.0 SQLAlchemy==1.3.23 Werkzeug==0.16.1 gunicorn==20.0.4 +kubernetes==27.2.0 + diff --git a/skf/rabbit_mq_workers/common.py b/skf/rabbit_mq_workers/common.py index 9f4aeabea..2bfe134bc 100644 --- a/skf/rabbit_mq_workers/common.py +++ b/skf/rabbit_mq_workers/common.py @@ -1,64 +1,71 @@ +import logging.config from sys import stderr from kubernetes import client, config +from skf import settings + +logging.config.fileConfig('logging.conf') +log = logging.getLogger(__name__) + + def delete_all(instance_name, user_id): delete_ingress(instance_name, user_id) delete_service(instance_name, user_id) delete_deployment(instance_name, user_id) - delete_namespace(user_id) +# delete_namespace(user_id) def delete_deployment(instance_name, user_id): try: config.load_kube_config() api_instance = client.AppsV1Api() api_response = api_instance.delete_namespaced_deployment( - name=instance_name, - namespace=user_id, + name=instance_name+'-'+user_id, + namespace=settings.SKF_LABS_NAMESPACE, body=client.V1DeleteOptions( propagation_policy='Foreground', grace_period_seconds=5)) - #print("Deployment deleted. status='%s'" % str(api_response.status)) + print("Deployment deleted. status='%s'" % str(api_response.status)) except: print('Error deleting deployment') -def delete_namespace(user_id): - try: - config.load_kube_config() - api_instance = client.CoreV1Api() - api_response = api_instance.delete_namespace( - name=user_id, - body=client.V1DeleteOptions( - propagation_policy='Foreground', - grace_period_seconds=5)) - #print("Namespace deleted. status='%s'" % str(api_response.status)) - except: - print('Error deleting namespace') +#def delete_namespace(user_id): +# try: +# config.load_kube_config() +# api_instance = client.CoreV1Api() +# api_response = api_instance.delete_namespace( +# name=user_id, +# body=client.V1DeleteOptions( +# propagation_policy='Foreground', +# grace_period_seconds=5)) +# print("Namespace deleted. status='%s'" % str(api_response.status)) +# except: +# print('Error deleting namespace') def delete_service(instance_name, user_id): try: config.load_kube_config() api_instance = client.CoreV1Api() api_response = api_instance.delete_namespaced_service( - name=instance_name, - namespace=user_id, + name=instance_name+'-'+user_id, + namespace=settings.SKF_LABS_NAMESPACE, body=client.V1DeleteOptions( propagation_policy='Foreground', grace_period_seconds=5)) - #print("Deployment deleted. status='%s'" % str(api_response.status)) + print("Service deleted. status='%s'" % str(api_response.status)) except: print('Error deleting service') def delete_ingress(instance_name, user_id): try: config.load_kube_config() - networking_v1_beta1_api = client.NetworkingV1beta1Api() - api_response = networking_v1_beta1_api.delete_namespaced_ingress( - name='ingress-'+instance_name, - namespace=user_id, + networking_v1_api = client.NetworkingV1Api() + api_response = networking_v1_api.delete_namespaced_ingress( + name='ingress-'+instance_name+'-'+user_id, + namespace=settings.SKF_LABS_NAMESPACE, body=client.V1DeleteOptions( propagation_policy='Foreground', grace_period_seconds=5)) - #print("Ingress deleted. status='%s'" % str(api_response.status)) + print("Ingress deleted. status='%s'" % str(api_response.status)) except: print('Error deleting ingress (this may not exist, that ok') diff --git a/skf/rabbit_mq_workers/deployment-worker.py b/skf/rabbit_mq_workers/deployment-worker.py index 3c6f0c992..0657f8eb4 100644 --- a/skf/rabbit_mq_workers/deployment-worker.py +++ b/skf/rabbit_mq_workers/deployment-worker.py @@ -1,10 +1,15 @@ #!/usr/bin/env python -import os, pika, random, re, time +import logging.config, os, pika, random, re, time from skf import settings from kubernetes import client, config from sys import stderr + +logging.config.fileConfig('logging.conf') +log = logging.getLogger(__name__) + + creds = pika.PlainCredentials('admin', 'admin-skf-secret') connection = pika.BlockingConnection(pika.ConnectionParameters( host=settings.RABBIT_MQ_CONN_STRING, @@ -13,6 +18,8 @@ channel = connection.channel() channel.queue_declare(queue='deployment_qeue') +labs_namespace = settings.SKF_LABS_NAMESPACE + labs_domain = os.environ['SKF_LABS_DOMAIN'] subdomain_deploy = os.environ.get('SKF_LABS_DEPLOY_MODE') == 'subdomain' if subdomain_deploy: @@ -26,93 +33,95 @@ def deploy_container(rpc_body): user_id = string_split_user_id(rpc_body) deployment = string_split_deployment(rpc_body) - create_user_namespace(user_id) - deployment_object = create_deployment_object(deployment) - create_deployment(deployment_object, user_id) + create_labs_namespace(labs_namespace) + deployment_object = create_deployment_object(deployment, user_id) + create_deployment(deployment_object, labs_namespace, user_id) try: - service_port = create_service_for_deployment(deployment, user_id) + service_port = create_service_for_deployment(deployment, labs_namespace, user_id) except Exception as ex: - print('Error creating service:', ex, file=stderr) + log.error(ex) return {'message': 'Failed to deploy, error K8s API create service call!'} time.sleep(15) - response = get_service_exposed_ip(deployment, user_id) + response = get_service_exposed_ip(deployment, labs_namespace, user_id) if subdomain_deploy: - hostname = '{}-{}.{}'.format(deployment, user_id, labs_domain) - networking_v1_beta1_api = client.NetworkingV1beta1Api() - ingress_err = create_ingress(networking_v1_beta1_api, hostname, deployment, service_port, user_id) + hostname = '{}-{}-{}'.format(deployment, user_id, labs_domain) + networking_v1_api = client.NetworkingV1Api() + ingress_err = create_ingress(networking_v1_api, hostname, deployment, service_port, labs_namespace, user_id) if ingress_err is not None: return { 'message': ingress_err } return { 'message': "'" + labs_protocol + hostname + "'" } else: return get_host_port_from_response(response) -def create_user_namespace(user_id): +def create_labs_namespace(namespace): try: config.load_kube_config() api_instance = client.CoreV1Api() body = client.V1Namespace() - body.metadata = client.V1ObjectMeta(name=user_id) + body.metadata = client.V1ObjectMeta(name=namespace) api_response = api_instance.create_namespace(body) except: return {'message': 'Failed to deploy, error namespace creation!'} -def create_deployment_object(deployment): +def create_deployment_object(deployment, user_id): try: # Configureate Pod template container container = client.V1Container( - name=deployment, + name=deployment + '-' + user_id, image="blabla1337/owasp-skf-lab:"+deployment, ports=[client.V1ContainerPort(container_port=5000)]) # Create and configurate a spec section template = client.V1PodTemplateSpec( - metadata=client.V1ObjectMeta(labels={"app": deployment}), + metadata=client.V1ObjectMeta(labels={"app": deployment + "-" + user_id}), spec=client.V1PodSpec(containers=[container])) # Create the specification of deployment spec = client.V1DeploymentSpec( replicas=1, template=template, - selector={'matchLabels': {'app': deployment}}) + selector={'matchLabels': {'app': deployment+"-"+user_id}}) # Instantiate the deployment object deployment = client.V1Deployment( api_version="apps/v1", kind="Deployment", - metadata=client.V1ObjectMeta(name=deployment), + metadata=client.V1ObjectMeta(name=deployment+"-"+user_id), spec=spec) return deployment except: return {'message': 'Failed to deploy, error creation deployment object!'} -def create_deployment(deployment, user_id): +def create_deployment(deployment, namespace, user_id): try: config.load_kube_config() k8s_apps_v1 = client.AppsV1Api() - response = k8s_apps_v1.create_namespaced_deployment(body=deployment, namespace=user_id) + response = k8s_apps_v1.create_namespaced_deployment(body=deployment, namespace=namespace) return response except: return {'message': 'Failed to deploy, error K8s API create call!'} -def create_service_for_deployment(deployment, user_id): +def create_service_for_deployment(deployment, namespace, user_id): config.load_kube_config() api_instance = client.CoreV1Api() service = client.V1Service() service.api_version = "v1" service.kind = "Service" - service.metadata = client.V1ObjectMeta(name=deployment) + service.metadata = client.V1ObjectMeta(name=deployment + "-" + user_id) + spec = client.V1ServiceSpec() spec.type = "NodePort" - spec.selector = {"app": deployment} + spec.selector = {"app": deployment + "-" + user_id} # Why a random port? random_port = random.randrange(40000, 60000) spec.ports = [client.V1ServicePort(protocol="TCP", port=random_port, target_port=5000)] service.spec = spec - response = api_instance.create_namespaced_service(namespace=user_id, body=service) + + response = api_instance.create_namespaced_service(namespace=namespace, body=service) return random_port -def get_service_exposed_ip(deployment, user_id): +def get_service_exposed_ip(deployment, namespace, user_id): try: config.load_kube_config() api_instance = client.CoreV1Api() - response = api_instance.read_namespaced_service(deployment, user_id, pretty=True) + response = api_instance.read_namespaced_service(deployment+"-"+user_id, namespace, pretty=True) return response except: return {'message': 'Failed to deploy, error service no exposed IP!'} @@ -163,24 +172,27 @@ def on_request(ch, method, props, body): body=str(response)) ch.basic_ack(delivery_tag=method.delivery_tag) -def create_ingress(networking_v1_beta1_api, hostname, deployment, service_port, user_id): +def create_ingress(networking_v1_api, hostname, deployment, service_port, namespace, user_id): try: - body = client.NetworkingV1beta1Ingress( - api_version="networking.k8s.io/v1beta1", + body = client.V1Ingress( + api_version="networking.k8s.io/v1", kind="Ingress", - metadata=client.V1ObjectMeta(name="ingress-"+deployment, annotations={ + metadata=client.V1ObjectMeta(name="ingress-"+deployment+"-"+user_id, annotations={ "kubernetes.io/ingress.class": "nginx", #"nginx.ingress.kubernetes.io/rewrite-target": "/", }), - spec=client.NetworkingV1beta1IngressSpec( - rules=[client.NetworkingV1beta1IngressRule( + spec=client.V1IngressSpec( + rules=[client.V1IngressRule( host=hostname, - http=client.NetworkingV1beta1HTTPIngressRuleValue( - paths=[client.NetworkingV1beta1HTTPIngressPath( + http=client.V1HTTPIngressRuleValue( + paths=[client.V1HTTPIngressPath( path="/", - backend=client.NetworkingV1beta1IngressBackend( - service_port=service_port, - service_name=deployment) + path_type="Prefix", + backend=client.V1IngressBackend( + service = client.V1IngressServiceBackend( + port=client.V1ServiceBackendPort(number=service_port), + name=deployment+"-"+user_id) + ) )] ) )] @@ -188,13 +200,14 @@ def create_ingress(networking_v1_beta1_api, hostname, deployment, service_port, ) # Creation of the Deployment in specified namespace # (Can replace "default" with a namespace you may have created) - networking_v1_beta1_api.create_namespaced_ingress( - namespace=user_id, + networking_v1_api.create_namespaced_ingress( + namespace=namespace, body=body ) return None except Exception as ex: print('Error creating ingress:', ex, file=stderr) + log.error(ex) return 'Failed to create ingress!' channel.basic_qos(prefetch_count=1) diff --git a/skf/settings.py b/skf/settings.py index 063e73220..0816072a1 100755 --- a/skf/settings.py +++ b/skf/settings.py @@ -11,6 +11,8 @@ SKF_API_URL = os.environ.get("SKF_API_URL") or "https://beta.securityknowledgeframework.org/api/" ORIGINS = '*' +SKF_LABS_NAMESPACE = os.environ.get("SKF_LABS_NAMESPACE") or "skflabs" + # Flask-Restplus settings RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list' RESTPLUS_VALIDATE = True @@ -48,4 +50,4 @@ RABBITMQ_DEFAULT_PASS = os.environ.get("RABBITMQ_DEFAULT_PASS") or 'guest' # SKF-LABS settings -LABS_KUBE_CONF = os.environ.get("LABS_KUBE_CONF") or '~/.kube/config' \ No newline at end of file +LABS_KUBE_CONF = os.environ.get("LABS_KUBE_CONF") or '~/.kube/config'