Skip to content
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
57 changes: 57 additions & 0 deletions .github/workflows/wiremock.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: LocalStack WireMock Extension Tests

on:
pull_request:
branches:
- main
paths:
- 'wiremock/**'
push:
branches:
- main
paths:
- 'wiremock/**'
workflow_dispatch:

env:
LOCALSTACK_DISABLE_EVENTS: "1"
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}

jobs:
integration-tests:
name: Run WireMock Extension Tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Terraform
uses: hashicorp/setup-terraform@v3

- name: Set up LocalStack and extension
run: |
cd wiremock

docker pull localstack/localstack-pro &
docker pull wiremock/wiremock &
docker pull public.ecr.aws/lambda/python:3.9 &
pip install localstack terraform-local awscli-local[ver1]

make install
make dist
localstack extensions -v install file://$(ls ./dist/localstack_wiremock-*.tar.gz)

DEBUG=1 localstack start -d
localstack wait

- name: Run sample app test
run: |
cd wiremock
make sample

- name: Print logs
if: always()
run: |
localstack logs
localstack stop
8 changes: 8 additions & 0 deletions wiremock/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.venv
dist
build
**/*.egg-info
.eggs
.terraform*
terraform.tfstate*
*.zip
54 changes: 54 additions & 0 deletions wiremock/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
VENV_BIN = python3 -m venv
VENV_DIR ?= .venv
VENV_ACTIVATE = $(VENV_DIR)/bin/activate
VENV_RUN = . $(VENV_ACTIVATE)

usage: ## Shows usage for this Makefile
@cat Makefile | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'

venv: $(VENV_ACTIVATE)

$(VENV_ACTIVATE): pyproject.toml
test -d .venv || $(VENV_BIN) .venv
$(VENV_RUN); pip install --upgrade pip setuptools plux
$(VENV_RUN); pip install -e .[dev]
touch $(VENV_DIR)/bin/activate

clean:
rm -rf .venv/
rm -rf build/
rm -rf .eggs/
rm -rf *.egg-info/

install: venv ## Install dependencies
$(VENV_RUN); python -m plux entrypoints

dist: venv ## Create distribution
$(VENV_RUN); python -m build

publish: clean-dist venv dist ## Publish extension to pypi
$(VENV_RUN); pip install --upgrade twine; twine upload dist/*

entrypoints: venv # Generate plugin entrypoints for Python package
$(VENV_RUN); python -m plux entrypoints

format: ## Run ruff to format the whole codebase
$(VENV_RUN); python -m ruff format .; python -m ruff check --output-format=full --fix .

test: ## Run integration tests (requires LocalStack running with the Extension installed)
$(VENV_RUN); pytest tests $(PYTEST_ARGS)

sample: ## Deploy sample app
echo "Creating stubs in WireMock ..."
bin/create-stubs.sh
echo "Deploying sample app into LocalStack via Terraform ..."
(cd sample-app; tflocal init; tflocal apply -auto-approve)
apiId=$$(awslocal apigateway get-rest-apis | jq -r '.items[0].id'); \
endpoint=https://$$apiId.execute-api.us-east-1.localhost.localstack.cloud/dev/time-off; \
echo "Invoking local API Gateway endpoint: $$endpoint"; \
curl -k -v $$endpoint | grep time_off_date

clean-dist: clean
rm -rf dist/

.PHONY: clean clean-dist dist install publish usage venv format test
41 changes: 41 additions & 0 deletions wiremock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
WireMock on LocalStack
========================

This repo contains a [LocalStack Extension](https://github.com/localstack/localstack-extensions) that facilitates developing [WireMock](https://wiremock.org)-based applications locally.

## Prerequisites

* Docker
* LocalStack Pro (free trial available)
* `localstack` CLI
* `make`

## Install from GitHub repository

This extension can be installed directly from this Github repo via:

```bash
localstack extensions install "git+https://github.com/whummer/localstack-utils.git#egg=localstack-wiremock&subdirectory=localstack-wiremock"
```

## Install local development version

To install the extension into localstack in developer mode, you will need Python 3.11, and create a virtual environment in the extensions project.

In the newly generated project, simply run

```bash
make install
```

Then, to enable the extension for LocalStack, run

```bash
localstack extensions dev enable .
```

You can then start LocalStack with `EXTENSION_DEV_MODE=1` to load all enabled extensions:

```bash
EXTENSION_DEV_MODE=1 localstack start
```
22 changes: 22 additions & 0 deletions wiremock/bin/create-stubs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

echo "Downloading WireMock stub definitions..."

# Define the URL for the stub definitions and the temporary file path
STUBS_URL="https://library.wiremock.org/catalog/api/p/personio.de/personio-de-personnel/personio.de-personnel-stubs.json"
TMP_STUBS_FILE="/tmp/personio-stubs.json"

# Define the WireMock server URL
WIREMOCK_URL="http://localhost:8080"

# Download the stub definitions
curl -s -o "$TMP_STUBS_FILE" "$STUBS_URL"

echo "Download complete. Stubs saved to $TMP_STUBS_FILE"
echo "Importing stubs into WireMock..."

# Send a POST request to WireMock's import endpoint with the downloaded file
curl -v -X POST -H "Content-Type: application/json" --data-binary "@$TMP_STUBS_FILE" "$WIREMOCK_URL/__admin/mappings/import"

echo ""
echo "WireMock stub import request sent."
1 change: 1 addition & 0 deletions wiremock/localstack_wiremock/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "localstack_wiremock"
45 changes: 45 additions & 0 deletions wiremock/localstack_wiremock/extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import os

from localstack.utils.container_utils.container_client import Util
from localstack_wiremock.utils.docker import ProxiedDockerContainerExtension


# Environment variable for WireMock Cloud API token - note: if this value is specified, then the
# `wiremock/wiremock-runner` image is being used, otherwise the `wiremock/wiremock` OSS image.
ENV_WIREMOCK_API_TOKEN = "WIREMOCK_API_TOKEN"
# container port for WireMock endpoint - TODO make configurable over time
PORT = 8080


class WireMockExtension(ProxiedDockerContainerExtension):
name = "localstack-wiremock"

HOST = "wiremock.<domain>"
# name of the OSS Docker image
DOCKER_IMAGE = "wiremock/wiremock"
# name of the WireMock Cloud runner Docker image
DOCKER_IMAGE_RUNNER = "wiremock/wiremock-runner"
# name of the container
CONTAINER_NAME = "ls-wiremock"

def __init__(self):
env_vars = {}
image_name = self.DOCKER_IMAGE
kwargs = {}
if api_token := os.getenv(ENV_WIREMOCK_API_TOKEN):
env_vars["WMC_ADMIN_PORT"] = str(PORT)
# TODO remove?
# env_vars["WMC_DEFAULT_MODE"] = "record-many"
env_vars["WMC_API_TOKEN"] = api_token
env_vars["WMC_RUNNER_ENABLED"] = "true"
image_name = self.DOCKER_IMAGE_RUNNER
settings_file = Util.mountable_tmp_file()
# TODO: set configs in YAML file
kwargs["volumes"] = ([(settings_file, "/work/.wiremock/wiremock.yaml")],)
super().__init__(
image_name=image_name,
container_ports=[PORT],
container_name=self.CONTAINER_NAME,
host=self.HOST,
**kwargs,
)
Empty file.
Loading