aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormrichomme <morgan.richomme@orange.com>2020-04-20 14:50:27 +0200
committermrichomme <morgan.richomme@orange.com>2020-04-20 14:50:27 +0200
commit5de622a8247c4cf4fc2bd4e5f8a947e60a8c4bfb (patch)
tree2038bfaa94413367fd46e8bcd38600f2e49dac05
parent3c64be99c3c24930674e9fa657993d95cbd2fe6d (diff)
Resync integration/xtesting repo
Issue-ID: INT-1366 Signed-off-by: mrichomme <morgan.richomme@orange.com> Change-Id: I3af9c4697f0e67d3ce5b6d2fceeb978aeb20a0ff
-rw-r--r--healthcheck/docker/Dockerfile10
-rw-r--r--infra-healthcheck/README.md32
-rw-r--r--infra-healthcheck/docker/Dockerfile7
-rw-r--r--infra-healthcheck/docker/logging.debug.ini70
-rw-r--r--infra-healthcheck/docker/logging.ini70
-rw-r--r--infra-healthcheck/docker/testcases.yaml12
-rw-r--r--infra-healthcheck/infra_healthcheck/k8stest.py21
-rw-r--r--infra-healthcheck/requirements.txt3
-rw-r--r--infra-healthcheck/setup.cfg3
-rw-r--r--infra-healthcheck/upper-constraints.txt1
-rw-r--r--security/README.md76
-rw-r--r--security/docker/Dockerfile58
-rw-r--r--security/docker/testcases.yaml64
-rw-r--r--security/onap_security/__init__.py0
-rw-r--r--security/onap_security/security_tests.py173
-rw-r--r--security/onap_security/test_security_test.py40
-rw-r--r--security/requirements.txt12
-rw-r--r--security/scripts/check_cis_kubernetes.sh25
-rw-r--r--security/scripts/check_security_root.sh76
-rw-r--r--security/scripts/check_unlimitted_pods.sh28
-rw-r--r--security/scripts/root_pods_xfail.txt33
-rw-r--r--security/setup.cfg16
-rw-r--r--security/setup.py29
-rw-r--r--smoke-usecases-robot/docker/Dockerfile12
24 files changed, 826 insertions, 45 deletions
diff --git a/healthcheck/docker/Dockerfile b/healthcheck/docker/Dockerfile
index 6496a70..bcaf378 100644
--- a/healthcheck/docker/Dockerfile
+++ b/healthcheck/docker/Dockerfile
@@ -1,4 +1,4 @@
-FROM opnfv/xtesting
+FROM opnfv/xtesting:jerma
ARG OPENSTACK_TAG=master
ARG OPNFV_TAG=master
@@ -9,7 +9,7 @@ ENV PYTHONPATH $PYTHONPATH:/src/testing-utils/robotframework-onap/eteutils
ENV TAG all
COPY requirements.txt requirements.txt
-RUN apk --no-cache add --update openssl && \
+RUN apk --no-cache add --update openssl chromium chromium-chromedriver && \
apk --no-cache add --virtual .build-deps --update \
python3-dev build-base linux-headers libffi-dev \
openssl-dev libjpeg-turbo-dev && \
@@ -28,12 +28,12 @@ RUN apk --no-cache add --update openssl && \
mkdir -p /var/opt/ONAP/demo/heat && cp -Rf /src/demo/heat/vFW /var/opt/ONAP/demo/heat/ && \
mkdir -p /demo/service_mapping && cp -Rf /src/demo/service_mapping /demo/ && \
mkdir -p /var/opt/ONAP/demo/preload_data && cp -Rf /src/demo/preload_data /var/opt/ONAP/demo/ && \
- ln -s /usr/lib/python3.8/site-packages/vcpeutils /usr/lib/python3.8/site-packages/SoUtils && \
- ln -s /usr/lib/python3.8/site-packages/heatbridge /usr/lib/python3.8/site-packages/HeatBridge && \
+ ln -s /usr/lib/python3.7/site-packages/vcpeutils /usr/lib/python3.7/site-packages/SoUtils && \
+ ln -s /usr/lib/python3.7/site-packages/heatbridge /usr/lib/python3.7/site-packages/HeatBridge && \
rm -r requirements.txt /var/opt/ONAP/.git /src/demo && \
cd / && ln -s /var/opt/ONAP/robot/ /robot && \
apk del .build-deps
-COPY docker/testcases.yaml /usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml
+COPY docker/testcases.yaml /usr/lib/python3.7/site-packages/xtesting/ci/testcases.yaml
COPY scripts/cmd.sh /
CMD ["/cmd.sh"]
diff --git a/infra-healthcheck/README.md b/infra-healthcheck/README.md
index ba873af..231ff88 100644
--- a/infra-healthcheck/README.md
+++ b/infra-healthcheck/README.md
@@ -12,6 +12,8 @@ It includes 2 tests:
are up&running
* onap-helm: list the helm charts. The success criteria is all the helm charts
are completed.
+* nodeport_ingress: check that we have a 1:1 corresdpondance between nodeports
+ and ingress (run only when the env variable DEPLOY_SCENARIO includes ingress)
## Usage
@@ -21,7 +23,7 @@ Mandatory:
* The kubernetes configuration: usually hosted on the.kube/config of your
jumphost. It corresponds the kubernetes credentials and are needed to perform
- the different operations. This file shall be copied in /config/.kube/config in
+ the different operations. This file shall be copied in /root/.kube/config in
the docker.
Optional:
@@ -35,9 +37,9 @@ Optional:
You can run this docker by typing:
```
-docker run -v <the kube config>:/config/.kube/config -v
+docker run -v <the kube config>:/root/.kube/config -v
<result directory>:/var/lib/xtesting/results
-registry.gitlab.com/orange-opensource/lfn/onap/integration/xtesting:latest
+registry.gitlab.com/orange-opensource/lfn/onap/integration/xtesting/infra-healthcheck:latest
```
Options:
@@ -46,9 +48,9 @@ Options:
specify the -r option in the command line. Please note that in this case, you
must precise some env variables.
-environement variables:
+environment variables:
-* Mandatory:
+* Mandatory (if you want to report the results in the database):
* TEST_DB_URL: the url of the target Database with the env variable .
* NODE_NAME: the name of your test environement. It must be declared in the
test database (e.g. windriver-SB00)
@@ -58,22 +60,26 @@ environement variables:
* BUILD_TAG: a unique tag of your CI system. It can be usefull to get all the
tests of one CI run. It uses the regex (dai|week)ly-(.+?)-[0-9]* to find the
version (e.g. daily-elalto-123456789).
+ * DEPLOY_SCENARIO: your scenario deployment. ingress test run only if the
+ scenario includes 'ingress'
The command becomes:
```
-docker run -v <the kube config>:/config/.kube/config -v
+docker run -v <the kube config>:/root/.kube/config -v
<result directory>:/var/lib/xtesting/results registry.gitlab.com/orange-opensour
-ce/lfn/onap/integration/xtesting:latest /bin/bash -c "run_tests -r -t all
+ce/lfn/onap/integration/xtesting/infra-healthcheck:latest:latest /bin/bash -c "
+run_tests -r -t all
```
### Output
```
-+------------+-------------+-------------------+----------+--------+
-| TEST CASE | PROJECT | TIER | DURATION | RESULT |
-+------------+-------------+-------------------+----------+--------+
-| onap-k8s | integration | infra-healthcheck | 00:06 | PASS |
-| onap-helm | integration | infra-healthcheck | 00:01 | PASS |
-+------------+-------------+-------------------+----------+--------+
++------------------+-------------+-------------------+----------+--------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++------------------+-------------+-------------------+----------+--------+
+| onap-k8s | integration | infra-healthcheck | 00:06 | PASS |
+| onap-helm | integration | infra-healthcheck | 00:01 | PASS |
+| nodeport_ingress | security | security | 00:01 | FAIL |
++------------------+-------------+-------------------+----------+--------+
```
diff --git a/infra-healthcheck/docker/Dockerfile b/infra-healthcheck/docker/Dockerfile
index 849268c..07b417b 100644
--- a/infra-healthcheck/docker/Dockerfile
+++ b/infra-healthcheck/docker/Dockerfile
@@ -3,6 +3,7 @@ FROM opnfv/xtesting
ARG KUBERNETES_VERSION="v1.15.2"
ARG HELM_VERSION="v2.14.1"
ARG ONAP_TESTS_TAG=master
+ARG ONAP_TAG=master
# Install kubectl
# Note: Latest version may be found on:
@@ -10,8 +11,8 @@ ARG ONAP_TESTS_TAG=master
ADD https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl
-COPY scripts/check_onap_k8s.sh /check_onap_k8s.sh
COPY scripts/check_onap_helm.sh /check_onap_helm.sh
+COPY upper-constraints.txt .
RUN set -x && \
apk --no-cache add --update curl ca-certificates && \
@@ -20,12 +21,16 @@ RUN set -x && \
chmod +x /usr/local/bin/kubectl && \
adduser kubectl -Du 2342 -h /config && \
wget https://storage.googleapis.com/kubernetes-helm/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm && \
+ wget -O /check_for_ingress_and_nodeports.py https://git.onap.org/integration/plain/test/security/check_for_ingress_and_nodeports.py?h=$ONAP_TAG &&\
chmod +x /usr/local/bin/helm && \
chmod +x /check_onap_*.sh && \
pip3 install --upgrade pip && \
+ pip3 install --no-cache-dir -r upper-constraints.txt && \
pip3 install --no-cache-dir \
git+https://gitlab.com/Orange-OpenSource/lfn/onap/integration/xtesting.git@$ONAP_TESTS_TAG#subdirectory=infra-healthcheck && \
apk del .build-deps
COPY docker/testcases.yaml /usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml
+COPY docker/logging.ini /usr/lib/python3.8/site-packages/xtesting/ci/logging.ini
+COPY docker/logging.debug.ini /usr/lib/python3.8/site-packages/xtesting/ci/logging.debug.ini
CMD ["run_tests", "-t", "all"]
diff --git a/infra-healthcheck/docker/logging.debug.ini b/infra-healthcheck/docker/logging.debug.ini
new file mode 100644
index 0000000..8b2644f
--- /dev/null
+++ b/infra-healthcheck/docker/logging.debug.ini
@@ -0,0 +1,70 @@
+[loggers]
+keys=root,xtesting,ci,core,warnings,kubernetes_status,infra_healthcheck
+
+[handlers]
+keys=console,wconsole,file,dfile
+
+[formatters]
+keys=standard
+
+[logger_root]
+level=NOTSET
+handlers=dfile
+
+[logger_xtesting]
+level=NOTSET
+handlers=file
+qualname=xtesting
+
+[logger_ci]
+level=NOTSET
+handlers=console
+qualname=xtesting.ci
+
+[logger_core]
+level=NOTSET
+handlers=console
+qualname=xtesting.core
+
+[logger_warnings]
+level=NOTSET
+handlers=file,console
+qualname=py.warnings
+
+[logger_kubernetes_status]
+level=NOTSET
+handlers=wconsole,file
+qualname=kubernetes_status
+
+[logger_infra_healthcheck]
+level=NOTSET
+handlers=wconsole,file
+qualname=infra_healthcheck
+
+[handler_console]
+class=StreamHandler
+level=INFO
+formatter=standard
+args=(sys.stdout,)
+
+[handler_wconsole]
+class=StreamHandler
+level=WARN
+formatter=standard
+args=(sys.stdout,)
+
+[handler_file]
+class=FileHandler
+level=DEBUG
+formatter=standard
+args=("/var/lib/xtesting/results/xtesting.log",)
+
+[handler_dfile]
+class=FileHandler
+level=DEBUG
+formatter=standard
+args=("/var/lib/xtesting/results/xtesting.debug.log",)
+
+[formatter_standard]
+format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
+datefmt=
diff --git a/infra-healthcheck/docker/logging.ini b/infra-healthcheck/docker/logging.ini
new file mode 100644
index 0000000..bdf651a
--- /dev/null
+++ b/infra-healthcheck/docker/logging.ini
@@ -0,0 +1,70 @@
+[loggers]
+keys=root,xtesting,ci,core,warnings,kubernetes_status,infra_healthcheck
+
+[handlers]
+keys=console,wconsole,file,null
+
+[formatters]
+keys=standard
+
+[logger_root]
+level=NOTSET
+handlers=null
+
+[logger_xtesting]
+level=NOTSET
+handlers=file
+qualname=xtesting
+
+[logger_ci]
+level=NOTSET
+handlers=console
+qualname=xtesting.ci
+
+[logger_core]
+level=NOTSET
+handlers=console
+qualname=xtesting.core
+
+[logger_warnings]
+level=NOTSET
+handlers=file,console
+qualname=py.warnings
+
+[logger_kubernetes_status]
+level=NOTSET
+handlers=wconsole,file
+qualname=kubernetes_status
+
+[logger_infra_healthcheck]
+level=NOTSET
+handlers=wconsole,file
+qualname=infra_healthcheck
+
+[handler_null]
+class=NullHandler
+level=NOTSET
+formatter=standard
+args=()
+
+[handler_console]
+class=StreamHandler
+level=INFO
+formatter=standard
+args=(sys.stdout,)
+
+[handler_wconsole]
+class=StreamHandler
+level=WARN
+formatter=standard
+args=(sys.stdout,)
+
+[handler_file]
+class=FileHandler
+level=DEBUG
+formatter=standard
+args=("/var/lib/xtesting/results/xtesting.log",)
+
+[formatter_standard]
+format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
+datefmt=
diff --git a/infra-healthcheck/docker/testcases.yaml b/infra-healthcheck/docker/testcases.yaml
index fb30c85..346daf5 100644
--- a/infra-healthcheck/docker/testcases.yaml
+++ b/infra-healthcheck/docker/testcases.yaml
@@ -27,3 +27,15 @@ tiers:
DEPLOYED status
run:
name: 'onap_helm'
+ -
+ case_name: nodeport_ingress
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ Check that there is no NodePort without corresponding
+ Ingress port
+ dependencies:
+ - DEPLOY_SCENARIO: 'ingress'
+ run:
+ name: 'nodeport_ingress'
diff --git a/infra-healthcheck/infra_healthcheck/k8stest.py b/infra-healthcheck/infra_healthcheck/k8stest.py
index 8bb7dde..f8d618f 100644
--- a/infra-healthcheck/infra_healthcheck/k8stest.py
+++ b/infra-healthcheck/infra_healthcheck/k8stest.py
@@ -101,16 +101,6 @@ class K8sTesting(testcase.TestCase):
return res
-class OnapK8sTest(K8sTesting):
- """Kubernetes smoke test suite"""
- def __init__(self, **kwargs):
- if "case_name" not in kwargs:
- kwargs.get("case_name", 'onap-k8s')
- super(OnapK8sTest, self).__init__(**kwargs)
- self.cmd = ['/check_onap_k8s.sh']
- self.criteria_string = "Nb Failed Pods"
-
-
class OnapHelmTest(K8sTesting):
"""Kubernetes conformance test suite"""
def __init__(self, **kwargs):
@@ -119,3 +109,14 @@ class OnapHelmTest(K8sTesting):
super(OnapHelmTest, self).__init__(**kwargs)
self.cmd = ['/check_onap_helm.sh']
self.criteria_string = "Nb Failed Helm Charts"
+
+
+class OnapSecurityNodePortsIngress(K8sTesting):
+ """Check that there is no NodePort without corresponding Ingress port."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'nodeport_ingress')
+ super(OnapSecurityNodePortsIngress, self).__init__(**kwargs)
+ self.cmd = ['python3', '/check_for_ingress_and_nodeports.py',
+ '--conf', '/root/.kube/config']
+ self.error_string = "NodePort without corresponding Ingress found"
diff --git a/infra-healthcheck/requirements.txt b/infra-healthcheck/requirements.txt
index aed40a6..91babf8 100644
--- a/infra-healthcheck/requirements.txt
+++ b/infra-healthcheck/requirements.txt
@@ -9,3 +9,6 @@ pylint>=2.1 # GPLv2
yamllint
bashate # Apache-2.0
xtesting
+kubernetes # Apache-2.0
+colorama # BSD
+kubernetes_status
diff --git a/infra-healthcheck/setup.cfg b/infra-healthcheck/setup.cfg
index 2cccb82..a3ec3db 100644
--- a/infra-healthcheck/setup.cfg
+++ b/infra-healthcheck/setup.cfg
@@ -7,5 +7,6 @@ packages = infra_healthcheck
[entry_points]
xtesting.testcase =
- onap_k8s = infra_healthcheck.k8stest:OnapK8sTest
+ onap_k8s = kubernetes_status.status:Status
onap_helm = infra_healthcheck.k8stest:OnapHelmTest
+ nodeport_ingress = infra_healthcheck.k8stest:OnapSecurityNodePortsIngress
diff --git a/infra-healthcheck/upper-constraints.txt b/infra-healthcheck/upper-constraints.txt
new file mode 100644
index 0000000..d37d29d
--- /dev/null
+++ b/infra-healthcheck/upper-constraints.txt
@@ -0,0 +1 @@
+git+https://gitlab.com/Orange-OpenSource/lfn/tools/kubernetes-status.git#egg=kubernetes_status
diff --git a/security/README.md b/security/README.md
index 3defbf8..b350078 100644
--- a/security/README.md
+++ b/security/README.md
@@ -2,10 +2,86 @@
## Goal
+This security docker includes the test suites dealing with security aspects
+of an ONAP deployment.
+
+It includes 6 tests:
+
+* root_pods: check that pods are nor using root user or started as root
+* unlimitted_pods: check that limits are set for pods
+* cis_kubernetes: perform the k8s cis test suite (upstream src aquasecurity)
+* http_public_endpoints: check that there is no public http endpoints exposed in
+ ONAP cluster
+* nonssl_endpoints: check that all public HTTP endpoints exposed in ONAP
+ cluster use SSL tunnels
+* jdpw_ports: check that there are no internal java ports
+* kube_hunter: security suite to search k8s vulnerabilities (upstream src
+ aquasecurity)
+
## Usage
### Configuration
+Mandatory:
+
+* The kubernetes configuration: usually hosted on the.kube/config of your
+ jumphost. It corresponds the kubernetes credentials and are needed to perform
+ the different operations. This file shall be copied in /root/.kube/config in
+ the docker.
+
+Optional:
+
+* The local result directory path: to store the results in your local
+ environement. It shall corresponds to the internal result docker path
+ /var/lib/xtesting/results
+
### Command
+You can run this docker by typing:
+
+```
+docker run -v <the kube config>:/root/.kube/config -v
+<result directory>:/var/lib/xtesting/results
+registry.gitlab.com/orange-opensource/lfn/onap/integration/xtesting/security:latest
+```
+
+Options:
+
+* -r: by default the reporting to the Database is not enabled. You need to
+ specify the -r option in the command line. Please note that in this case, you
+ must precise some env variables.
+
+environment variables:
+
+* Mandatory (if you want to report the results in the database):
+ * TEST_DB_URL: the url of the target Database with the env variable .
+ * NODE_NAME: the name of your test environement. It must be declared in the
+ test database (e.g. windriver-SB00)
+* Optionnal
+ * INSTALLER_TYPE: precise how your ONAP has been installed (e.g. kubespray-oom,
+ rke-oom)
+ * BUILD_TAG: a unique tag of your CI system. It can be usefull to get all the
+ tests of one CI run. It uses the regex (dai|week)ly-(.+?)-[0-9]* to find the
+ version (e.g. daily-elalto-123456789).
+
+The command becomes:
+
+```
+docker run -v <the kube config>:/root/.kube/config -v
+<result directory>:/var/lib/xtesting/results registry.gitlab.com/orange-opensour
+ce/lfn/onap/integration/xtesting/security:latest /bin/bash -c "run_tests -r -t all
+```
+
### Output
+
+```
++-----------------------+------------+------------+------------+-----------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++-----------------------+------------+------------+------------+-----------+
+| root_pods | security | security | 03:48 | FAIL |
+| unlimitted_pods | security | security | 00:37 | FAIL |
+| cis_kubernetes | security | security | 00:01 | FAIL |
+| http_public_endpoints | security | security | 00:01 | FAIL |
+| jdpw_ports | security | security | 05:39 | FAIL |
++-----------------------+------------+------------+------------+-----------+
+```
diff --git a/security/docker/Dockerfile b/security/docker/Dockerfile
index 667900f..e38f565 100644
--- a/security/docker/Dockerfile
+++ b/security/docker/Dockerfile
@@ -1,12 +1,58 @@
-FROM opnfv/xtesting
+FROM golang:1.13 AS build_aqua
+WORKDIR /go/src/github.com/aquasecurity/
+RUN git clone https://github.com/aquasecurity/kube-bench.git --depth 1
+WORKDIR /go/src/github.com/aquasecurity/kube-bench
+RUN GO111MODULE=on CGO_ENABLED=0 go install -a -ldflags "-w"
+FROM golang:1.13 AS build_onap
+WORKDIR /opt/onap
+RUN git clone https://git.onap.org/integration --depth 1
+WORKDIR /opt/onap/integration/test/security/sslendpoints
+RUN CGO_ENABLED=0 go install -a -ldflags '-w -s -extldflags "-static"'
+
+FROM opnfv/xtesting AS run
+
+ARG KUBERNETES_VERSION="v1.15.2"
+ARG HELM_VERSION="v2.14.1"
ARG ONAP_TAG=master
-ARG PIP_TAG=19.3.1
+ARG ONAP_TESTS_TAG=master
+
+# Install kubectl
+# Note: Latest version may be found on:
+# https://aur.archlinux.org/packages/kubectl-bin/
+
+ADD https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl
+
+COPY scripts/check_security_root.sh /check_security_root.sh
+COPY scripts/root_pods_xfail.txt /root_pods_xfail.txt
+COPY scripts/check_unlimitted_pods.sh /check_unlimitted_pods.sh
+COPY scripts/check_cis_kubernetes.sh /check_cis_kubernetes.sh
+COPY --from=build_aqua /go/bin/kube-bench /usr/local/bin/kube-bench
+COPY --from=build_aqua /go/src/github.com/aquasecurity/kube-bench/cfg/ /cfg/
+COPY --from=build_onap /go/bin/sslendpoints /usr/local/bin/sslendpoints
-COPY requirements.txt requirements.txt
-RUN apk --no-cache add --virtual .build-deps --update \
- openssl-dev libjpeg-turbo-dev && \
+RUN set -x && \
+ apk --no-cache add --update curl ca-certificates openssl procps util-linux \
+ nmap nmap-scripts && \
+ apk --no-cache add --virtual .build-deps --update \
+ python3-dev linux-headers gcc musl-dev && \
+ chmod +x /usr/local/bin/kubectl && \
+ git clone --depth 1 https://github.com/aquasecurity/kube-hunter.git /kube-hunter && \
+ adduser kubectl -Du 2342 -h /config && \
+ wget https://storage.googleapis.com/kubernetes-helm/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm && \
+ wget -O /check_for_nonssl_endpoints.sh https://git.onap.org/integration/plain/test/security/check_for_nonssl_endpoints.sh?h=$ONAP_TAG &&\
+ wget -O /check_for_jdwp.sh https://git.onap.org/integration/plain/test/security/check_for_jdwp.sh?h=$ONAP_TAG &&\
+ wget -O /jdwp_xfail.txt https://git.onap.org/integration/plain/test/security/jdwp_xfail.txt?h=$ONAP_TAG &&\
+ wget -O /nonssl_xfail.txt https://git.onap.org/integration/plain/test/security/nonssl_xfail.txt?h=$ONAP_TAG &&\
+ chmod +x /usr/local/bin/helm && \
+ chmod +x /usr/local/bin/kube-bench && \
+ chmod +x /usr/local/bin/sslendpoints && \
+ chmod +x /check_*.sh && \
+ pip3 install --upgrade pip && \
+ pip3 install --no-cache-dir \
+ git+https://gitlab.com/Orange-OpenSource/lfn/onap/integration/xtesting.git@$ONAP_TESTS_TAG#subdirectory=security && \
+ cd /kube-hunter && pip3 install -r /kube-hunter/requirements.txt && \
apk del .build-deps
COPY docker/testcases.yaml /usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml
-CMD ["run_test -t all -r"]
+CMD ["run_tests", "-t", "all"]
diff --git a/security/docker/testcases.yaml b/security/docker/testcases.yaml
index ed281f2..6b9d482 100644
--- a/security/docker/testcases.yaml
+++ b/security/docker/testcases.yaml
@@ -8,11 +8,67 @@ tiers:
Set of basic Functional security tests.
testcases:
-
- case_name: osji
- project_name: integration
+ case_name: root_pods
+ project_name: security
criteria: 100
blocking: false
description: >-
- run osji scan.
+ test if pods are run in root.
run:
- name: 'onap_osji'
+ name: 'root_pods'
+ -
+ case_name: unlimitted_pods
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ test if pods are run without limit.
+ run:
+ name: 'unlimitted_pods'
+ -
+ case_name: cis_kubernetes
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ test if kubernetes install is CIS compliant.
+ run:
+ name: 'cis_kubernetes'
+ -
+ case_name: http_public_endpoints
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ Check all ports exposed outside of kubernetes cluster
+ looking for plain http endpoint.
+ run:
+ name: 'http_public_endpoints'
+ -
+ case_name: nonssl_endpoints
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ Check that all ports exposed outside of kubernetes cluster
+ use SSL tunnels.
+ run:
+ name: 'nonssl_endpoints'
+ -
+ case_name: jdpw_ports
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ Check that no jdwp ports are exposed
+ run:
+ name: 'jdpw_ports'
+ -
+ case_name: kube_hunter
+ project_name: security
+ criteria: 100
+ blocking: false
+ description: >-
+ Check k8s CVE.
+ run:
+ name: 'kube_hunter'
diff --git a/security/onap_security/__init__.py b/security/onap_security/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/security/onap_security/__init__.py
diff --git a/security/onap_security/security_tests.py b/security/onap_security/security_tests.py
new file mode 100644
index 0000000..4136f66
--- /dev/null
+++ b/security/onap_security/security_tests.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2018 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+"""
+Define the parent for Kubernetes testing.
+"""
+
+from __future__ import division
+
+import logging
+import subprocess
+import time
+
+from xtesting.core import testcase
+from kubernetes import client, config
+
+
+class SecurityTesting(testcase.TestCase):
+ """Security test runner"""
+
+ __logger = logging.getLogger(__name__)
+
+ def __init__(self, **kwargs):
+ super(SecurityTesting, self).__init__(**kwargs)
+ self.cmd = []
+ self.result = 0
+ self.details = {}
+ self.start_time = 0
+ self.stop_time = 0
+ self.error_string = ""
+
+ def run_security(self): # pylint: disable=too-many-branches
+ """Run the test suites"""
+ cmd_line = self.cmd
+ self.__logger.info("Starting k8s test: '%s'.", cmd_line)
+
+ process = subprocess.Popen(cmd_line, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ process.wait()
+ output = process.stdout.read().decode("utf-8")
+ if ('Error loading client' in output or
+ 'Unexpected error' in output):
+ raise Exception(output)
+
+ # create a log file
+ file_name = "/var/lib/xtesting/results/" + self.case_name + ".log"
+ log_file = open(file_name, "w")
+ log_file.write(output)
+ log_file.close()
+
+ # we consider the command return code for success criteria
+ if process.returncode is None:
+ success = False
+ details = self.error_string
+ if (self.case_name == 'kube_hunter' and
+ "No vulnerabilities were found" in output):
+ success = True
+ elif process.returncode != 0:
+ success = False
+ details = self.error_string
+ else:
+ success = True
+ details = "Test PASS"
+
+ self.details = details
+ self.__logger.info("details: %s", details)
+
+ if success:
+ self.result = 100
+ else:
+ self.result = 0
+
+ def run(self, **kwargs):
+ """Generic Run."""
+
+ self.start_time = time.time()
+ try:
+ self.run_security()
+ res = self.EX_OK
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Error with running Security tests:")
+ res = self.EX_RUN_ERROR
+
+ self.stop_time = time.time()
+ return res
+
+
+class OnapSecurityDockerRootTest(SecurityTesting):
+ """Test that the dockers launched as root."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'root_pods')
+ super(OnapSecurityDockerRootTest, self).__init__(**kwargs)
+ self.cmd = ['/check_security_root.sh', 'onap', '-l', '/root_pods_xfail.txt']
+ self.error_string = "Pods launched with root users"
+
+
+class OnapSecurityUnlimittedPodTest(SecurityTesting):
+ """Check that no pod is launch without limits."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'unlimitted_pods')
+ super(OnapSecurityUnlimittedPodTest, self).__init__(**kwargs)
+ self.cmd = ['/check_unlimitted_pods.sh']
+ self.error_string = "Pods lauched without limits"
+
+
+class OnapSecurityCisKubernetes(SecurityTesting):
+ """Check that kubernetes install is CIS compliant"""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'cis_kubernetes')
+ super(OnapSecurityCisKubernetes, self).__init__(**kwargs)
+ self.cmd = ['/check_cis_kubernetes.sh']
+ self.error_string = "Kubernetes Deployment is not CIS compatible"
+
+
+class OnapSecurityHttpPorts(SecurityTesting):
+ """Check all ports exposed outside of kubernetes cluster looking for plain
+ http endpoint."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'http_public_endpoints')
+ super(OnapSecurityHttpPorts, self).__init__(**kwargs)
+ self.cmd = ['/check_for_nonssl_endpoints.sh', 'onap', '-l', '/nonssl_xfail.txt']
+ self.error_string = "Public http endpoints still found"
+
+
+class OnapSecurityNonSSLPorts(SecurityTesting):
+ """Check that all ports exposed outside of kubernetes cluster use SSL
+ tunnels."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'nonssl_endpoints')
+ super(OnapSecurityNonSSLPorts, self).__init__(**kwargs)
+ self.cmd = ['/usr/local/bin/sslendpoints', '-xfail', '/nonssl_xfail.txt']
+ self.error_string = "Public non-SSL endpoints still found"
+
+
+class OnapSecurityJdwpPorts(SecurityTesting):
+ """Check that no jdwp ports are exposed."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'jdpw_ports')
+ super(OnapSecurityJdwpPorts, self).__init__(**kwargs)
+ self.cmd = ['/check_for_jdwp.sh', 'onap', '-l', '/jdwp_xfail.txt']
+ self.error_string = "JDWP ports found"
+
+
+class OnapSecurityKubeHunter(SecurityTesting):
+ """Check k8s vulnerabilities."""
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs.get("case_name", 'kube_hunter')
+ super(OnapSecurityKubeHunter, self).__init__(**kwargs)
+ config.load_kube_config(config_file='/root/.kube/config')
+ client_kubernetes = client.CoreV1Api()
+ node_list = client_kubernetes.list_node()
+ kube_hunter_cmd = ['/kube-hunter/kube-hunter.py', '--remote']
+ for i in node_list.items:
+ addresses = i.status.addresses
+ for j in addresses:
+ if "External" in str(j):
+ kube_hunter_cmd.append(j.address)
+ self.cmd = kube_hunter_cmd
+ self.error_string = "Vulnerabilties detected."
diff --git a/security/onap_security/test_security_test.py b/security/onap_security/test_security_test.py
new file mode 100644
index 0000000..7906d8a
--- /dev/null
+++ b/security/onap_security/test_security_test.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2018 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+"""Define the classes required to fully cover k8s."""
+
+import logging
+import os
+import unittest
+
+
+from security_tests import SecurityTesting
+
+
+class SecurityTests(unittest.TestCase):
+
+ # pylint: disable=missing-docstring
+
+ def setUp(self):
+ os.environ["DEPLOY_SCENARIO"] = "k8-test"
+ os.environ["KUBE_MASTER_IP"] = "127.0.0.1"
+ os.environ["KUBE_MASTER_URL"] = "https://127.0.0.1:6443"
+ os.environ["KUBERNETES_PROVIDER"] = "local"
+
+ self.security_stesting = SecurityTesting.SecurityTesting()
+
+ def test_run_kubetest_cmd_none(self):
+ with self.assertRaises(TypeError):
+ self.security_stesting.run_security()
+
+
+if __name__ == "__main__":
+ logging.disable(logging.CRITICAL)
+ unittest.main(verbosity=2)
diff --git a/security/requirements.txt b/security/requirements.txt
index b2c729c..6e8b944 100644
--- a/security/requirements.txt
+++ b/security/requirements.txt
@@ -1 +1,13 @@
+# The order of packages is significant, because pip processes them in the order
+# of appearance. Changing the order has an impact on the overall integration
+# process, which may cause wedges in the gate later.
+coverage!=4.4 # Apache-2.0
+mock # BSD
+nose # LGPL
+flake8>=2.5.4 # MIT
+pylint>=2.1 # GPLv2
yamllint
+bashate # Apache-2.0
+xtesting
+Kubernetes
+colorama
diff --git a/security/scripts/check_cis_kubernetes.sh b/security/scripts/check_cis_kubernetes.sh
new file mode 100644
index 0000000..33ffdf5
--- /dev/null
+++ b/security/scripts/check_cis_kubernetes.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+echo "------------------------------------------------------------------------"
+echo "-------------------- ONAP Security tests ----------------------------"
+echo "----------------- Test if K8S is CIS compliant ----------------------"
+echo "------------------------------------------------------------------------"
+
+code=0
+
+CIS_VERSION=${CIS_VERSION:-1.4}
+echo "Running CIS test case version ${CIS_VERSION}"
+kube-bench master --benchmark cis-${CIS_VERSION} > cis_full_test.txt
+cat cis_full_test.txt | grep "\[FAIL]" > cisK8s.txt
+
+if [ -s cisK8s.txt ]
+then
+ code=1
+ nb_errors=`cat cisK8s.txt | wc -l`
+ echo "Test FAIL: $nb_errors assertions not passed"
+ cat cis_full_test.txt
+else
+ echo "Test PASS: Kubernetes Deployment is CIS compatible"
+fi
+
+exit $code
diff --git a/security/scripts/check_security_root.sh b/security/scripts/check_security_root.sh
new file mode 100644
index 0000000..ca388fd
--- /dev/null
+++ b/security/scripts/check_security_root.sh
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+
+usage() {
+ cat <<EOF
+Usage: $(basename $0) <k8s-namespace> [-l <white list file>]
+ -l: rooted pod xfail file
+EOF
+ exit ${1:-0}
+}
+
+if [ "$#" -lt 1 ]; then
+ usage
+ exit 1
+fi
+
+K8S_NAMESPACE=$1
+FILTERED_PODS_LIST=$(mktemp rooted_pods_XXXXXX)
+WL_RAW_FILE_PATH=$(mktemp raw_filtered_pods_XXXXXX)
+
+manage_white_list() {
+ # init filtered port list file
+ if [ ! -f $WL_FILE_PATH ];then
+ echo "File not found"
+ usage
+ fi
+ grep -o '^[^#]*' $WL_FILE_PATH > $WL_RAW_FILE_PATH
+}
+
+### getopts
+while :
+do
+ case $2 in
+ -h|--help|help) usage;;
+ -l) WL_FILE_PATH=$3;manage_white_list;shift;;
+ -*) usage 1 ;;
+ *) break ;;
+ esac
+done
+
+echo "------------------------------------------------------------------------"
+echo "-------------------- ONAP Security tests ----------------------------"
+echo "-------------------- Test root user in pods -------------------------"
+echo "------------------------------------------------------------------------"
+
+code=0
+
+# get the pod list
+for pod in `kubectl get pod -n $K8S_NAMESPACE| grep "Running" | grep -v functest | grep -v integration | awk '{print $1}'` ;do
+ list=`kubectl top pod $pod --containers -n onap |grep -v "POD"|awk '{print $1":"$2}'`;
+ for po in $list; do
+ contname=`echo $po|cut -d':' -f2`;uid=`kubectl exec $pod --container $contname -n $K8S_NAMESPACE id|sed -r "s/^uid=(.*) gid.*$/\1/"`;echo "POD: $pod container: $contname uid: $uid";
+ done;
+done | grep root > $FILTERED_PODS_LIST
+
+while IFS= read -r line; do
+ # for each line we test if it is in the white list with a regular expression
+ while IFS= read -r wl_line; do
+ wl_name=$(echo $wl_line | awk {'print $1'})
+ if grep -e $K8S_NAMESPACE-$wl_name <<< "$line" > /dev/null ;then
+ # Found in white list, exclude it
+ sed -i "/$line/d" $FILTERED_PODS_LIST
+ fi
+ done < $WL_RAW_FILE_PATH
+done < $FILTERED_PODS_LIST
+
+if [ -s $FILTERED_PODS_LIST ]
+then
+ code=1
+ nb_errors=`cat $FILTERED_PODS_LIST | wc -l`
+ echo "Test FAIL: $nb_errors pod(s) launched as root found"
+ cat $FILTERED_PODS_LIST
+else
+ echo "Test PASS: No pod launched as root found"
+fi
+
+exit $code
diff --git a/security/scripts/check_unlimitted_pods.sh b/security/scripts/check_unlimitted_pods.sh
new file mode 100644
index 0000000..fdef6f3
--- /dev/null
+++ b/security/scripts/check_unlimitted_pods.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+echo "------------------------------------------------------------------------"
+echo "-------------------- ONAP Security tests ----------------------------"
+echo "-------------------- Test pods without limit ------------------------"
+echo "------------------------------------------------------------------------"
+
+code=0
+
+# get the pod list
+for pod in `kubectl get pod -n onap|grep -v "NAME"|grep "Running\|Completed" |grep -v functest |grep -v integration | awk '{print $1}'`;do
+ kubectl describe pod $pod -n onap|grep "Limits";
+ if [ $? == 1 ] ; then
+ echo $pod ;
+ fi;
+done | grep -v Limits > NoLimitContainer.txt
+
+if [ -s NoLimitContainer.txt ]
+then
+ code=1
+ nb_errors=`cat NoLimitContainer.txt | wc -l`
+ echo "Test FAIL: $nb_errors pod(s) launched without limit"
+ cat NoLimitContainer.txt
+else
+ echo "Test PASS: No pod launched without limit"
+fi
+
+exit $code
diff --git a/security/scripts/root_pods_xfail.txt b/security/scripts/root_pods_xfail.txt
new file mode 100644
index 0000000..c282cf8
--- /dev/null
+++ b/security/scripts/root_pods_xfail.txt
@@ -0,0 +1,33 @@
+# Expected failure list for rooted ports
+# Upstream pods are excluded in Frankfurt
+# We consider only the pods we built
+aaf-cass # cassandra
+aaf-sms-vault # upstream vault and consul docker used by aaf AAF-1102
+aai # aai pods not launched as root even root user still in dockers AAI-2822
+awx # ansible
+cassandra # common cassandra
+consul # nobody remembers who is responsible for consul
+dcae-redis # redis container
+dcae-mongo # mongo container
+dcae-cloudify-manager # DCAEGEN2-2121
+mariadb # common mariadb
+msb-consul # another consul
+multicloud-fcaps # rabbit-mq upstream pod MULTICLOUD-1017
+multicloud-k8s-etcd
+multicloud-k8s-mongo
+music-cassandra # music has itw own cassandra
+nbi-mongo # a mongo db
+netbox # netbox
+pomba-elasticsearch # elasticsearch
+portal-cassandra # portal cassandra
+portal-db # portal mariadb
+portal-zookeeper # portal zookeeper
+zookeeper # common zookeper
+
+# other waivers
+robot # testing
+sniro-emulator # testing
+oof-cmso-service # testing
+vnfsdk # testing VNFSDK-565
+pomba # nobody taking cares of pomba for several releases
+dcaemod # dcae experimental pods for Frankfurt
diff --git a/security/setup.cfg b/security/setup.cfg
new file mode 100644
index 0000000..61fe7fa
--- /dev/null
+++ b/security/setup.cfg
@@ -0,0 +1,16 @@
+[metadata]
+name = onap_security
+version = 1
+
+[files]
+packages = onap_security
+
+[entry_points]
+xtesting.testcase =
+ root_pods = onap_security.security_tests:OnapSecurityDockerRootTest
+ unlimitted_pods = onap_security.security_tests:OnapSecurityUnlimittedPodTest
+ cis_kubernetes = onap_security.security_tests:OnapSecurityCisKubernetes
+ http_public_endpoints = onap_security.security_tests:OnapSecurityHttpPorts
+ nonssl_endpoints = onap_security.security_tests:OnapSecurityNonSSLPorts
+ jdpw_ports = onap_security.security_tests:OnapSecurityJdwpPorts
+ kube_hunter = onap_security.security_tests:OnapSecurityKubeHunter
diff --git a/security/setup.py b/security/setup.py
new file mode 100644
index 0000000..566d844
--- /dev/null
+++ b/security/setup.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
+import setuptools
+
+# In python < 2.7.4, a lazy loading of package `pbr` will break
+# setuptools if some other modules registered functions in `atexit`.
+# solution from: http://bugs.python.org/issue15881#msg170215
+try:
+ import multiprocessing # noqa
+except ImportError:
+ pass
+
+setuptools.setup(
+ setup_requires=['pbr>=2.0.0'],
+ pbr=True)
diff --git a/smoke-usecases-robot/docker/Dockerfile b/smoke-usecases-robot/docker/Dockerfile
index 38616aa..8dbe29a 100644
--- a/smoke-usecases-robot/docker/Dockerfile
+++ b/smoke-usecases-robot/docker/Dockerfile
@@ -1,4 +1,4 @@
-FROM opnfv/xtesting
+FROM opnfv/xtesting:jerma
MAINTAINER Morgan Richomme <morgan.richomme@orange.com>
@@ -10,7 +10,8 @@ ARG PIP_TAG=19.3.1
ENV TAG all
COPY requirements.txt requirements.txt
-RUN apk --no-cache add --virtual .build-deps --update \
+RUN apk --no-cache add --update openssl chromium chromium-chromedriver && \
+ apk --no-cache add --virtual .build-deps --update \
python3-dev build-base linux-headers libffi-dev \
openssl-dev libjpeg-turbo-dev && \
pip3 install --upgrade pip && \
@@ -26,14 +27,15 @@ RUN apk --no-cache add --virtual .build-deps --update \
-chttps://git.opnfv.org/functest/plain/upper-constraints.txt?h=$OPNFV_TAG \
-rrequirements.txt && \
mkdir -p /var/opt/ONAP/demo/heat && cp -Rf /src/demo/heat/vFW /var/opt/ONAP/demo/heat/ && \
+ mkdir -p /var/opt/ONAP/demo/tosca && cp -Rf /src/demo/tosca/pNF /var/opt/ONAP/demo/tosca/ && \
mkdir -p /demo/service_mapping && cp -Rf /src/demo/service_mapping /demo/ && \
mkdir -p /var/opt/ONAP/demo/preload_data && cp -Rf /src/demo/preload_data /var/opt/ONAP/demo/ && \
- ln -s /usr/lib/python3.8/site-packages/vcpeutils /usr/lib/python3.8/site-packages/SoUtils && \
- ln -s /usr/lib/python3.8/site-packages/heatbridge /usr/lib/python3.8/site-packages/HeatBridge && \
+ ln -s /usr/lib/python3.7/site-packages/vcpeutils /usr/lib/python3.7/site-packages/SoUtils && \
+ ln -s /usr/lib/python3.7/site-packages/heatbridge /usr/lib/python3.7/site-packages/HeatBridge && \
rm -r requirements.txt /var/opt/ONAP/.git /src/demo && \
cd / && ln -s /var/opt/ONAP/robot/ /robot && \
apk del .build-deps
-COPY docker/testcases.yaml /usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml
+COPY docker/testcases.yaml /usr/lib/python3.7/site-packages/xtesting/ci/testcases.yaml
COPY scripts/cmd.sh /
CMD ["/cmd.sh"]