Merge "Add ICN Bluval support"
authorTapio Tallgren <tapio.tallgren@nokia.com>
Wed, 3 Jun 2020 12:31:42 +0000 (12:31 +0000)
committerGerrit Code Review <gerrit@akraino.org>
Wed, 3 Jun 2020 12:31:42 +0000 (12:31 +0000)
13 files changed:
bluval/blucon.py
bluval/blucon.sh
bluval/bluval-eliot.yaml [new file with mode: 0644]
bluval/bluval.py
bluval/rules.txt [new file with mode: 0644]
docker/kube-conformance/Makefile
docker/os/Dockerfile
tests/hardware/bios_version/bios_version_dell.robot
tests/k8s/conformance/conformance.robot
tests/k8s/kube-hunter/kube-hunter.resource
tests/os/lynis/lynis.robot
tests/os/vuls/vuls.robot
tests/variables.yaml

index 0d5d7ca..6913330 100644 (file)
@@ -29,6 +29,7 @@ import yaml
 from bluutil import BluvalError
 from bluutil import ShowStopperError
 
+_PULL = False
 _OPTIONAL_ALSO = False
 _SUBNET = ""
 
@@ -53,27 +54,43 @@ def get_volumes(layer):
     return volume_list
 
 
-def invoke_docker(bluprint, layer):
+def pull_docker(layer, tag):
+    """Pull docker image for given layer
+    """
+    cmd = ("docker pull akraino/validation:{0}-{1}"
+           .format(layer, tag))
+
+    args = [cmd]
+    try:
+        print('\nPulling image using {}'.format(args), flush=True)
+        subprocess.call(args, shell=True)
+    except OSError:
+        raise BluvalError(OSError)
+
+
+def invoke_docker(bluprint, layer, tag):
     """Start docker container for given layer
     """
+    if _PULL:
+        pull_docker(layer, tag)
     volume_list = get_volumes('common') + get_volumes(layer)
     cmd = ("docker run --rm" + volume_list + _SUBNET +
-           " akraino/validation:{0}-latest"
+           " akraino/validation:{0}-{3}"
            " /bin/sh -c"
            " 'cd /opt/akraino/validation "
            "&& python -B bluval/bluval.py -l {0} {1} {2}'"
-           .format(layer, ("-o" if _OPTIONAL_ALSO else ""), bluprint))
+           .format(layer, ("-o" if _OPTIONAL_ALSO else ""), bluprint, tag))
 
     args = [cmd]
     try:
-        print('\nInvoking {}'.format(args))
+        print('\nInvoking {}'.format(args), flush=True)
         subprocess.call(args, shell=True)
     except OSError:
         #print('Error while executing {}'.format(args))
         raise BluvalError(OSError)
 
 
-def invoke_dockers(yaml_loc, layer, blueprint_name):
+def invoke_dockers(yaml_loc, layer, blueprint_name, tag):
     """Parses yaml file and starts docker container for one/all layers
     """
     with open(str(yaml_loc)) as yaml_file:
@@ -81,34 +98,44 @@ def invoke_dockers(yaml_loc, layer, blueprint_name):
     blueprint = yamldoc['blueprint']
     if layer is None or layer == "all":
         for each_layer in blueprint['layers']:
-            invoke_docker(blueprint_name, each_layer)
+            invoke_docker(blueprint_name, each_layer, tag)
     else:
-        invoke_docker(blueprint_name, layer)
+        invoke_docker(blueprint_name, layer, tag)
 
 
 @click.command()
 @click.argument('blueprint')
 @click.option('--layer', '-l')
 @click.option('--network', '-n')
+@click.option('--tag', '-t')
 @click.option('--optional_also', '-o', is_flag=True)
-def main(blueprint, layer, network, optional_also):
+@click.option('--pull', '-P', is_flag=True)
+# pylint: disable=too-many-arguments
+def main(blueprint, layer, network, tag, optional_also, pull):
     """Takes blueprint name and optional layer. Validates inputs and derives
-    yaml location from blueprint name. Invokes validate on blue print.
+    yaml location from blueprint name. Invokes validate on blueprint.
     """
+    global _PULL # pylint: disable=global-statement
     global _OPTIONAL_ALSO  # pylint: disable=global-statement
     global _SUBNET # pylint: disable=global-statement
     mypath = Path(__file__).absolute()
     yaml_loc = mypath.parents[0].joinpath('bluval-{}.yaml'.format(blueprint))
     if layer is not None:
         layer = layer.lower()
