From 274d19af19e333a24ccf9f5cee155b97fcb753fd Mon Sep 17 00:00:00 2001 From: JonZeolla Date: Tue, 9 Jan 2024 20:40:27 -0500 Subject: [PATCH] feat: add support for bitbucket pipes (#317) --- build/common.sh | 15 ++++++++++ build/docker-entrypoint.sh | 8 ++++- docs/BitBucket/index.rst | 60 ++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + pipe.yml | 27 +++++++++++++++++ setup.cfg | 4 +++ tests/test.py | 32 ++++++++++++++++++++ 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 docs/BitBucket/index.rst create mode 100644 pipe.yml diff --git a/build/common.sh b/build/common.sh index 9fc10ea3..151a2833 100755 --- a/build/common.sh +++ b/build/common.sh @@ -273,3 +273,18 @@ function _clone() { clone_log="/var/log/clone.log" echo "$(date): Cloned ${folder_count} folders" >> "${clone_log}" } + +function pipeline_setup() { + # Returns a custom command if a supported custom pipeline is detected, empty otherwise + + # Quit early if this is not a Bitbucket pipeline + if [[ -z "${BITBUCKET_BUILD_NUMBER}" ]]; then + return + fi + + if [[ -n "${COMMAND}" ]]; then + echo "${COMMAND}" + else + echo "terraform validate" + fi +} diff --git a/build/docker-entrypoint.sh b/build/docker-entrypoint.sh index 5109e24d..e70dfa4f 100755 --- a/build/docker-entrypoint.sh +++ b/build/docker-entrypoint.sh @@ -44,7 +44,13 @@ if [[ -x "$(which strace)" ]]; then fi fi -if [ "$#" -eq 0 ]; then +# Pipeline-specific detection and setup steps +custom_command=$(pipeline_setup) + +if [[ -n "${custom_command}" ]]; then + # Run the command provided + eval "${custom_command}" +elif [ "$#" -eq 0 ]; then # Print select tool versions then open an bash shell if [ -x "$(which aws)" ]; then echo -e "aws-cli\t\t ${AWS_CLI_VERSION}" diff --git a/docs/BitBucket/index.rst b/docs/BitBucket/index.rst new file mode 100644 index 00000000..b29667cf --- /dev/null +++ b/docs/BitBucket/index.rst @@ -0,0 +1,60 @@ +********* +BitBucket +********* + +``easy_infra`` can be used as a BitBucket pipe. + +Using the pipe +-------------- + +An example ``bitbucket-pipeline.yml`` is as follows:: + + --- + image: + name: atlassian/default-image:4 + + test: &test + step: + name: Test + services: + - docker + script: + - pipe: docker://seisollc/easy_infra:2024.01.01-terraform + + pipelines: + default: + - <<: *test + +Configuring the pipe +-------------------- + +The pipe accepts the following variables:: + ++-----------------------+------------------------+------------------------------------------------------------+ +| Variable | Default | Result | ++=======================+========================+============================================================+ +| ``COMMAND`` | ``terraform validate`` | Sets the command to run in the ``easy_infra`` container | ++-----------------------+------------------------+------------------------------------------------------------+ +| ``LEARNING_MODE`` | ``false`` | Sets ``LEARNING_MODE`` in the ``easy_infra`` container | ++-----------------------+------------------------+------------------------------------------------------------+ +| ``TERRAFORM_VERSION`` | N/A | Sets ``TERRAFORM_VERSION`` in the ``easy_infra`` container | ++-----------------------+------------------------+------------------------------------------------------------+ + +For example:: + + --- + deploy: &deploy + step: + name: Deploy + services: + - docker + script: + - pipe: docker://seisollc/easy_infra:2024.01.01-terraform + variables: + COMMAND: /bin/bash -c "terraform plan -out=plan.out && terraform apply -auto-approve plan.out" + LEARNING_MODE: true + TERRAFORM_VERSION: 1.6.6 + + pipelines: + default: + - <<: *deploy diff --git a/docs/index.rst b/docs/index.rst index f70c7ccf..b9e04949 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,4 +14,5 @@ Logging/index Hooks/index Cloning/index + BitBucket/index Technical Details/index diff --git a/pipe.yml b/pipe.yml new file mode 100644 index 00000000..36fd30e2 --- /dev/null +++ b/pipe.yml @@ -0,0 +1,27 @@ +--- +NOTICE: | + This is just for illustrative purposes; BitBucket requires that pipe.yml files be hosted on bitbucket so we use `pipe: docker://` in our examples to go direct + to Docker Hub, bypassing the use of this file. +--- +name: Easy Infra (terraform) +description: A docker container to simplify and secure the use of Infrastructure as Code (IaC) +image: seiso/easy_infra:2024.01.01-terraform +category: Security +repository: https://github.com/seisollc/easy_infra +maintainer: + name: Seiso + website: https://SeisoLLC.com/ +vendor: + name: Seiso + website: https://SeisoLLC.com/ +variables: + - name: COMMAND + default: "terraform validate" + - name: LEARNING_MODE + default: "false" + - name: TERRAFORM_VERSION + default: "$TERRAFORM_VERSION" +tags: + - seiso + - security + - terraform diff --git a/setup.cfg b/setup.cfg index 44a9c457..3e09981d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -18,3 +18,7 @@ url = "https://github.com/SeisoLLC/easy_infra" [bumpversion:file:easy_infra/__init__.py] [bumpversion:file:docs/conf.py] + +[bumpversion:file:docs/BitBucket/index.rst] + +[bumpversion:file:pipe.yml] diff --git a/tests/test.py b/tests/test.py index d37dbc4d..ad0ebeeb 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1403,6 +1403,38 @@ def run_terraform(*, image: str, user: str, mount_local_files: bool) -> None: tests=tests, volumes=hooks_script_volumes, image=image, user=user ) + # Test the custom "COMMAND" feature used with bitbucket pipes + tests: list[tuple[dict, str, int]] = [ # type: ignore + ( + { + "BITBUCKET_BUILD_NUMBER": "mustexist", # Prereq to allow it to continue + "COMMAND": "ls", + }, + "exit 230", # This should be overridden by COMMAND + 0, + ), + ( + { + "BITBUCKET_BUILD_NUMBER": "mustexist", # Prereq to allow it to continue + "COMMAND": "", + }, + "exit 230", # Because BITBUCKET_BUILD_NUMBER was set, even though COMMAND is empty, this will be ignored + 0, # This falls back to the built-in default command when a BitBucket pipeline is detected which exits neither 230 nor 1, but 0 + ), + ( + { + "COMMAND": "exit 230", # BITBUCKET_BUILD_NUMBER is purposefully missing, so this should be skipped + }, + "exit 1", + 1, + ), + ] + + LOG.debug("Testing the bitbucket pipe detection and COMMAND variable") + num_tests_ran += exec_tests( + tests=tests, volumes=hooks_script_volumes, image=image, user=user + ) + tests: list[tuple[dict, str, int]] = [ # type: ignore ( {