from bluutil import BluvalError
from bluutil import ShowStopperError
+_PULL = False
_OPTIONAL_ALSO = False
_SUBNET = ""
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:
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:
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
Options:
-l, --layer TEXT
-n, --network TEXT
+ -t, --tag TEXT
-o, --optional_also
--help Show this message and exit.'
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" "$@"
--- /dev/null
+---
+##############################################################################
+# 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"
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":
--- /dev/null
+# 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/
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
# 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 && \
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 && \
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 \
#${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}
[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}
${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
*** 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
*** 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
*** 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
${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
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
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
### 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
### 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