+    if pull:
+        _PULL = True
+        print("_PULL {}".format(_PULL))
     if optional_also:
         _OPTIONAL_ALSO = True
         print("_OPTIONAL_ALSO {}".format(_OPTIONAL_ALSO))
     if network is not None:
         _SUBNET = " --net=" + network
         print("Using", _SUBNET)
+    if tag is None:
+        tag = 'latest'
+    print("Using tag {}".format(tag))
     try:
-        invoke_dockers(yaml_loc, layer, blueprint)
+        invoke_dockers(yaml_loc, layer, blueprint, tag)
     except ShowStopperError as err:
         print('ShowStopperError:', err)
     except BluvalError as err:
index afe54db..b882f92 100755 (executable)
 
 if [ -z "$AKRAINO_HOME" ]
 then
-    echo "AKRAINO_HOME not available. Setting..."
-    this_file="$(readlink -f $0)"
-    bluval_dir="$(dirname $this_file)"
-    validation_dir="$(dirname $bluval_dir)"
-    parent_dir="$(dirname $validation_dir)"
-    export AKRAINO_HOME="$parent_dir"
+    echo "AKRAINO_HOME not available. Setting ..."
+    AKRAINO_HOME="$(readlink -f "$(dirname "$0")/../..")"
 fi
+
+# Allow overriding VALIDATION_DIR and/or RESULTS_DIR via env vars
+VALIDATION_DIR=${VALIDATION_DIR:-"${AKRAINO_HOME}/validation"}
+RESULTS_DIR=${RESULTS_DIR:-"${AKRAINO_HOME}/results"}
+
 echo "AKRAINO_HOME=$AKRAINO_HOME"
+echo "VALIDATION_DIR=$VALIDATION_DIR"
+echo "RESULTS_DIR=$RESULTS_DIR"
 
 if [ "$#" -eq 0 ]
 then
@@ -38,6 +41,7 @@ then
     Options:
         -l, --layer TEXT
         -n, --network TEXT
+        -t, --tag TEXT
         -o, --optional_also
         --help               Show this message and exit.'
 
@@ -45,13 +49,13 @@ then
 fi
 
 echo "Building docker image"
-image_tag=$( (git branch || echo "* local") | grep "^\*" | awk '{print $2}')
-docker build -t akraino/validation:blucon-$image_tag $AKRAINO_HOME/validation/bluval
+img="akraino/validation:blucon-$(git rev-parse --abbrev-ref HEAD || echo local)"
+docker build -t "$img" "$VALIDATION_DIR/bluval"
 
 set -x
 
 docker run --rm \
     -v /var/run/docker.sock:/var/run/docker.sock \
-    -v $AKRAINO_HOME/results:/opt/akraino/results \
-    -v $AKRAINO_HOME/validation:/opt/akraino/validation \
-    akraino/validation:blucon-$image_tag "$@"
+    -v "$RESULTS_DIR":/opt/akraino/results \
+    -v "$VALIDATION_DIR":/opt/akraino/validation \
+    "$img" "$@"
diff --git a/bluval/bluval-eliot.yaml b/bluval/bluval-eliot.yaml
new file mode 100644 (file)
index 0000000..3632777
--- /dev/null
@@ -0,0 +1,41 @@
+---
+##############################################################################
+# Copyright (c) 2020 Huawei Tech and others.                                 #
+#                                                                            #
+# 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.                                             #
+##############################################################################
+blueprint:
+    name: eliot
+    layers:
+        - os
+        - k8s
+
+    os: &os_eliot
+        -
+            name: lynis
+            what: lynis
+            optional: "False"
+        -
+            name: vuls
+            what: vuls
+            optional: "False"
+
+    k8s: &k8s
+        -
+            name: kube-hunter
+            what: kube-hunter
+            optional: "False"
+        -
+            name: conformance
+            what: conformance
+            optional: "False"
index 63b301f..73cc68a 100644 (file)
@@ -68,7 +68,7 @@ def run_testcase(testcase):
 
     print('Executing testcase {}'.format(name))
     print('show_stopper {}'.format(show_stopper))
