Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generate fips compliant container image for Harvest #3113

Merged
merged 3 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.PHONY: help deps clean build test fmt lint package asup dev fetch-asup ci

SHELL := /bin/bash
REQUIRED_GO_VERSION := 1.22
REQUIRED_GO_VERSION := 1.23
GOLANGCI_LINT_VERSION := latest
GOVULNCHECK_VERSION := latest
ifneq (, $(shell which go))
Expand Down Expand Up @@ -40,6 +40,9 @@ ifneq (,$(wildcard $(HARVEST_ENV)))
export $(shell sed '/^\#/d; s/=.*//' $(HARVEST_ENV))
endif

# FIPS flag
FIPS ?= 0

help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-11s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

Expand Down Expand Up @@ -100,9 +103,13 @@ all: package ## Build, Test, Package
harvest: deps
@mkdir -p bin
@# Build the harvest and poller cli
ifeq ($(FIPS), 1)
@echo "Building with BoringCrypto (FIPS compliance)"
GOEXPERIMENT=boringcrypto GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=1 go build -trimpath -tags boringcrypto -o bin -ldflags=$(LD_FLAGS) ./cmd/harvest ./cmd/poller
else
@echo "Building"
@GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=$(CGO_ENABLED) go build -trimpath -o bin -ldflags=$(LD_FLAGS) ./cmd/harvest ./cmd/poller

endif
@cp service/contrib/grafana bin; chmod +x bin/grafana

###############################################################################
Expand Down Expand Up @@ -131,7 +138,7 @@ asup:
else\
git clone -b ${BRANCH} https://${GIT_TOKEN}@github.com/NetApp/harvest-private.git ${ASUP_TMP};\
fi
@cd ${ASUP_TMP}/harvest-asup && CGO_ENABLED=0 make ${ASUP_MAKE_TARGET} VERSION=${VERSION} RELEASE=${RELEASE}
@cd ${ASUP_TMP}/harvest-asup && make ${ASUP_MAKE_TARGET} VERSION=${VERSION} RELEASE=${RELEASE} FIPS=${FIPS}
@mkdir -p ${CURRENT_DIR}/autosupport
@cp ${ASUP_TMP}/harvest-asup/bin/asup ${CURRENT_DIR}/autosupport

Expand Down
7 changes: 7 additions & 0 deletions cmd/harvest/fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build boringcrypto

package main

import (
_ "crypto/tls/fipsonly"
)
7 changes: 7 additions & 0 deletions cmd/poller/fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build boringcrypto

package main

import (
_ "crypto/tls/fipsonly"
)
31 changes: 21 additions & 10 deletions container/onePollerPerContainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ARG BUILD_DIR=/opt/home
ARG VERSION=2.0
ARG RELEASE=nightly
ARG ASUP_MAKE_TARGET=build
ARG FIPS=0

# Set the Current Working Directory inside the container
WORKDIR $BUILD_DIR
Expand All @@ -19,25 +20,35 @@ COPY . .

RUN --mount=type=secret,id=git_token \
if [[ -n "$ASUP_MAKE_TARGET" && -f "/run/secrets/git_token" ]]; then \
GIT_TOKEN=$(cat /run/secrets/git_token) && \
make build asup VERSION=$VERSION RELEASE=$RELEASE ASUP_MAKE_TARGET=$ASUP_MAKE_TARGET GIT_TOKEN=$GIT_TOKEN ; \
make build asup VERSION=$VERSION RELEASE=$RELEASE ASUP_MAKE_TARGET=$ASUP_MAKE_TARGET GIT_TOKEN=$(cat /run/secrets/git_token) FIPS=$FIPS ; \
else \
make build VERSION=$VERSION RELEASE=$RELEASE BIN_PLATFORM=linux ;\
make build VERSION=$VERSION RELEASE=$RELEASE BIN_PLATFORM=linux FIPS=$FIPS ;\
fi

RUN cp -a $BUILD_DIR/harvest.yml $INSTALL_DIR/harvest.yml.example

RUN cp -aR bin $BUILD_DIR/conf $BUILD_DIR/grafana $BUILD_DIR/autosupport $BUILD_DIR/prom-stack.tmpl $INSTALL_DIR

RUN cp -a $BUILD_DIR/container/onePollerPerContainer/docker-compose.tmpl $INSTALL_DIR/container/onePollerPerContainer

RUN cp -aR $BUILD_DIR/container/prometheus $INSTALL_DIR/container/
RUN cp -a $BUILD_DIR/harvest.yml $INSTALL_DIR/harvest.yml.example \
&& cp -aR bin $BUILD_DIR/conf $BUILD_DIR/grafana $BUILD_DIR/autosupport $BUILD_DIR/prom-stack.tmpl $INSTALL_DIR \
&& cp -a $BUILD_DIR/container/onePollerPerContainer/docker-compose.tmpl $INSTALL_DIR/container/onePollerPerContainer \
&& cp -aR $BUILD_DIR/container/prometheus $INSTALL_DIR/container/

