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

Add a containerized helmExport offering #61

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
58 changes: 58 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest AS build

ENV PKGMGR="microdnf"
# TEMP_DIR is the directory to store temporary downloads, etc.
ENV TEMP_DIR="/tmp"

# Set up Runtime Dependencies, which should not be removed.
RUN ${PKGMGR} install -y python3

# Set up Install Time Dependencies, which can be removed later.
RUN ${PKGMGR} install -y git make tar wget

# Set up pip
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
python3 get-pip.py --user
# Set up ansible-galaxy
RUN python3 -m pip install ansible

# Install Go binary and add to PATH
ENV GO_DL_URL="https://golang.org/dl"
ENV GO_BIN_TAR="go1.14.12.linux-amd64.tar.gz"
ENV GO_BIN_URL_x86_64=${GO_DL_URL}/${GO_BIN_TAR}
ENV GOPATH="/root/go"
RUN if [[ "$(uname -m)" -eq "x86_64" ]] ; then \
wget --directory-prefix=${TEMP_DIR} ${GO_BIN_URL_x86_64} && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf ${TEMP_DIR}/${GO_BIN_TAR}; \
else \
echo "CPU architecture not supported" && exit 1; \
fi
ENV PATH=${PATH}:"/usr/local/go/bin"

ENV HELM_EXPORT_BUILD_DIR=/usr/helm-ansible-template-exporter
ENV HELM_EXPORT_SRC_DIR=${HELM_EXPORT_BUILD_DIR}/src

ARG HELM_EXPORT_TAG
ARG HELM_EXPORT_SRC_URL=https://github.com/redhat-nfvpe/helm-ansible-template-exporter
ARG GIT_CHECKOUT_TARGET=${HELM_EXPORT_TAG}

# Clone the Helm Ansible Template Exporter source repository and checkout the target branch/tag/commit
RUN git clone --no-single-branch --depth=1 ${HELM_EXPORT_SRC_URL} ${HELM_EXPORT_SRC_DIR}
RUN git -C ${HELM_EXPORT_SRC_DIR} fetch origin ${GIT_CHECKOUT_TARGET}
RUN git -C ${HELM_EXPORT_SRC_DIR} checkout ${GIT_CHECKOUT_TARGET}

WORKDIR ${HELM_EXPORT_SRC_DIR}
RUN make all
ENV HELM_EXPORT_EXECUTABLE="helmExport"
ENV HELM_EXPORT_BIN=/usr/local/helmExport/bin
RUN mkdir -p ${HELM_EXPORT_BIN} && \
cp ${HELM_EXPORT_SRC_DIR}/${HELM_EXPORT_EXECUTABLE} ${HELM_EXPORT_BIN}

RUN ${PKGMGR} remove -y make tar wget && \
Copy link
Member

@aneeshkp aneeshkp Jul 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we use Multi-stage build here?
Example
FROM golang:1.14.3-alpine AS build
Copy the entire project and build it
This layer is rebuilt when a file changes in the project directory
COPY . /go/src/project/
RUN go build -o /bin/project

This results in a single layer image
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]

rm -rf ${TMP_DIR} && \
rm -rf /root/.cache && \
rm -rf /root/go/pkg && \
rm -rf /root/go/src && \
rm -rf /usr/lib/golang/pkg && \
rm -rf /usr/lib/golang/src
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Go Templates provide "template" and "include" in order to support dynamic templa
replacement, and although there are some similar constructs, helmExport currently doesn't support any conversion.
Instead, consider using Ansible defaults as a replacement.

### Building The Exporter
### Building The Exporter Binary

To build the code, use the following command:

Expand All @@ -86,7 +86,17 @@ To clean the code base, use the following command:
make clean
```

### Running the Exporter
### Building the Exporter Container Image

To build the `helm-export` docker image, issue the following command:

```shell script
export HELM_EXPORT_VERSION="v1.0.0"
export HELM_EXPORT_TAG="master"
docker build -t helm-export:${HELM_EXPORT_VERSION} --build-arg HELM_EXPORT_TAG=${HELM_EXPORT_TAG} .
```

### Running the Exporter built from Source

#### Runtime Dependencies

Expand All @@ -109,6 +119,16 @@ Alternatively:
./helmExport export nginx --helm-chart=./example --workspace=./workspace --generateFilters=true --emitKeysSnakeCase=true
```

### Running the Exporter Container

These instructions assume you have already built or pulled the container image. To run the image, use the
`helmExport.sh` utility script similar to the following:

```shell script
./helmExport.sh -c $(pwd)/examples/helmcharts/nginx -w $(pwd)/output -r nginx
```


### Testing the Ansible Playbook Role

Ansible Operators are deployed using the
Expand Down
122 changes: 122 additions & 0 deletions helmExport.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env bash

#
# helmExport.sh
#
# Given an input Helm chart directory, an output workspace directory, and an output role name, helmExport.sh makes a
# best effort conversion of the input Helm chart to a corresponding Ansible Role.
#

CONTAINER_CHART_PATH="/chart"
CONTAINER_WORKSPACE_PATH="/workspace"

HELM_EXPORT_EXECUTABLE="helmExport"
HELM_EXPORT_BIN="/usr/local/helmExport/bin"
HELM_EXPORT_PATH="${HELM_EXPORT_BIN}/${HELM_EXPORT_EXECUTABLE}"

export REQUIRED_VARS=('HELM_CHART_PATH' 'OUTPUT_PATH' 'EMITTED_ROLE')
export REQUIRED_VARS_ERROR_MESSAGES=(
'HELM_CHART_PATH is invalid or not given. Use the -c option to provide path to the input helm chart.'
'OUTPUT_PATH is required. Use the -w option to specify the directory containing the output workspace.'
'EMITTED_ROLE is required. Use the -r option to specify the output Ansible Role name.'
)

# outputs a welcome banner to stdout
output_welcome_banner() {
echo "Helm Ansible Template Exporter}"
}

# usage contains usage information
usage() {
read -d '' usage_prompt <<- EOF
Usage: $0 -c HELM_CHART_PATH -w OUTPUT_PATH -r EMITTED_ROLE

Export a helm chart as an Ansible Role. Note, not all cases are covered, and this tool is considered best effort.

Options (required)
-c: set the directory containing the input helm chart
-w: set the output working directory where the Ansible Playbook Role is emitted
-r: set the name of the role for the generated Ansible Playbook Role
EOF

echo -e "$usage_prompt"
}

# usage_error emits the usage message and then exits with exit code 1.
usage_error() {
usage
exit 1
}

# check_required_vars checks that the required bash arguments have been provided.
check_required_vars() {
local var_missing=false

for index in "${!REQUIRED_VARS[@]}"; do
var=${REQUIRED_VARS[$index]}
if [[ -z ${!var} ]]; then
error_message=${REQUIRED_VARS_ERROR_MESSAGES[$index]}
echo "$0: error: $error_message" 1>&2
var_missing=true
fi
done

if $var_missing; then
echo ""
usage_error
fi
}

# parse_cli_args parses the input CLI arguments.
parse_cli_args() {
# Parse args beginning with -
while [[ "$1" == -* ]]; do
echo "$1 $2"
case "$1" in
-h|--help|-\?) usage; exit 0;;
-c) if (($# > 1)); then
export HELM_CHART_PATH="$2"
shift 2
else
echo "-c requires an argument" 1>&2
exit 1
fi ;;
-w) if (($# > 1)); then
export OUTPUT_PATH="$2"; shift 2
else
echo "-w requires an argument" 1>&2
exit 1
fi ;;
-r) if (($# > 1)); then
export EMITTED_ROLE="$2"; shift 2
else
echo "-r requires an argument" 1>&2
exit 1
fi ;;
--) shift; break;;
-*) echo "invalid option: $1" 1>&2; usage_error;;
esac
done
}

# check_output_dir ensures that there isn't a generated role already in place in the output working directory.
check_output_dir() {
if [ -d "${OUTPUT_PATH}/${EMITTED_ROLE}" ]
then
echo "output directory \"${OUTPUT_PATH}/${EMITTED_ROLE}\" already has a generated role; delete or change the output directory before proceeding"
exit 2
else
echo "Ansible Role \"${EMITTED_ROLE}\" will be generated in \"${OUTPUT_PATH}\""
fi
}

output_welcome_banner
parse_cli_args "$@"
check_required_vars
mkdir -p "${OUTPUT_PATH}"
check_output_dir

# runs the conversion utility
docker run -v "${HELM_CHART_PATH}":"${CONTAINER_CHART_PATH}":Z \
-v "${OUTPUT_PATH}":"${CONTAINER_WORKSPACE_PATH}":Z \
helm-export:v1.0.0 "${HELM_EXPORT_PATH}" export "${EMITTED_ROLE}" --helm-chart="${CONTAINER_CHART_PATH}" --workspace="${CONTAINER_WORKSPACE_PATH}" 2> "${OUTPUT_PATH}/${EMITTED_ROLE}-conversion-log.txt"