-    print('Invoking {}'.format(args))
+    print('Invoking {}'.format(args), flush=True)
     try:
         status = subprocess.call(args, shell=False)
         if status != 0 and show_stopper.lower() == "true":
diff --git a/bluval/rules.txt b/bluval/rules.txt
new file mode 100644 (file)
index 0000000..f2273ff
--- /dev/null
@@ -0,0 +1,10 @@
+# Separate results based on suite (group the messages by suite)
+start /(?:Executing testcase ).*$/
+
+# Only fail if some critical tests failed
+debug /critical test.*passed, 0 failed/
+error /critical test.*passed/
+
+# Suite/subsuite test results will be marked as info/warn
+info /PASS/
+warn /FAIL/
index ee7b40f..1c0f7f0 100644 (file)
@@ -16,7 +16,7 @@
 
 export WORK_DIR?=$(TAG_PRE)
 export KUBE_VERSION=1.16
-export TAG_VER?=v$(KUBE_VERSION)
+export TAG_VER=v$(KUBE_VERSION)
 
 .PHONY: .build
 .build:: .submodules_patched
index c4d5938..1981b16 100644 (file)
@@ -60,13 +60,13 @@ RUN git clone https://github.com/CISOfy/lynis && tar czvf /opt/akraino/lynis-rem
 # Fetches vuls databases (invalidate cache using unique timestamp)
 SHELL ["/bin/bash", "-c"]
 RUN if [ $(uname -m) == 'aarch64' ]; then HOST_ARCH=arm64; else HOST_ARCH=amd64; fi && \
-    wget https://dl.google.com/go/go1.12.6.linux-$HOST_ARCH.tar.gz -P /root/ --progress=dot:giga && \
+    wget https://dl.google.com/go/go1.14.linux-$HOST_ARCH.tar.gz -P /root/ --progress=dot:giga && \
     cd /root/ && \
-    tar -xzf go1.12.6.linux-$HOST_ARCH.tar.gz -C /root/ && \
-    rm go1.12.6.linux-$HOST_ARCH.tar.gz && \
+    tar -xzf go1.14.linux-$HOST_ARCH.tar.gz -C /root/ && \
+    rm go1.14.linux-$HOST_ARCH.tar.gz && \
     export GOROOT=/root/go && \
-    export GOPATH=/root/go/src && \
-    export PATH=$PATH:/root/go/bin:/root/go/src/bin && \
+    export GOPATH=/root/go/src/github.com && \
+    export PATH=$PATH:/root/go/bin:/root/go/src/github.com/bin && \
     mkdir -p /root/go/src/github.com/future-architect && \
     cd /root/go/src/github.com/future-architect && \
     git clone https://github.com/future-architect/vuls && \
@@ -88,8 +88,8 @@ ADD db.tar.gz /opt/akraino/validation/tests/os/vuls/
 ADD db.tar.gz.timestamp /root/
 RUN \
     export GOROOT=/root/go && \
-    export GOPATH=/root/go/src && \
-    export PATH=$PATH:/root/go/bin:/root/go/src/bin && \
+    export GOPATH=/root/go/src/github.com && \
+    export PATH=$PATH:/root/go/bin:/root/go/src/github.com/bin && \
     for i in $(seq 2002 "$(date +"%Y")"); do go-cve-dictionary fetchnvd -quiet -http-proxy=${HTTP_PROXY} -dbpath /opt/akraino/validation/tests/os/vuls/cve.sqlite3 -years "$i"; done && \
     goval-dictionary fetch-ubuntu -http-proxy=${HTTP_PROXY} -dbpath=/opt/akraino/validation/tests/os/vuls/oval_ubuntu_16.sqlite3 16 && \
     goval-dictionary fetch-ubuntu -http-proxy=${HTTP_PROXY} -dbpath=/opt/akraino/validation/tests/os/vuls/oval_ubuntu_18.sqlite3 18 && \
@@ -106,9 +106,11 @@ COPY --from=build /opt/akraino/validation /opt/akraino/validation
 COPY --from=build /opt/akraino/ltp.tar.gz /opt/akraino/ltp.tar.gz
 COPY --from=build /opt/akraino/lynis-remote.tar.gz /opt/akraino/lynis-remote.tar.gz
 COPY --from=build /root/go/bin /root/go/bin
-COPY --from=build /root/go/src/bin /root/go/src/bin
+COPY --from=build /root/go/src/github.com/bin /root/go/src/github.com/bin
 
 RUN apt-get update && apt-get -y install \
