diff --git a/.github/workflows/build-pgaudit.yml b/.github/workflows/build-pgaudit.yml new file mode 100644 index 0000000..ab743c9 --- /dev/null +++ b/.github/workflows/build-pgaudit.yml @@ -0,0 +1,205 @@ +name: Build pgaudit Extension + +on: + push: + paths: + - 'pgaudit/**' + workflow_call: + inputs: + pgaudit-version: + required: true + type: string + pg-version: + required: false + type: string + default: "18" + distro: + required: false + type: string + default: "bookworm" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Clone pgaudit source + if: github.event_name == 'workflow_call' + run: | + git clone https://github.com/pgaudit/pgaudit.git pgaudit/source + cd pgaudit/source + git checkout ${{ inputs.pgaudit-version }} + + - name: Get latest pgaudit version for push + if: github.event_name == 'push' + id: version + run: | + LATEST=$(curl -s https://api.github.com/repos/pgaudit/pgaudit/releases/latest | jq -r '.tag_name') + echo "version=${LATEST}" >> $GITHUB_OUTPUT + git clone https://github.com/pgaudit/pgaudit.git pgaudit/source + cd pgaudit/source + git checkout ${LATEST} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + run: | + cd pgaudit + PGAUDIT_VER="${{ inputs.pgaudit-version || steps.version.outputs.version }}" + + # Choose target and set variables based on branch + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + # Build all combinations for main branch + REGISTRY="ghcr.io/${{ github.repository_owner }}" \ + PGAUDIT_VERSION="${PGAUDIT_VER}" \ + docker buildx bake \ + --set "*.context=source" \ + --set "*.args.PGAUDIT_VERSION=${PGAUDIT_VER}" \ + pgaudit-all \ + --push + else + # Build single combination for feature branch + TARGET="pgaudit-feature" + REGISTRY="ghcr.io/${{ github.repository_owner }}" \ + PG_VERSION="${{ inputs.pg-version || '18' }}" \ + DISTRO="${{ inputs.distro || 'bookworm' }}" \ + PGAUDIT_VERSION="${PGAUDIT_VER}" \ + BRANCH_NAME="${{ github.ref_name }}" \ + docker buildx bake \ + --set pgaudit-feature.context=source \ + --set "*.args.PG_VERSION=${{ inputs.pg-version || '18' }}" \ + --set "*.args.DISTRO=${{ inputs.distro || 'bookworm' }}" \ + --set "*.args.PGAUDIT_VERSION=${PGAUDIT_VER}" \ + ${TARGET} \ + --push + fi + + smoke-test: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Get version from build + id: get-version + run: | + if [ "${{ github.event_name }}" = "workflow_call" ]; then + echo "version=${{ inputs.pgaudit-version }}" >> $GITHUB_OUTPUT + else + LATEST=$(curl -s https://api.github.com/repos/pgaudit/pgaudit/releases/latest | jq -r '.tag_name') + echo "version=${LATEST}" >> $GITHUB_OUTPUT + fi + + - name: Setup Kind Cluster + uses: helm/kind-action@v1 + with: + version: v0.30.0 + kubectl_version: v1.34.0 + node_image: kindest/node:v1.34.0 + config: kind-config.yaml + + + # - name: Check Kind Cluster Status + # run: | + # echo "Kind cluster 'kind' is ready." + # kubectl cluster-info + # kubectl get nodes + + - name: Install CloudNativePG Operator + run: | + # Get latest CNPG release + CNPG_VERSION=$(curl -s https://api.github.com/repos/cloudnative-pg/cloudnative-pg/releases/latest | jq -r '.tag_name') + echo "Installing CloudNativePG operator version: ${CNPG_VERSION}" + + # Extract version without 'v' prefix for branch name + BRANCH_VERSION=$(echo ${CNPG_VERSION} | sed 's/^v//' | cut -d. -f1,2) + + # Install CNPG operator using correct URL format + kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-${BRANCH_VERSION}/releases/cnpg-${CNPG_VERSION#v}.yaml + + - name: Verify CNPG Operator Installation + run: | + # Wait for operator deployment to be ready + kubectl wait --for=condition=Available deployment/cnpg-controller-manager -n cnpg-system --timeout=120s + + # Check operator status + kubectl get pods -n cnpg-system + kubectl get deployment -n cnpg-system + + # Verify CRDs are installed + kubectl get crd | grep postgresql + + echo "✅ CloudNativePG operator installed successfully" + + - name: Create Postgres Cluster with Extension + run: | + PG_VER="${{ inputs.pg-version || '18' }}" + DISTRO="${{ inputs.distro || 'bookworm' }}" + PGAUDIT_VER="${{ steps.get-version.outputs.version }}" + + # Set image tag based on branch + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + IMAGE_TAG="ghcr.io/${{ github.repository_owner }}/pgaudit:${PG_VER}-${PGAUDIT_VER}-${DISTRO}" + else + IMAGE_TAG="ghcr.io/${{ github.repository_owner }}/pgaudit:${PG_VER}-${PGAUDIT_VER}-${{ github.ref_name }}-${DISTRO}" + fi + + echo "Testing with image: ${IMAGE_TAG}" + + # Create test pod with pgaudit extension + kubectl apply -f - <> $GITHUB_OUTPUT + else + echo "New version found: ${LATEST}" + echo "new-version=${LATEST}" >> $GITHUB_OUTPUT + echo "should-build=true" >> $GITHUB_OUTPUT + fi + + build-and-test: + needs: check-release + if: needs.check-release.outputs.should-build == 'true' + uses: ./.github/workflows/build-pgaudit.yml + with: + pgaudit-version: ${{ needs.check-release.outputs.new-version }} + secrets: inherit \ No newline at end of file diff --git a/README.md b/README.md index 071c41a..2d66017 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ in CloudNativePG. ## Supported Extensions -Currently: **none**. -This repository lays the foundation for packaging extensions going forward. +- **pgaudit** - PostgreSQL Audit Extension for detailed session and object audit logging --- diff --git a/kind-config.yaml b/kind-config.yaml new file mode 100644 index 0000000..a997ec2 --- /dev/null +++ b/kind-config.yaml @@ -0,0 +1,4 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +featureGates: + ImageVolume: true \ No newline at end of file diff --git a/pgaudit/Dockerfile b/pgaudit/Dockerfile new file mode 100644 index 0000000..2bd9384 --- /dev/null +++ b/pgaudit/Dockerfile @@ -0,0 +1,20 @@ +FROM ghcr.io/cloudnative-pg/postgresql:18-minimal-bookworm AS builder + +USER 0 + +COPY . /tmp/pgaudit + +RUN set -eux; \ + mkdir -p /opt/extension && \ + apt-get update && \ + apt-get install -y --no-install-recommends build-essential git "postgresql-server-dev-18=18*" libkrb5-dev libxml2-dev && \ + cd /tmp/pgaudit && \ + git checkout REL_18_STABLE && \ + PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config USE_PGXS=1 make clean && \ + PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config USE_PGXS=1 OPTFLAGS="" make && \ + PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config USE_PGXS=1 make install datadir=/opt/extension/share/ pkglibdir=/opt/extension/lib/ + +FROM scratch + +COPY --from=builder /opt/extension/lib/ /lib/ +COPY --from=builder /opt/extension/share/ /share/ \ No newline at end of file diff --git a/pgaudit/README.md b/pgaudit/README.md new file mode 100644 index 0000000..b12e40e --- /dev/null +++ b/pgaudit/README.md @@ -0,0 +1,44 @@ +# pgaudit Extension + +PostgreSQL Audit Extension for detailed session and object audit logging. + +## Supported Versions + +| PostgreSQL | pgaudit | Distros | Status | +|------------|---------|---------|--------| +| 18 | 18.0 | bookworm, trixie | ✅ Active | + +## Usage + +### PostgreSQL 18 +```yaml +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: postgres-with-pgaudit +spec: + instances: 3 + imageName: ghcr.io/cloudnative-pg/postgresql:18-bookworm + postgresql: + extensions: + - name: pgaudit + image: + reference: ghcr.io/cloudnative-pg/pgaudit:18-18.0-bookworm + parameters: + shared_preload_libraries: "pgaudit" + pgaudit.log: "all" + storage: + size: 1Gi +``` + + + +## Available Images + +- `ghcr.io/cloudnative-pg/pgaudit:18-18.0-bookworm` +- `ghcr.io/cloudnative-pg/pgaudit:18-18.0-trixie` + +## Links + +- [pgaudit Documentation](https://github.com/pgaudit/pgaudit) +- [CloudNativePG Extensions Guide](https://cloudnative-pg.io/documentation/current/imagevolume_extensions/) \ No newline at end of file diff --git a/pgaudit/docker-bake.hcl b/pgaudit/docker-bake.hcl new file mode 100644 index 0000000..d942bf4 --- /dev/null +++ b/pgaudit/docker-bake.hcl @@ -0,0 +1,72 @@ +variable "REGISTRY" { + default = "ghcr.io" +} + + + +variable "PG_VERSION" { + default = "18" +} + +variable "PGAUDIT_VERSION" { + default = "" +} + +variable "DISTROS" { + default = ["bookworm", "trixie"] +} + +variable "DISTRO" { + default = "bookworm" +} + +variable "BRANCH_NAME" { + default = "" +} + +target "pgaudit" { + dockerfile = "../Dockerfile" + tags = [ + "${REGISTRY}/pgaudit:${PG_VERSION}-${PGAUDIT_VERSION}-${formatdate("YYYYMMDDHHMM", timestamp())}-${DISTRO}", + "${REGISTRY}/pgaudit:${PG_VERSION}-${PGAUDIT_VERSION}-${DISTRO}" + ] + args = { + PG_VERSION = PG_VERSION + DISTRO = DISTRO + } +} + +target "pgaudit-feature" { + dockerfile = "../Dockerfile" + tags = [ + "${REGISTRY}/pgaudit:${PG_VERSION}-${PGAUDIT_VERSION}-${BRANCH_NAME}-${DISTRO}" + ] + args = { + PG_VERSION = PG_VERSION + DISTRO = DISTRO + } +} + +# Matrix builds for PG 18 with multiple distros +group "pgaudit-all" { + targets = [ + "pgaudit-18-bookworm", + "pgaudit-18-trixie" + ] +} + +target "pgaudit-18-bookworm" { + inherits = ["pgaudit"] + args = { + PG_VERSION = "18" + DISTRO = "bookworm" + } +} + +target "pgaudit-18-trixie" { + inherits = ["pgaudit"] + args = { + PG_VERSION = "18" + DISTRO = "trixie" + } +} \ No newline at end of file