# Create directories and conditionally copy .so files if FIPS is enabled
RUN mkdir -p /temp_libs/x86_64-linux-gnu /temp_libs/lib64 && \
if [ "$FIPS" -eq "1" ]; then \
cp /lib/x86_64-linux-gnu/libresolv.so.2 /temp_libs/x86_64-linux-gnu/ && \
cp /lib/x86_64-linux-gnu/libpthread.so.0 /temp_libs/x86_64-linux-gnu/ && \
cp /lib/x86_64-linux-gnu/libc.so.6 /temp_libs/x86_64-linux-gnu/ && \
cp /lib64/ld-linux-x86-64.so.2 /temp_libs/lib64/; \
fi

FROM gcr.io/distroless/static-debian12:debug

ARG INSTALL_DIR=/opt/harvest
ENV HARVEST_DOCKER=yes
COPY --from=builder $INSTALL_DIR $INSTALL_DIR

# Conditionally copy .so files from builder stage if they exist
COPY --from=builder /temp_libs/x86_64-linux-gnu/ /lib/x86_64-linux-gnu/
COPY --from=builder /temp_libs/lib64/ /lib64/

WORKDIR $INSTALL_DIR

ENTRYPOINT ["bin/poller"]
74 changes: 68 additions & 6 deletions integration/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ pipeline {
string(name: 'VERSION', defaultValue: '', description: 'Version')
string(name: 'BRANCH', defaultValue: 'main', description: '[Optional] Branch name to clone. Default (main) ')
string(name: 'DOCKER', defaultValue: '', description: 'http url of docker tar build or docker image')
string(name: 'DOCKER_FIPS', defaultValue: '', description: 'http url of fips complaint docker tar build or docker image')
string(name: 'RPM', defaultValue: '', description: 'http url of rpm file')
string(name: 'NATIVE', defaultValue: '', description: 'http url of native tar file')
}
environment {
BUILD_ID="dontKillMe"
JENKINS_NODE_COOKIE="dontKillMe"
}

stages {
stage('Setup') {
agent {
Expand Down Expand Up @@ -150,7 +151,7 @@ pipeline {
agent {
label "docker"
}
stages('Test on docker Pkg') {
stages('Test on Docker Pkg') {
stage('Setup') {
steps {
printNodeInfo()
Expand All @@ -162,7 +163,7 @@ pipeline {
stage('Install Docker') {
steps {
sh '''
echo "Installing"
echo "Installing Docker"
curl -O $DOCKER && docker load -i docker_harvest.tar
rm -rf $WORKSPACE/docker
mkdir $WORKSPACE/docker
Expand All @@ -172,9 +173,10 @@ pipeline {
--entrypoint "bin/harvest" \
--volume "$(pwd):/opt/temp" \
--volume "$(pwd)/harvest.yml:/opt/harvest/harvest.yml" \
ghcr.io/netapp/harvest \
ghcr.io/netapp/harvest:latest \
generate docker full \
--output harvest-compose.yml
--output harvest-compose.yml \
--image ghcr.io/netapp/harvest:latest
docker compose -f prom-stack.yml -f harvest-compose.yml up -d --remove-orphans
sleep 1m
INSTALL_DOCKER=1 bash $WORKSPACE/harvest/integration/test/test.sh
Expand Down Expand Up @@ -205,6 +207,66 @@ pipeline {
}
}
}
stage('DOCKER_FIPS') {
agent {
label "docker"
}
stages('Test on Docker FIPS Pkg') {
stage('Setup') {
steps {
printNodeInfo()
cleanWs()
stopAndRemoveDockers()
setupWorkspace()
}
}
stage('Install Docker FIPS') {
steps {
sh '''
echo "Installing Docker FIPS"
curl -O $DOCKER_FIPS && docker load -i docker_harvest_fips.tar
rm -rf $WORKSPACE/docker
mkdir $WORKSPACE/docker
cd $WORKSPACE/docker
cp -rf $WORKSPACE/harvest/integration/test/harvest.yml .
docker run --rm \
--entrypoint "bin/harvest" \
--volume "$(pwd):/opt/temp" \
--volume "$(pwd)/harvest.yml:/opt/harvest/harvest.yml" \
ghcr.io/netapp/harvest:latest-fips \
generate docker full \
--output harvest-compose.yml \
--image ghcr.io/netapp/harvest:latest-fips
docker compose -f prom-stack.yml -f harvest-compose.yml up -d --remove-orphans
sleep 1m
INSTALL_DOCKER=1 bash $WORKSPACE/harvest/integration/test/test.sh
'''
}
}
stage('Running Test') {
steps {
sh """
export VERSION=$VERSION
REGRESSION=1 bash $WORKSPACE/harvest/integration/test/test.sh
"""

}
post {
always {
sh """
COPY_DOCKER_LOGS=1 bash $WORKSPACE/harvest/integration/test/test.sh
rm -f docker_fips_logs.zip
zip -r docker_fips_logs.zip /var/log/harvest
cd $WORKSPACE/docker
ANALYZE_DOCKER_LOGS=1 bash $WORKSPACE/harvest/integration/test/test.sh
docker ps -q | xargs docker stop | xargs docker rm --force
"""
archiveArtifacts artifacts: "docker_fips_logs.zip", fingerprint: true
}
}
}
}
}
}
}
}
Expand Down Expand Up @@ -238,4 +300,4 @@ def void printNodeInfo() {
socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
nodeIp = socket.getLocalAddress().getHostAddress();
println("The Node IP Address is: ${nodeIp}")
}
}
Loading