+    openssh-client \
+    sshpass \
     python3-pip python3.6 && \
     cd /usr/bin && ln -s python3 python && \
     pip3 install -r /wheels/requirements/pip-requirements.txt \
index 682e596..acbb5bc 100644 (file)
@@ -27,21 +27,22 @@ Suite Teardown    Close All Connections
 #${HOST}           localhost
 #${USERNAME}       localadmin
 #${SYSINFO}        PowerEdge R740xd
-#${BIOS_REVISION}   1.3
+#${BIOS_REVISION}  1.3
+#${BLK_DEV_REGEXP} ([sh]d[a-z]+|nvme)[0-9]+
 ${SSH_KEYFILE}     /root/.ssh/id_rsa
 ${LOG}             ${LOG_PATH}${/}${SUITE_NAME.replace(' ','_')}.log
 
 *** Test Cases ***
 Get HW Details
         [Documentation]         Verify HW details
-        Start Command           dmidecode | grep -A3 '^System Information'   sudo=True
+        Start Command           cat /sys/class/dmi/id/product_name
         ${stdout}=              Read Command Output
         Append To File          ${LOG}  ${stdout}${\n}
         Should Contain          ${stdout}               ${SYSINFO}
 
 Verify BIOS Revision
         [Documentation]         Verify BIOS Revision
-        Start Command           dmidecode | more | grep 'BIOS Revision'    sudo=True
+        Start Command           printf "BIOS Revision: %u.%u" $(sudo od -t u1 -j 20 -N 2 -A none /sys/firmware/dmi/tables/DMI)
         ${stdout}=              Read Command Output
         Append To File          ${LOG}  ${stdout}${\n}
         Should Contain          ${stdout}               BIOS Revision: ${BIOS_REVISION}
@@ -50,16 +51,15 @@ Check NUMA and CPU
         [Documentation]         NUMAs and CPU components
         ${output}=              Execute Command         lscpu
         Append To File          ${LOG}  ${output}${\n}
-        Should Contain          ${output}       CPU(s):                88
+        Should Match Regexp     ${output}               CPU\\(s\\):\\s+\\d+
 
 Verify Block Devices
         [Documentation]         Reads the sysfs filesystem
         ${output}=              Execute Command         lsblk
         Append To File          ${LOG}  ${output}${\n}
-        Should Contain          ${output}       sdg4
+        Should Match Regexp     ${output}               ${BLK_DEV_REGEXP}
 
 *** Keywords ***
 Open Connection And Log In
-  Open Connection       ${HOST}
-  Login With Public Key    ${USERNAME}  ${SSH_KEYFILE}
-
+        Open Connection         ${HOST}
+        Login With Public Key   ${USERNAME}  ${SSH_KEYFILE}
index edd2271..c51f217 100644 (file)
@@ -148,6 +148,8 @@ Define Images
         ${versions}=            Convert String To JSON  ${result.stdout}
         ${major}=               Get Value From Json  ${versions}  $.serverVersion.major
         ${minor}=               Get Value From Json  ${versions}  $.serverVersion.minor
+        ${major}=               Get Regexp Matches  ${major[0]}  \\d+
+        ${minor}=               Get Regexp Matches  ${minor[0]}  \\d+
         Set To Dictionary       ${SONOBUOY_IMGS['e2e']}  name=validation:kube-conformance-v${major[0]}.${minor[0]}
 
 Onboard Images
index 6651ddc..65a154d 100644 (file)
@@ -33,7 +33,7 @@ ${REPORTDIR}        ${LOG_PATH}/${SUITE_NAME.replace(' ','_')}
 *** Keywords ***
 Open Connection And Log In
     Open Connection  ${HOST}
-    Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}
+    Run Keyword IF  '${SSH_KEYFILE}' != 'None'  Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}  ELSE IF  '${PASSWORD}' != 'None'  Login  ${USERNAME}  ${PASSWORD}  ELSE  FAIL
 
 Get Cluster Address
     ${result}=        Run Process  kubectl  config  view  --minify
index de05d8d..a51af7f 100644 (file)
@@ -47,7 +47,7 @@ Run Lynis Audit System
 *** Keywords ***
 Open Connection And Log In
     Open Connection  ${HOST}
-    Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}
+    Run Keyword IF  '${SSH_KEYFILE}' != 'None'  Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}  ELSE IF  '${PASSWORD}' != 'None'  Login  ${USERNAME}  ${PASSWORD}  ELSE  FAIL
 
 Install Lynis
     [Documentation]  Install Lynis
index d79fab9..0847322 100644 (file)
@@ -25,8 +25,8 @@ Suite Teardown    Close All Connections
 *** Test Cases ***
 Run Vuls test
     Set Environment Variable  GOROOT  /root/go
-    Set Environment Variable  GOPATH  /root/go/src
-    Set Environment Variable  PATH  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/go/bin:/root/go/src/bin
+    Set Environment Variable  GOPATH  /root/go/src/github.com
+    Set Environment Variable  PATH  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/go/bin:/root/go/src/github.com/bin
     Set Environment Variable  LC_ALL  en_US.UTF-8
     Set Environment Variable  LANG  en_US.UTF-8
 
@@ -41,6 +41,8 @@ Run Vuls test
 
     ${os} =  SSHLibrary.Execute Command   source /etc/os-release && echo $ID
 
+    Run Keyword IF  '${SSH_KEYFILE}' == 'None'  Create ssh_keyfile
+
     ${rc} =  Run And Return Rc  vuls scan -config ${CURDIR}/config.toml -ssh-config
     Should Be Equal As Integers  ${rc}  0
 
@@ -50,6 +52,8 @@ Run Vuls test
     Run Keyword If  '${status}' == 'False'  FAIL  Vulnerabilities discovered
     ...                     non-critical
 
+    Run Keyword IF  '${SSH_KEYFILE}' == 'None'  Cleanup ssh
+
 *** Keywords ***
 Run vuls for ubuntu
     ${os_version} =  SSHLibrary.Execute Command  source /etc/os-release && echo $VERSION_ID | cut -d '.' -f1
@@ -65,6 +69,19 @@ Run vuls for centos
     Append To File  ${LOG_PATH}/vuls.log  ${output}${\n}
     Set Global Variable  ${LOG}  ${output}
 
+Create ssh_keyfile
+    ${rc} =  Run And Return Rc  ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N ""
+    Should Be Equal As Integers  ${rc}  0
+
+    ${rc} =  Run and Return Rc  sshpass -p '${PASSWORD}' ssh-copy-id -i /root/.ssh/id_rsa.pub '${USERNAME}'@'${HOST}'
+    Should Be Equal As Integers  ${rc}  0
+
+Cleanup ssh
+    ${rc}  ${idssh} =  Run And Return Rc And Output  cat /root/.ssh/id_rsa.pub
+    Should Be Equal As Integers  ${rc}  0
+    ${rc} =  Run And Return Rc  ssh '${USERNAME}'@'${HOST}' "sed -i 's#${idssh}##' ~/.ssh/authorized_keys"
+    Should Be Equal As Integers  ${rc}  0
+
 Open Connection And Log In
     Open Connection  ${HOST}
-    Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}
+    Run Keyword IF  '${SSH_KEYFILE}' != 'None'  Login With Public Key  ${USERNAME}  ${SSH_KEYFILE}  ELSE IF  '${PASSWORD}' != 'None'  Login  ${USERNAME}  ${PASSWORD}  ELSE  FAIL
index 4a68a51..4ba17b4 100644 (file)
@@ -31,7 +31,8 @@
 ### Input variables cluster's master host
 host: 172.28.17.206             # cluster's master host address
 username: cloudadmin            # login name to connect to cluster
-ssh_keyfile: /root/.ssh/id_rsa  # Identity file for authentication
+password: cloudpassword         # login password to connect to cluster
+ssh_keyfile: ssh_keyfile        # Identity file for authentication
 
 ### bluval.py adds/modifies following, before passing to robot.
 ### while debugging from CLI user has to modify these
@@ -40,6 +41,7 @@ ssh_keyfile: /root/.ssh/id_rsa  # Identity file for authentication
 ### Input variables for bios_version_dell.robot
 sysinfo: PowerEdge R740xd
 bios_revision: 1.3
+blk_dev_regexp: ([sh]d[a-z]+|nvme)[0-9]+
 
 ### Input variables for bare metal hardware test dell or hp
 base_uri: https://192.168.XX.XX/redfish/v1/   # OOB Redfish link address