├── puppetdb
├── conf.d
│ ├── puppetdb.conf
│ ├── config.conf
│ ├── database.conf
│ ├── jetty.ini
│ └── auth.conf
├── healthcheck.sh
├── docker-entrypoint.d
│ ├── 30-certificate-allowlist.sh
│ ├── 20-configure-ssl.sh
│ └── 10-wait-for-hosts.sh
├── docker-entrypoint.sh
├── request-logging.xml
├── puppetdb
├── logback.xml
├── Dockerfile
├── wtfc.sh
└── ssl.sh
├── .rspec
├── .gitignore
├── .markdownlint.json
├── .github
├── labeler.yml
├── CODEOWNERS
├── workflows
│ ├── release.yml
│ ├── labeler.yml
│ ├── security_scanning.yml
│ ├── ci.yaml
│ └── build_docker.yml
├── dependabot.yml
└── release.yml
├── Gemfile
├── Rakefile
├── spec
└── puppetdb_spec.rb
├── RELEASE.md
├── README.md
├── LICENSE
└── CHANGELOG.md
/puppetdb/conf.d/puppetdb.conf:
--------------------------------------------------------------------------------
1 | puppetdb: {
2 | disable-update-checking: 'true'
3 | }
4 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --require pupperware/spec_helper
2 | --format RspecJunitFormatter
3 | --out TEST-rspec.xml
4 | --format documentation
5 |
--------------------------------------------------------------------------------
/puppetdb/conf.d/config.conf:
--------------------------------------------------------------------------------
1 | global: {
2 | vardir: /opt/puppetlabs/server/data/puppetdb
3 | logging-config: /etc/puppetlabs/puppetdb/logback.xml
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | .bundle/
5 | .vendor/
6 | vendor/
7 | Gemfile.lock
8 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | "MD033": {
4 | "allowed_elements": [
5 | "br"
6 | ]
7 | },
8 | "MD013": {
9 | "line_length": 185
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | skip-changelog:
6 | - head-branch: ['^release-*']
7 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | # No matter which file got changed, request a review from the main developers
5 | * @voxpupuli/tools-containerimages
6 |
--------------------------------------------------------------------------------
/puppetdb/healthcheck.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | set -x
4 | set -e
5 |
6 | curl --fail \
7 | --resolve "puppetdb:8080:127.0.0.1" \
8 | "http://puppetdb:8080/status/v1/services/puppetdb-status" \
9 | | grep -q '"state":"running"' \
10 | || exit 1
11 |
--------------------------------------------------------------------------------
/puppetdb/conf.d/database.conf:
--------------------------------------------------------------------------------
1 | database: {
2 | subname: "//"${PUPPETDB_POSTGRES_HOSTNAME}":"${PUPPETDB_POSTGRES_PORT}"/"${PUPPETDB_POSTGRES_DATABASE}
3 | username: ${PUPPETDB_USER}
4 | password: ${PUPPETDB_PASSWORD}
5 | node-ttl: ${PUPPETDB_NODE_TTL}
6 | node-purge-ttl: ${PUPPETDB_NODE_PURGE_TTL}
7 | report-ttl: ${PUPPETDB_REPORT_TTL}
8 | }
9 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Managed by modulesync - DO NOT EDIT
4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
5 |
6 | source ENV['GEM_SOURCE'] || 'https://rubygems.org'
7 |
8 | group :release do
9 | gem 'faraday-retry', '~> 2.1', require: false
10 | gem 'github_changelog_generator', '~> 1.16.4', require: false
11 | end
12 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: Release 🚀
6 |
7 | on:
8 | push:
9 | tags:
10 | - '*'
11 |
12 | jobs:
13 | release:
14 | name: Release
15 | uses: voxpupuli/crafty/.github/workflows/release.yml@main
16 | with:
17 | allowed_owner: voxpupuli
18 |
--------------------------------------------------------------------------------
/.github/workflows/labeler.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: Labeler 🏷️
6 |
7 | on:
8 | - pull_request_target
9 |
10 | jobs:
11 | labeler:
12 | name: Labeler
13 | uses: voxpupuli/crafty/.github/workflows/labeler.yml@main
14 | with:
15 | allowed_owner: ${{ github.repository_owner }}
16 |
--------------------------------------------------------------------------------
/puppetdb/docker-entrypoint.d/30-certificate-allowlist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | hocon() {
4 | /opt/puppetlabs/puppet/lib/ruby/vendor_gems/bin/hocon "$@"
5 | }
6 |
7 | if [ "$PUPPETDB_CERTIFICATE_ALLOWLIST" != "" ]; then
8 | hocon -f /etc/puppetlabs/puppetdb/conf.d/puppetdb.conf set puppetdb.certificate-allowlist certificate-allowlist
9 | IFS=','
10 | for cert in $PUPPETDB_CERTIFICATE_ALLOWLIST; do
11 | echo $cert >> /opt/puppetlabs/server/apps/puppetdb/certificate-allowlist
12 | done
13 | fi
14 |
15 |
--------------------------------------------------------------------------------
/puppetdb/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # bash is required to pass ENV vars with dots as sh cannot
3 |
4 | set -e
5 |
6 | for f in /docker-entrypoint.d/*.sh; do
7 | echo "Running $f"
8 | "$f"
9 | done
10 |
11 | if [ -d /docker-custom-entrypoint.d/ ]; then
12 | find /docker-custom-entrypoint.d/ -type f -name "*.sh" \
13 | -exec chmod +x {} \;
14 | sync
15 | find /docker-custom-entrypoint.d/ -type f -name "*.sh" \
16 | -exec echo Running {} \; -exec {} \;
17 | fi
18 |
19 | exec /opt/puppetlabs/bin/puppetdb "$@"
20 |
--------------------------------------------------------------------------------
/puppetdb/docker-entrypoint.d/20-configure-ssl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | # when certs need to be generated and haven't been user supplied
6 | if [ "$USE_PUPPETSERVER" = true ]; then
7 | # previously DNS_ALT_NAMES was omitted if empty, but ssl.sh already skips setting when empty
8 | DNS_ALT_NAMES="${DNS_ALT_NAMES}" CERTNAME="$CERTNAME" /ssl.sh
9 |
10 | # enable SSL in Jetty
11 | sed -i '/^# ssl-/s/^# //g' /etc/puppetlabs/puppetdb/conf.d/jetty.ini
12 | fi
13 |
14 | if [ -w "$SSLDIR" ] && [ "$(id -un)" = "root" ]; then
15 | # make sure Java apps running as puppetdb can read these files
16 | echo "Setting ownership for $SSLDIR to puppetdb:puppetdb"
17 | chown -R puppetdb:puppetdb ${SSLDIR}
18 | fi
19 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | version: 2
6 | updates:
7 | # raise PRs for gem updates
8 | - package-ecosystem: bundler
9 | directory: "/"
10 | schedule:
11 | interval: daily
12 | time: "13:00"
13 | open-pull-requests-limit: 10
14 |
15 | # Maintain dependencies for GitHub Actions
16 | - package-ecosystem: github-actions
17 | directory: "/"
18 | schedule:
19 | interval: daily
20 | time: "13:00"
21 | open-pull-requests-limit: 10
22 |
23 | - package-ecosystem: "docker"
24 | directory: "/"
25 | schedule:
26 | interval: "daily"
27 | time: "13:00"
28 | open-pull-requests-limit: 10
29 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Managed by modulesync - DO NOT EDIT
4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
5 |
6 | begin
7 | require 'rubygems'
8 | require 'github_changelog_generator/task'
9 | rescue LoadError
10 | # github_changelog_generator isn't available, so we won't define a rake task with it
11 | else
12 | GitHubChangelogGenerator::RakeTask.new :changelog do |config|
13 | config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file."
14 | config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog modulesync github_actions]
15 | config.user = 'voxpupuli'
16 | config.project = 'container-puppetdb'
17 | # get branch name from git and strip off any prefixes (e.g. 'release-')
18 | config.future_release = `git rev-parse --abbrev-ref HEAD`.strip.split('-', 2).last
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/spec/puppetdb_spec.rb:
--------------------------------------------------------------------------------
1 | include Pupperware::SpecHelpers
2 |
3 | # unifies volume naming
4 | ENV['COMPOSE_PROJECT_NAME'] ||= 'puppetdb'
5 | Pupperware::SpecHelpers.load_compose_services = 'postgres,puppet'
6 |
7 | RSpec.configure do |c|
8 | c.before(:suite) do
9 | ENV['PUPPETDB_IMAGE'] = require_test_image
10 | pull_images('puppetdb')
11 | teardown_cluster()
12 | docker_compose_up(preload_certs: true)
13 | end
14 |
15 | c.after(:suite) do
16 | emit_logs
17 | teardown_cluster()
18 | end
19 | end
20 |
21 | describe 'puppetdb container specs' do
22 | it 'should have installed postgres extensions' do
23 | installed_extensions = get_postgres_extensions
24 | expect(installed_extensions).to match(/\s+pg_trgm\s+/)
25 | expect(installed_extensions).to match(/\s+pgcrypto\s+/)
26 | end
27 |
28 | it 'should have started puppetdb' do
29 | expect(get_service_container('puppetdb')).to_not be_empty
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
6 |
7 | changelog:
8 | exclude:
9 | labels:
10 | - duplicate
11 | - invalid
12 | - modulesync
13 | - question
14 | - skip-changelog
15 | - wont-fix
16 | - wontfix
17 |
18 | categories:
19 | - title: Breaking Changes 🛠
20 | labels:
21 | - backwards-incompatible
22 |
23 | - title: New Features 🎉
24 | labels:
25 | - enhancement
26 |
27 | - title: Bug Fixes 🐛
28 | labels:
29 | - bug
30 |
31 | - title: Documentation Updates 📚
32 | labels:
33 | - documentation
34 | - docs
35 |
36 | - title: Dependency Updates ⬆️
37 | labels:
38 | - dependencies
39 |
40 | - title: Other Changes
41 | labels:
42 | - "*"
43 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # Release
2 |
3 | ## On a fork
4 |
5 | Please follow these instructions carefully.
6 | Ensure that you name the branch precisely as `release-vX.Y.Z`
7 | since this nomenclature is crucial for obtaining the `future_version` in the changelog.
8 | Your attention to this specific branch naming convention is essential for accurate version tracking in the changelog.
9 |
10 | ```shell
11 | export RELEASE_VERSION="X.Y.Z"
12 | git switch main
13 | git pull --rebase
14 | git switch -c release-v$RELEASE_VERSION
15 |
16 | bundle config set --local path vendor/bundle
17 | bundle config set --local with 'release'
18 | bundle install
19 |
20 | CHANGELOG_GITHUB_TOKEN="token_MC_tokenface" bundle exec rake changelog
21 | git commit --all --message "Release v${RELEASE_VERSION}"
22 | git push --set-upstream origin HEAD
23 | ```
24 |
25 | Then open a PR, discuss and merge.
26 |
27 | ## After the merge, as a maintainer on upstream
28 |
29 | ```shell
30 | git switch main
31 | git pull --rebase
32 | git tag v$RELEASE_VERSION -m "v$RELEASE_VERSION"
33 | git push --tags
34 | ```
35 |
--------------------------------------------------------------------------------
/puppetdb/request-logging.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | combined
5 |
6 |
7 |
8 | ${LOGDIR}/puppetdb-access.log
9 | true
10 |
11 | ${LOGDIR}/puppetdb-access-%d{yyyy-MM-dd}.%i.log.gz
12 |
13 | 200MB
14 | 90
15 | 1GB
16 |
17 |
18 | %h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}" %D %i{Content-Length} %header{X-Uncompressed-Length}
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/puppetdb/conf.d/jetty.ini:
--------------------------------------------------------------------------------
1 | [jetty]
2 | # IP address or hostname to listen for clear-text HTTP. To avoid resolution
3 | # issues, IP addresses are recommended over hostnames.
4 | # Default is `localhost`.
5 | host = 0.0.0.0
6 |
7 | # Port to listen on for clear-text HTTP.
8 | port = 8080
9 |
10 | # The following are SSL specific settings.
11 | # They are enabled by setting USE_PUPPETSERVER=true (the default) when starting
12 | # the container by the configure-ssl.sh entrypoint script
13 |
14 | # IP address to listen on for HTTPS connections. Hostnames can also be used
15 | # but are not recommended to avoid DNS resolution issues. To listen on all
16 | # interfaces, use `0.0.0.0`.
17 | # ssl-host = 0.0.0.0
18 |
19 | # The port to listen on for HTTPS connections
20 | # ssl-port = 8081
21 |
22 | # Private key path
23 | # ssl-key = /opt/puppetlabs/server/data/puppetdb/certs/private_keys/server.key
24 |
25 | # Public certificate path
26 | # ssl-cert = /opt/puppetlabs/server/data/puppetdb/certs/certs/server.crt
27 |
28 | # Certificate authority path
29 | # ssl-ca-cert = /opt/puppetlabs/server/data/puppetdb/certs/certs/ca.pem
30 |
31 | # Allow for token authentication
32 | client-auth = want
33 |
34 | # Access logging configuration path. To turn off access logging
35 | # comment out the line with `access-log-config=...`
36 | access-log-config = /etc/puppetlabs/puppetdb/request-logging.xml
37 |
--------------------------------------------------------------------------------
/puppetdb/puppetdb:
--------------------------------------------------------------------------------
1 | ###########################################
2 | # Init settings for puppetdb
3 | ###########################################
4 |
5 | # Location of your Java binary (version 8)
6 | JAVA_BIN="/usr/bin/java"
7 |
8 | # Modify this if you'd like to change the memory allocation, enable JMX, etc
9 | JAVA_ARGS="${PUPPETDB_JAVA_ARGS}"
10 |
11 | # Modify this as you would JAVA_ARGS but for non-service related subcommands
12 | JAVA_ARGS_CLI="${JAVA_ARGS_CLI:-}"
13 |
14 | # Modify this if you'd like TrapperKeeper specific arguments
15 | TK_ARGS=""
16 |
17 | # These normally shouldn't need to be edited if using OS packages
18 | USER="puppetdb"
19 | GROUP="puppetdb"
20 | INSTALL_DIR="/opt/puppetlabs/server/apps/puppetdb"
21 | CONFIG="/etc/puppetlabs/puppetdb/conf.d"
22 |
23 | # Bootstrap path
24 | BOOTSTRAP_CONFIG="/etc/puppetlabs/puppetdb/bootstrap.cfg"
25 |
26 | # SERVICE_STOP_RETRIES can be set here to alter the default stop timeout in
27 | # seconds. For systemd, the shorter of this setting or 'TimeoutStopSec' in
28 | # the systemd.service definition will effectively be the timeout which is used.
29 | SERVICE_STOP_RETRIES=60
30 |
31 | # START_TIMEOUT can be set here to alter the default startup timeout in
32 | # seconds. For systemd, the shorter of this setting or 'TimeoutStartSec'
33 | # in the service's systemd.service configuration file will effectively be the
34 | # timeout which is used.
35 | START_TIMEOUT=14400
36 |
37 |
38 | # Maximum number of seconds that can expire for a service reload attempt before
39 | # the result of the attempt is interpreted as a failure.
40 | RELOAD_TIMEOUT=120
41 |
--------------------------------------------------------------------------------
/puppetdb/conf.d/auth.conf:
--------------------------------------------------------------------------------
1 | authorization: {
2 | version: 1
3 | rules: [
4 | {
5 | # Allow unauthenticated access to the status service endpoint
6 | match-request: {
7 | path: "/status/v1/services"
8 | type: path
9 | method: get
10 | }
11 | allow-unauthenticated: true
12 | sort-order: 500
13 | name: "puppetlabs status service - full"
14 | },
15 | {
16 | match-request: {
17 | path: "/status/v1/simple"
18 | type: path
19 | method: get
20 | }
21 | allow-unauthenticated: true
22 | sort-order: 500
23 | name: "puppetlabs status service - simple"
24 | },
25 | {
26 | # Allow nodes to access the metrics service
27 | # for puppetdb, the metrics service is the only
28 | # service using the authentication service
29 | match-request: {
30 | path: "/metrics"
31 | type: path
32 | method: [get, post]
33 | }
34 | allow: "*"
35 | sort-order: 500
36 | name: "puppetlabs puppetdb metrics"
37 | },
38 | {
39 | # Deny everything else. This ACL is not strictly
40 | # necessary, but illustrates the default policy
41 | match-request: {
42 | path: "/"
43 | type: path
44 | }
45 | deny: "*"
46 | sort-order: 999
47 | name: "puppetlabs deny all"
48 | }
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/.github/workflows/security_scanning.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Security Scanning 🕵️
3 |
4 | on:
5 | push:
6 | branches:
7 | - main
8 | pull_request:
9 | branches:
10 | - main
11 |
12 | jobs:
13 | setup-matrix:
14 | runs-on: ubuntu-latest
15 | outputs:
16 | matrix: ${{ steps.set-matrix.outputs.matrix }}
17 | steps:
18 | - name: Source checkout
19 | uses: actions/checkout@v4
20 |
21 | - id: set-matrix
22 | run: echo "matrix=$(jq -c . build_versions.json)" >> $GITHUB_OUTPUT
23 |
24 | scan_ci_container:
25 | name: 'Scan CI container'
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 | needs: setup-matrix
32 | strategy:
33 | matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
34 | steps:
35 | - name: Checkout repository
36 | uses: actions/checkout@v4
37 |
38 | - name: Build CI container
39 | uses: docker/build-push-action@v6
40 | with:
41 | tags: 'ci/puppetdb:${{ matrix.version }}'
42 | context: puppetdb
43 | push: false
44 | build-args: |
45 | PUPPET_RELEASE=${{ matrix.release }}
46 | PUPPETDB_VERSION=${{ matrix.version }}
47 |
48 | - name: Scan image with Anchore Grype
49 | uses: anchore/scan-action@v6
50 | id: scan
51 | with:
52 | image: 'ci/puppetdb:${{ matrix.version }}'
53 | fail-build: false
54 |
55 | - name: Inspect action SARIF report
56 | run: jq . ${{ steps.scan.outputs.sarif }}
57 |
58 | - name: Upload Anchore scan SARIF report
59 | uses: github/codeql-action/upload-sarif@v3
60 | with:
61 | sarif_file: ${{ steps.scan.outputs.sarif }}
62 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: CI🚦
3 |
4 | on:
5 | pull_request:
6 | branches:
7 | - main
8 | workflow_dispatch:
9 |
10 | jobs:
11 | setup-matrix:
12 | runs-on: ubuntu-latest
13 | outputs:
14 | matrix: ${{ steps.set-matrix.outputs.matrix }}
15 | steps:
16 | - name: Source checkout
17 | uses: actions/checkout@v4
18 |
19 | - id: set-matrix
20 | run: echo "matrix=$(jq -c . build_versions.json)" >> $GITHUB_OUTPUT
21 |
22 | general_ci:
23 | uses: voxpupuli/crafty/.github/workflows/general_ci.yaml@main
24 | with:
25 | shellcheck_scan_dir: './puppetdb'
26 |
27 | build_test_container:
28 | name: 'Build test container'
29 | runs-on: ubuntu-latest
30 | permissions:
31 | actions: read
32 | contents: read
33 | security-events: write
34 | pull-requests: write
35 | needs: setup-matrix
36 | strategy:
37 | matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
38 | steps:
39 | - name: Checkout repository
40 | uses: actions/checkout@v4
41 |
42 | - name: Build image
43 | uses: docker/build-push-action@v6
44 | with:
45 | tags: 'ci/puppetdb:${{ matrix.version }}'
46 | context: puppetdb
47 | push: false
48 | build-args: |
49 | PUPPET_RELEASE=${{ matrix.release }}
50 | PUPPETDB_VERSION=${{ matrix.version }}
51 |
52 | tests:
53 | needs:
54 | - general_ci
55 | - build_test_container
56 | runs-on: ubuntu-latest
57 | name: Test suite
58 | steps:
59 | - run: echo Test suite completed
60 |
61 | dependabot:
62 | permissions:
63 | contents: write
64 | name: 'Dependabot auto-merge'
65 | needs:
66 | - tests
67 | runs-on: ubuntu-latest
68 | if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}}
69 | steps:
70 | - name: Dependabot metadata
71 | id: metadata
72 | uses: dependabot/fetch-metadata@v2.3.0
73 | with:
74 | github-token: '${{ secrets.GITHUB_TOKEN }}'
75 |
76 | - name: Enable auto-merge for Dependabot PRs
77 | run: gh pr merge --auto --merge "$PR_URL"
78 | env:
79 | PR_URL: ${{github.event.pull_request.html_url}}
80 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
81 |
--------------------------------------------------------------------------------
/.github/workflows/build_docker.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build and publish a 🛢️ container
3 |
4 | on:
5 | push:
6 | branches:
7 | - 'main'
8 | tags:
9 | - '*'
10 | workflow_dispatch:
11 |
12 | jobs:
13 | setup-matrix:
14 | runs-on: ubuntu-latest
15 | outputs:
16 | matrix: ${{ steps.set-matrix.outputs.matrix }}
17 | steps:
18 | - name: Source checkout
19 | uses: actions/checkout@v4
20 |
21 | - id: set-matrix
22 | run: echo "matrix=$(cat build_versions.json | jq -c)" >> $GITHUB_OUTPUT
23 |
24 | build-and-push-container:
25 | runs-on: ubuntu-latest
26 | permissions:
27 | contents: read
28 | packages: write
29 | needs: setup-matrix
30 | strategy:
31 | matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
32 | steps:
33 | - name: Build PuppetDB ${{ matrix.release }} container
34 | uses: voxpupuli/gha-build-and-publish-a-container@v2
35 | with:
36 | registry_password: ${{ secrets.GITHUB_TOKEN }}
37 | build_args: |
38 | PUPPET_RELEASE=${{ matrix.release }}
39 | PUPPETDB_VERSION=${{ matrix.version }}
40 | build_arch: linux/amd64,linux/arm64
41 | docker_username: voxpupulibot
42 | docker_password: ${{ secrets.DOCKERHUB_BOT_PASSWORD }}
43 | build_context: puppetdb
44 | buildfile: puppetdb/Dockerfile
45 | tags: |
46 | ghcr.io/${{ github.repository }}:${{ matrix.version }}-${{ github.ref_name }}
47 | ghcr.io/${{ github.repository }}:${{ matrix.version }}-latest
48 | ghcr.io/${{ github.repository }}:latest
49 | ghcr.io/voxpupuli/puppetdb:${{ matrix.version }}-${{ github.ref_name }}
50 | ghcr.io/voxpupuli/puppetdb:${{ matrix.version }}-latest
51 | ghcr.io/voxpupuli/puppetdb:latest
52 | docker.io/${{ github.repository }}:${{ matrix.version }}-${{ github.ref_name }}
53 | docker.io/${{ github.repository }}:${{ matrix.version }}-latest
54 | docker.io/${{ github.repository }}:latest
55 | docker.io/voxpupuli/puppetdb:${{ matrix.version }}-${{ github.ref_name }}
56 | docker.io/voxpupuli/puppetdb:${{ matrix.version }}-latest
57 | docker.io/voxpupuli/puppetdb:latest
58 |
59 | - name: Update Docker Hub Description
60 | uses: peter-evans/dockerhub-description@v4
61 | with:
62 | username: voxpupulibot
63 | password: ${{ secrets.DOCKERHUB_BOT_PASSWORD }}
64 |
65 | - name: Update Docker Hub Description for shortname
66 | uses: peter-evans/dockerhub-description@v4
67 | with:
68 | username: voxpupulibot
69 | password: ${{ secrets.DOCKERHUB_BOT_PASSWORD }}
70 | repository: voxpupuli/puppetdb
71 |
--------------------------------------------------------------------------------
/puppetdb/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | %d %-5p [%c{2}] %m%n
8 |
9 |
10 |
11 |
12 | ${LOGDIR}/puppetdb.log
13 | true
14 |
15 | ${LOGDIR}/puppetdb-%d{yyyy-MM-dd}.%i.log.gz
16 |
17 | 200MB
18 | 90
19 | 1GB
20 |
21 |
22 | %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %-5p [%c{2}] %m%n
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 | ${LOGDIR}/puppetdb-status.log
38 | true
39 |
40 |
41 | ${LOGDIR}/puppetdb-status-%d{yyyy-MM-dd}.%i.log.gz
42 |
43 | 200MB
44 | 90
45 | 1GB
46 |
47 |
48 |
49 | %m%n
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/puppetdb/docker-entrypoint.d/10-wait-for-hosts.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | # Wait on hosts to become available before proceeding
6 | #
7 | #
8 | # Optional environment variables:
9 | # PUPPETDB_WAITFORHOST_SECONDS Number of seconds to wait for DNS names of
10 | # Postgres and Puppetserver to resolve, defaults to 30
11 | # PUPPETDB_WAITFORHEALTH_SECONDS Number of seconds to wait for health
12 | # checks of Puppetserver to succeed, defaults to 360
13 | # to match puppetserver healthcheck max wait
14 | # PUPPETDB_WAITFORPOSTGRES_SECONDS Additional number of seconds to wait on Postgres,
15 | # after PuppetServer is healthy, defaults to 60
16 | # PUPPETDB_POSTGRES_HOSTNAME Specified in Dockerfile, defaults to postgres
17 | # PUPPETSERVER_HOSTNAME DNS name of puppetserver to wait on, defaults to puppet
18 |
19 |
20 | msg() {
21 | echo "($0) $1"
22 | }
23 |
24 | error() {
25 | msg "Error: $1"
26 | exit 1
27 | }
28 |
29 | # Alpine as high as 3.9 seems to have failures reaching addresses sporadically
30 | # In local repro scenarios, performing a DNS lookup with dig increases reliability
31 | wait_for_host_name_resolution() {
32 | # host and dig are in the bind-tools Alpine package
33 | # k8s nodes may not be reachable with a ping
34 | # performing a dig prior to a host may help prime the cache in Alpine
35 | # https://github.com/Microsoft/opengcs/issues/303
36 | /wtfc.sh --timeout="${2}" --interval=1 --progress "dig $1 && host -t A $1"
37 | # additionally log the DNS lookup information for diagnostic purposes
38 | NAME_RESOLVED=$?
39 | dig $1
40 | if [ $NAME_RESOLVED -ne 0 ]; then
41 | error "dependent service at $1 cannot be resolved or contacted"
42 | fi
43 | }
44 |
45 | wait_for_host_port() {
46 | # -v verbose -w connect / final net read timeout -z scan and don't send data
47 | /wtfc.sh --timeout=${3} --interval=1 --progress "nc -v -w 1 -z '${1}' ${2}"
48 | if [ $? -ne 0 ]; then
49 | error "host $1:$2 does not appear to be listening"
50 | fi
51 | }
52 |
53 | PUPPETDB_WAITFORHOST_SECONDS=${PUPPETDB_WAITFORHOST_SECONDS:-30}
54 | PUPPETDB_WAITFORPOSTGRES_SECONDS=${PUPPETDB_WAITFORPOSTGRES_SECONDS:-60}
55 | PUPPETDB_WAITFORHEALTH_SECONDS=${PUPPETDB_WAITFORHEALTH_SECONDS:-360}
56 | PUPPETDB_POSTGRES_HOSTNAME="${PUPPETDB_POSTGRES_HOSTNAME:-postgres}"
57 | PUPPETSERVER_HOSTNAME="${PUPPETSERVER_HOSTNAME:-puppet}"
58 | PUPPETSERVER_PORT="${PUPPETSERVER_PORT:-8140}"
59 |
60 | # wait for postgres DNS
61 | wait_for_host_name_resolution $PUPPETDB_POSTGRES_HOSTNAME $PUPPETDB_WAITFORHOST_SECONDS
62 |
63 | # wait for puppetserver DNS, then healthcheck
64 | if [ "$USE_PUPPETSERVER" = true ]; then
65 | wait_for_host_name_resolution $PUPPETSERVER_HOSTNAME $PUPPETDB_WAITFORHOST_SECONDS
66 | HEALTH_COMMAND="curl --silent --fail --insecure 'https://${PUPPETSERVER_HOSTNAME}:"${PUPPETSERVER_PORT}"/status/v1/simple' | grep -q '^running$'"
67 | fi
68 |
69 | if [ -n "$HEALTH_COMMAND" ]; then
70 | /wtfc.sh --timeout=$PUPPETDB_WAITFORHEALTH_SECONDS --interval=1 --progress "$HEALTH_COMMAND"
71 | if [ $? -ne 0 ]; then
72 | error "Required health check failed"
73 | fi
74 | fi
75 |
76 | # wait for postgres
77 | wait_for_host_port $PUPPETDB_POSTGRES_HOSTNAME "${PUPPETDB_POSTGRES_PORT:-5432}" $PUPPETDB_WAITFORPOSTGRES_SECONDS
78 |
--------------------------------------------------------------------------------
/puppetdb/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | ARG vcs_ref
4 | ARG build_date
5 | ARG build_type
6 |
7 | LABEL org.label-schema.maintainer="Voxpupuli Release Team " \
8 | org.label-schema.vendor="Vox Pupuli" \
9 | org.label-schema.url="https://github.com/voxpupuli/container-puppetdb" \
10 | org.label-schema.license="Apache-2.0" \
11 | org.label-schema.vcs-url="https://github.com/voxpupuli/container-puppetdb" \
12 | org.label-schema.schema-version="1.0" \
13 | org.label-schema.dockerfile="/Dockerfile" \
14 | org.label-schema.name="PuppetDB ($build_type)" \
15 | org.label-schema.vcs-ref="$vcs_ref" \
16 | org.label-schema.build-date="$build_date"
17 |
18 | ARG DUMB_INIT_VERSION="1.2.5"
19 | ARG TARGETARCH
20 | ARG UBUNTU_CODENAME=jammy
21 |
22 | ARG LOGDIR
23 | ENV LOGDIR=${LOGDIR:-/opt/puppetlabs/server/data/puppetdb/logs}
24 |
25 | ARG PUPPET_RELEASE
26 | ENV PUPPET_RELEASE=${PUPPET_RELEASE:-8}
27 |
28 | ARG PUPPETDB_VERSION
29 | ENV PUPPETDB_VERSION=${PUPPETDB_VERSION:-8.8.0}
30 |
31 | ARG SSLDIR
32 | ENV SSLDIR=${SSLDIR:-/opt/puppetlabs/server/data/puppetdb/certs}
33 |
34 | ENV PUPPETDB_POSTGRES_HOSTNAME="postgres" \
35 | PUPPETDB_POSTGRES_PORT="5432" \
36 | PUPPETDB_POSTGRES_DATABASE="puppetdb" \
37 | CERTNAME=puppetdb \
38 | DNS_ALT_NAMES="" \
39 | WAITFORCERT="" \
40 | PUPPETDB_USER=puppetdb \
41 | PUPPETDB_PASSWORD=puppetdb \
42 | PUPPETDB_NODE_TTL=7d \
43 | PUPPETDB_NODE_PURGE_TTL=14d \
44 | PUPPETDB_REPORT_TTL=14d \
45 | PUPPETDB_CERTIFICATE_ALLOWLIST="" \
46 | # used by entrypoint to determine if puppetserver should be contacted for config
47 | # set to false when container tests are run
48 | USE_PUPPETSERVER=true \
49 | # this value may be set by users, keeping in mind that some of these values are mandatory
50 | # -Djavax.net.debug=ssl may be particularly useful to set for debugging SSL
51 | PUPPETDB_JAVA_ARGS="-Djava.net.preferIPv4Stack=true -Xms256m -Xmx256m -XX:+UseParallelGC -Xlog:gc*:file=$LOGDIR/puppetdb_gc.log -Djdk.tls.ephemeralDHKeySize=2048" \
52 | PUPPET_DEB=puppet${PUPPET_RELEASE}-release-${UBUNTU_CODENAME}.deb \
53 | DEBIAN_FRONTEND=noninteractive
54 |
55 | # puppetdb data and generated certs
56 | VOLUME /opt/puppetlabs/server/data/puppetdb
57 |
58 | ADD https://apt.puppet.com/${PUPPET_DEB} /${PUPPET_DEB}
59 |
60 | ADD ssl.sh \
61 | wtfc.sh \
62 | docker-entrypoint.sh \
63 | healthcheck.sh \
64 | /
65 |
66 | COPY docker-entrypoint.d /docker-entrypoint.d
67 |
68 | RUN dpkg -i /${PUPPET_DEB} && \
69 | rm /${PUPPET_DEB} && \
70 | apt update && \
71 | apt install --no-install-recommends -y ca-certificates curl dnsutils netcat-traditional dumb-init && \
72 | chmod +x /ssl.sh /wtfc.sh /docker-entrypoint.sh /healthcheck.sh /docker-entrypoint.d/*.sh && \
73 | apt install --no-install-recommends -y puppetdb=${PUPPETDB_VERSION}-1${UBUNTU_CODENAME} && \
74 | apt install --no-install-recommends -y openjdk-17-jre-headless && \
75 | apt autoremove && \
76 | rm -rf /var/lib/apt/lists/* && \
77 | mkdir -p "$LOGDIR" && \
78 | chown puppetdb:puppetdb "$LOGDIR" && \
79 | # We want to use the HOCON database.conf and config.conf files, so get rid
80 | # of the packaged files
81 | rm -f /etc/puppetlabs/puppetdb/conf.d/database.ini && \
82 | rm -f /etc/puppetlabs/puppetdb/conf.d/config.ini
83 |
84 | COPY logback.xml \
85 | request-logging.xml \
86 | /etc/puppetlabs/puppetdb/
87 | COPY conf.d /etc/puppetlabs/puppetdb/conf.d/
88 | COPY puppetdb /etc/default/puppetdb
89 | COPY Dockerfile /
90 |
91 | # The start-period is just a wild guess how long it takes PuppetDB to come
92 | # up in the worst case. The other timing parameters are set so that it
93 | # takes at most a minute to realize that PuppetDB has failed.
94 | # Probe failure during --start-period will not be counted towards the maximum number of retries
95 | # NOTE: k8s uses livenessProbe, startupProbe, readinessProbe and ignores HEALTHCHECK
96 | HEALTHCHECK --start-period=5m --interval=10s --timeout=10s --retries=6 CMD ["/healthcheck.sh"]
97 |
98 | # NOTE: this is just documentation on defaults
99 | EXPOSE 8080 8081
100 |
101 | ENTRYPOINT ["dumb-init", "/docker-entrypoint.sh"]
102 | CMD ["foreground"]
103 |
--------------------------------------------------------------------------------
/puppetdb/wtfc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Taken from https://raw.githubusercontent.com/puppetlabs/wtfc/6aa5eef89728cc2903490a618430cc3e59216fa8/wtfc.sh
4 | # December, 20, 2023
5 |
6 | cmdname="${0##*/}"
7 |
8 | VERSION=0.0.2
9 |
10 | echoto() {
11 | # print to stderr or to stdout
12 | out=$1
13 | shift 1
14 |
15 | if ([ "${out}" -eq 2 ]); then
16 | printf "$@" >&2
17 | else
18 | # stdout can be silenced only
19 | if [ "${QUIET}" -eq 0 ]; then
20 | printf "$@"
21 | fi
22 | fi
23 | }
24 |
25 | progress() {
26 | if ([ "${PROGRESS}" -eq 1 ]); then
27 | echoto 1 "."
28 | fi
29 | }
30 |
31 | usage() {
32 | # (TODO) -F, --format-progress=FORMAT set FORMAT for progress, available: DOTS, PROGRESSBAR (default is DOTS)
33 | OUTPUT=`cat < 0), otherwise to stdout
55 | if ([ "$1" -gt 0 ]); then
56 | echo "${OUTPUT}" >&2
57 | else
58 | echo "${OUTPUT}"
59 | fi
60 |
61 | exit $1
62 | }
63 |
64 | version() {
65 | echo "wtfc (WaiT For the Command) version: ${VERSION}"
66 | exit 0
67 | }
68 |
69 | wait_for(){
70 | if [ "${TIMEOUT}" -gt 0 ]; then
71 | echoto 1 "$cmdname: waiting $TIMEOUT seconds for $CMD\n"
72 | else
73 | echoto 1 "$cmdname: waiting without a timeout for $CMD\n"
74 | fi
75 |
76 | while :
77 | do
78 | eval $CMD >/dev/null 2>&1
79 | result=$?
80 |
81 | if ([ "${result}" -eq "${STATUS}" ]); then
82 | break
83 | fi
84 | sleep $INTERVAL
85 |
86 | progress
87 | done
88 | return $result
89 | }
90 |
91 | wait_for_wrapper() {
92 | TIME_START=$(date +%s)
93 |
94 | # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
95 | if ([ "${QUIET}" -eq 1 ]); then
96 | eval $TIMEOUT_CMD $TIMEOUT_FLAG $TIMEOUT $0 --quiet --child --status=$STATUS --timeout=$TIMEOUT \"$CMD\" &
97 | else
98 | eval $TIMEOUT_CMD $TIMEOUT_FLAG $TIMEOUT $0 --child --status=$STATUS --timeout=$TIMEOUT \"$CMD\" &
99 | fi
100 | PID=$!
101 | trap "kill -INT -$PID" INT
102 |
103 | while [ $(($(date +%s)-TIME_START)) -lt "${TIMEOUT}" ]; do
104 |
105 | eval $CMD >/dev/null 2>&1
106 | result=$?
107 |
108 | if ([ "${result}" -eq "${STATUS}" ]); then
109 | break
110 | fi
111 |
112 | sleep $INTERVAL
113 |
114 | progress
115 | done
116 | wait $PID
117 | RESULT=$?
118 | return $RESULT
119 | }
120 |
121 | # process arguments
122 | while [ $# -gt 0 ]
123 | do
124 | case "$1" in
125 | --child)
126 | CHILD=1
127 | shift 1
128 | ;;
129 | -H | --help)
130 | usage 0
131 | ;;
132 | -I)
133 | INTERVAL="$2"
134 | if [ -z "${INTERVAL}" ]; then break; fi
135 | shift 2
136 | ;;
137 | --interval=*)
138 | INTERVAL="${1#*=}"
139 | shift 1
140 | ;;
141 | -P | --progress)
142 | PROGRESS=1
143 | shift 1
144 | ;;
145 | -Q | --quiet)
146 | QUIET=1
147 | shift 1
148 | ;;
149 | -S)
150 | STATUS="$2"
151 | if [ -z "${STATUS}" ]; then break; fi
152 | shift 2
153 | ;;
154 | --status=*)
155 | STATUS="${1#*=}"
156 | shift 1
157 | ;;
158 | -T)
159 | TIMEOUT="$2"
160 | if [ -z "${TIMEOUT}" ]; then break; fi
161 | shift 2
162 | ;;
163 | --timeout=*)
164 | TIMEOUT="${1#*=}"
165 | shift 1
166 | ;;
167 | -V | --version)
168 | version
169 | ;;
170 | -*)
171 | echoto 2 "Unknown argument: $1"
172 | usage 1
173 | ;;
174 | *)
175 | CMD="$@"
176 | break
177 | ;;
178 | esac
179 | done
180 |
181 | # read from stdin, if no cmd provided
182 | if [ -z "${CMD}" ]; then
183 | read CMD
184 | fi
185 |
186 | if [ -z "${CMD}" ]; then
187 | echoto 2 "Error: you need to provide a COMMAND to test as the last argument or via standard input.\n"
188 | usage 1
189 | fi
190 |
191 | CHILD=${CHILD:-0}
192 | INTERVAL=${INTERVAL:-1}
193 | PROGRESS=${PROGRESS:-0}
194 | QUIET=${QUIET:-0}
195 | STATUS=${STATUS:-0}
196 | TIMEOUT=${TIMEOUT:-1}
197 |
198 | # check to see if timeout is from busybox/alpine => '-t' switch is required or not
199 | TIMEOUT_TEST="$(timeout 1 sleep 0 2>&1)"
200 | case "${TIMEOUT_TEST}" in
201 | timeout:\ can\'t\ execute\ \'1\':*) TIMEOUT_FLAG="-t" ;;
202 | *) TIMEOUT_FLAG="" ;;
203 | esac
204 |
205 | TIMEOUT_TEST="$(timeout ${TIMEOUT_FLAG} 1 sleep 0 2>&1)"
206 | TIMEOUT_TEST_STATUS="$?"
207 |
208 | # fallback for osx (uses gtimeout)
209 | if [ "${TIMEOUT_TEST_STATUS}" -eq 127 ]; then
210 | TIMEOUT_TEST="$(gtimeout ${TIMEOUT_FLAG} 1 sleep 0 2>&1)"
211 | TIMEOUT_TEST_STATUS="$?"
212 |
213 | if [ "${TIMEOUT_TEST_STATUS}" -eq 127 ]; then
214 | echoto 2 "timeout|gtimeout is required by the script, but not found!\n"
215 | exit 1
216 | fi
217 |
218 | TIMEOUT_CMD="gtimeout"
219 | else
220 | TIMEOUT_CMD="timeout"
221 | fi
222 |
223 | start_ts=$(date +%s)
224 |
225 | if [ "${CHILD}" -eq 1 ]; then
226 | wait_for
227 | RESULT=$?
228 | exit $RESULT
229 | else
230 | if [ "${TIMEOUT}" -gt 0 ]; then
231 | wait_for_wrapper
232 | RESULT=$?
233 | else
234 | wait_for
235 | RESULT=$?
236 | fi
237 | fi
238 |
239 | if [ "${RESULT}" -ne "${STATUS}" ]; then
240 | echoto 2 "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $CMD to return status: $STATUS (was status: $RESULT)\n"
241 | if [ "${RESULT}" -eq 0 ]; then
242 | # exit with 1, inspite the fact original ended with 0 (as we expected non-0)
243 | exit 1
244 | else
245 | exit $RESULT
246 | fi
247 | else
248 | end_ts=$(date +%s)
249 | echoto 1 "$cmdname: $CMD finished with expected status $RESULT after $((end_ts - start_ts)) seconds\n"
250 | exit 0
251 | fi
252 |
253 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Voxpupuli PuppetDB container
2 |
3 | # ⚠️ Deprecated ⚠️
4 |
5 | This repository is deprecated and will be archived soon. Please use the [OpenVox DB container](https://github.com/OpenVoxProject/container-openvoxdb) instead.
6 |
7 | [](https://github.com/voxpupuli/container-puppetdb/actions/workflows/ci.yaml)
8 | [](https://github.com/voxpupuli/container-puppetdb/blob/main/LICENSE)
9 | [](https://www.puppet.com)
10 | [](https://www.betadots.de)
11 |
12 | ---
13 |
14 | - [Voxpupuli PuppetDB container](#voxpupuli-puppetdb-container)
15 | - [New version schema](#new-version-schema)
16 | - [Configuration](#configuration)
17 | - [Cert File Locations](#cert-file-locations)
18 | - [Initialization Scripts](#initialization-scripts)
19 | - [How to Release the container](#how-to-release-the-container)
20 | - [How to contribute](#how-to-contribute)
21 | - [Transfer notice](#transfer-notice)
22 |
23 | ---
24 |
25 | __⚠️ Attention ⚠️__: the container name `voxpupuli/container-puppetdb` will be deprecated in 2025-02 and might be removed in the future. Please use `voxpupuli/puppetdb` instead.
26 |
27 | ---
28 | This project hosts the Dockerfile and the required scripts to build a PuppetDB container image.
29 |
30 | For compose file see: [CRAFTY](https://github.com/voxpupuli/crafty/tree/main/puppet/oss)
31 |
32 | The PuppetDB container requires a working postgres container or other suitably
33 | configured PostgreSQL database. For a Compose example see the [CRAFTY OSS Demo compose.yaml](https://github.com/voxpupuli/crafty/blob/main/puppet/oss/compose.yaml)
34 |
35 | You can change configuration settings by mounting volumes containing
36 | configuration files or by using this image as a base image. For the defaults,
37 | see the [Dockerfile and supporting folders](https://github.com/voxpupuli/container-puppetdb/tree/main/puppetdb).
38 |
39 | For more details about PuppetDB, see the [official documentation](https://puppet.com/docs/puppetdb/latest/index.html).
40 |
41 | ## New version schema
42 |
43 | The new version schema has the following layout:
44 |
45 | ```text
46 | ..-v..
47 | ```
48 |
49 | Example usage:
50 |
51 | ```shell
52 | docker pull ghcr.io/voxpupuli/puppetdb:7.13.0-v1.2.1
53 | ```
54 |
55 | | Name | Description |
56 | | --- | --- |
57 | | puppet.major | Describes the contained major Puppet version (7 or 8) |
58 | | puppet.minor | Describes the contained minor Puppet version |
59 | | puppet.patch | Describes the contained patchlevel Puppet version |
60 | | container.major | Describes the major version of the base container (Ubunutu 22.04) or incompatible changes |
61 | | container.minor | Describes new features or refactoring with backward compatibility |
62 | | container.patch | Describes if minor changes or bugfixes have been implemented |
63 |
64 | ## Configuration
65 |
66 | | Name | Usage / Default |
67 | |-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
68 | | **CERTNAME** | The DNS name used on this services SSL certificate
`puppetdb` |
69 | | **DNS_ALT_NAMES** | Additional DNS names to add to the services SSL certificate
Unset |
70 | | **WAITFORCERT** | Number of seconds to wait for certificate to be signed
`120` |
71 | | **USE_PUPPETSERVER** | Set to `false` to skip acquiring SSL certificates from a Puppet Server.
`true` |
72 | | **PUPPETSERVER_HOSTNAME** | The DNS hostname of the puppet server
`puppet` |
73 | | **PUPPETSERVER_PORT** | The port of the puppet server
`8140` |
74 | | **PUPPETDB_POSTGRES_HOSTNAME** | The DNS hostname of the postgres service
`postgres` |
75 | | **PUPPETDB_POSTGRES_PORT** | The port for postgres
`5432` |
76 | | **PUPPETDB_POSTGRES_DATABASE** | The name of the puppetdb database in postgres
`puppetdb` |
77 | | **PUPPETDB_USER** | The puppetdb database user
`puppetdb` |
78 | | **PUPPETDB_PASSWORD** | The puppetdb database password
`puppetdb` |
79 | | **PUPPETDB_NODE_TTL** | Mark as ‘expired’ nodes that haven’t seen any activity (no new catalogs, facts, or reports) in the specified amount of time
`7d` |
80 | | **PUPPETDB_NODE_PURGE_TTL** | Automatically delete nodes that have been deactivated or expired for the specified amount of time
`14d` |
81 | | **PUPPETDB_REPORT_TTL** | Automatically delete reports that are older than the specified amount of time
`14d` |
82 | | **PUPPETDB_JAVA_ARGS** | Arguments passed directly to the JVM when starting the service
`-Djava.net.preferIPv4Stack=true -Xms256m -Xmx256m -XX:+UseParallelGC -Xlog:gc*:file=$LOGDIR/puppetdb_gc.log -Djdk.tls.ephemeralDHKeySize=2048` |
83 | | **PUPPETDB_CERTIFICATE_ALLOWLIST** | Comma separated list of certnames. No whitespaces!
example: `certname1,certname2,certname3`, default: empty string |
84 | | **LOGDIR** | Path of the log directory
`/opt/puppetlabs/server/data/puppetdb/logs` |
85 | | **SSLDIR** | Path of the SSL directory
`/opt/puppetlabs/server/data/puppetdb/certs` |
86 |
87 | ### Cert File Locations
88 |
89 | The directory structure follows the following conventions. The full path is always available inside the container as the environment variable `$SSLDIR`
90 |
91 | - 'ssl-ca-cert'
92 | `/opt/puppetlabs/server/data/puppetdb/certs/certs/ca.pem`
93 |
94 | - 'ssl-cert'
95 | `/opt/puppetlabs/server/data/puppetdb/certs/certs/.pem`
96 |
97 | - 'ssl-key'
98 | `/opt/puppetlabs/server/data/puppetdb/certs/private_keys/.pem`
99 |
100 | ## Initialization Scripts
101 |
102 | If you would like to do additional initialization, add a directory called `/docker-custom-entrypoint.d/` and fill it with `.sh` scripts.
103 | These scripts will be executed at the end of the entrypoint script, before the service is ran.
104 |
105 | ## How to Release the container
106 |
107 | [see here](https://github.com/voxpupuli/crafty/blob/main/RELEASE.md)
108 |
109 | ## How to contribute
110 |
111 | [see here](https://github.com/voxpupuli/crafty/blob/main/CONTRIBUTING.md)
112 |
113 | ## Transfer Notice
114 |
115 | This project was originally authored by [Puppet](https://github.com/puppetlabs).
116 | The maintainer preferred that Vox Pupuli take ownership of the project for future improvement and maintenance.
117 | Existing pull requests and issues were transferred over, please fork and continue to contribute here.
118 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/puppetdb/ssl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Taken from https://raw.githubusercontent.com/puppetlabs/pupperware/1c8d5f7fdcf2a81dfaf34f5ee34435cc50526d35/gem/lib/pupperware/compose-services/pe-postgres-custom/00-ssl.sh
4 | # December 20, 2023
5 | #
6 | # Get a signed certificate for this host.
7 | #
8 | # Uses OpenSSL directly to generate a new CSR and get it signed by the
9 | # Puppet Server CA.
10 | #
11 | # Intended to be used in place of a full-blown puppet agent run that is solely
12 | # for getting SSL certificates onto the host.
13 | #
14 | # Files will be placed in the same default directory location and structure
15 | # that the puppet agent would put them, which is /etc/puppetlabs/puppet/ssl,
16 | # unless the SSLDIR environment variable is specified.
17 | #
18 | # The certname is provided as the CERTNAME environment variable. If not found,
19 | # the HOSTNAME will be used.
20 | #
21 | # Supports DNS alt names via the DNS_ALT_NAMES environment variable, which
22 | # is a comma-separated string of names. The Puppet Server CA must be configured
23 | # to allow subject alt names, by default it will reject certificate requests
24 | # with them.
25 | #
26 | # Optional environment variables:
27 | # CERTNAME Certname to use
28 | # WAITFORCERT Number of seconds to wait for certificate to be
29 | # signed, defaults to 300
30 | # PUPPETSERVER_HOSTNAME Hostname of Puppet Server CA, defaults to "puppet"
31 | # PUPPETSERVER_PORT Port of Puppet Server CA, defaults to 8140
32 | # SSLDIR Root directory to write files to, defaults to
33 | # "/etc/puppetlabs/puppet/ssl"
34 | # DNS_ALT_NAMES Comma-separated string of DNS subject alternative
35 | # names, defaults to none
36 |
37 | msg() {
38 | echo "($0) $1"
39 | }
40 |
41 | # write to stderr so as to not pollute function output streams
42 | log_error() {
43 | msg "Error: $1" >&2
44 | }
45 |
46 | error() {
47 | msg "Error: $1"
48 | exit 1
49 | }
50 |
51 | # builds the GET http request given a URI
52 | get() {
53 | printf "GET %s HTTP/1.0\n%s" "$1" "$HOSTHEADER"
54 | }
55 |
56 | # $1 is request value
57 | # $2 is the maximum timeout
58 | # $3 is the amount to wait between retries, defaults to 1s
59 | retry_httpsreq() {
60 | retry_httpsreq_insecure "$1" "$2" "${3:-1}" "-CAfile ""${CACERTFILE}"""
61 | }
62 |
63 | # use openssl s_client to create HTTP requests and parse the response
64 | # a 200 OK will set a 0 return value, all other responses are non-zero
65 | # the HTTP response body is returned over stdout
66 | # $1 is request value
67 | httpsreq() {
68 | httpsreq_insecure "$1" "-CAfile ""${CACERTFILE}"""
69 | }
70 |
71 | # use openssl s_client to create HTTP requests and parse the response
72 | # a 200 OK will set a 0 return value, all other responses are non-zero
73 | # the HTTP response body is returned over stdout
74 | # $1 is request value
75 | # $2 is the maximum timeout
76 | # $3 is the amount to wait between retries, defaults to 1s
77 | # $4 is additional s_client CLI flags
78 | # returns 1 on failures, 4 for 404, 0 for a 200 OK
79 | retry_httpsreq_insecure() {
80 | maxwait=$2
81 | sleeptime=${3:-1}
82 | timewaited=0
83 | while ! output=$(httpsreq_insecure "$1" "$4"); do
84 | exit_code=$?
85 | if [ ${timewaited} -ge $((maxwait)) ]; then
86 | printf "%s" "${output}"
87 | return $exit_code
88 | fi
89 | sleep $((sleeptime))
90 | timewaited=$((timewaited+sleeptime))
91 | done
92 |
93 | printf "%s" "${output}"
94 | }
95 |
96 | # use openssl s_client to create HTTP requests and parse the response
97 | # a 200 OK will set a 0 return value, all other responses are non-zero
98 | # the HTTP response body is returned over stdout
99 | # $1 is request value
100 | # $2 is additional s_client CLI flags
101 | # returns 1 on failures, 4 for 404, 0 for a 200 OK
102 | httpsreq_insecure() {
103 | CLIENTFLAGS="-connect ""${PUPPETSERVER_HOSTNAME}:${PUPPETSERVER_PORT}"" -ign_eof -quiet $2"
104 |
105 | # shellcheck disable=SC2086 # $CLIENTFLAGS shouldn't be quoted
106 | if ! response=$(printf "%s\n\n" "$1" | openssl s_client ${CLIENTFLAGS} 2>/dev/null); then
107 | # possibly due to DNS errors or connnection refused
108 | # don't pollute stderr as these are frequent at boot
109 | return 1
110 | fi
111 |
112 | # an empty response doesn't include a status code, so abort
113 | if [ -z "$response" ]; then
114 | log_error "Empty response from request\n${1}"
115 | return 1
116 | fi
117 |
118 | # extract the HTTP status code from first line of response
119 | # RFC2616 defines first line header as Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
120 | status=$(printf "%s" "$response" | head -1 | cut -d ' ' -f 2)
121 |
122 | # unparseable status line, so abort
123 | if [ -z "$status" ]; then
124 | log_error "Invalid status line ${status} from request\n${1}"
125 | return 1
126 | fi
127 |
128 | # write HTTP payload over stdout by collecting all lines after header\r
129 | # same as: awk -v bl=1 'bl{bl=0; h=($0 ~ /HTTP\/1/)} /^\r?$/{bl=1} {if(!h) print}'
130 | body=false
131 | printf "%s\n" "$response" | while read -r line
132 | do
133 | if [ $body = true ]; then
134 | printf '%s\n' "$line"
135 | # a lone CR means the separator between headers and body has been reached
136 | elif [ "$line" = "$(printf "\r")" ]; then
137 | body=true
138 | fi
139 | done
140 |
141 | # treat 200 as success, don't pollute on not found status
142 | case "${status}" in
143 | '200') return 0 ;;
144 | '404') return 4 ;;
145 | *) log_error "HTTP ${status} from request\n${1}\n${response}"
146 | return 1 ;;
147 | esac
148 | }
149 |
150 | ca_running() {
151 | test "$(httpsreq_insecure "$(get '/status/v1/simple')")" = "running" && \
152 | httpsreq_insecure "$(get "${CA}/certificate/ca")" > /dev/null
153 | }
154 |
155 | set_file_perms() {
156 | msg "Securing permissions on ${SSLDIR}"
157 |
158 | # 700 for directories, 600 for files
159 | find "${SSLDIR}/." -type d -exec chmod u=rwx,g=,o= -- {} +
160 | find "${SSLDIR}/." -type f -exec chmod u=rw,g=,o= -- {} +
161 | }
162 |
163 | ### Verify we got a signed certificate
164 | verify_cert() {
165 | if [ -f "${CERTFILE}" ] && [ "$(head -1 "${CERTFILE}")" = "${CERTHEADER}" ]; then
166 | altnames="-certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux"
167 | # shellcheck disable=SC2086 # $altnames shouldn't be quoted
168 | if openssl x509 -subject -issuer -text -noout -in "${CERTFILE}" $altnames; then
169 | msg "Successfully signed certificate '${CERTFILE}'"
170 | else
171 | error "invalid signed certificate '${CERTFILE}'"
172 | fi
173 | else
174 | error "failed to get signed certificate for '${CERTNAME}'"
175 | fi
176 | }
177 |
178 | ### Verify dependencies available
179 | ! command -v openssl > /dev/null && error "openssl not found on PATH"
180 |
181 | ### Verify options are valid
182 | # shellcheck disable=SC2039 # Docker injects $HOSTNAME
183 | CERTNAME="${CERTNAME:-${HOSTNAME}}"
184 | [ -z "${CERTNAME}" ] && error "certificate name must be non-empty value"
185 | PUPPETSERVER_HOSTNAME="${PUPPETSERVER_HOSTNAME:-puppet}"
186 | PUPPETSERVER_PORT="${PUPPETSERVER_PORT:-8140}"
187 | SSLDIR="${SSLDIR:-/etc/puppetlabs/puppet/ssl}"
188 | WAITFORCERT=${WAITFORCERT:-300}
189 | DNS_ALT_NAMES=${DNS_ALT_NAMES:-}
190 |
191 | ### Create directories and files
192 | PUBKEYDIR="${SSLDIR}/public_keys"
193 | PRIVKEYDIR="${SSLDIR}/private_keys"
194 | CSRDIR="${SSLDIR}/certificate_requests"
195 | CERTDIR="${SSLDIR}/certs"
196 | mkdir -p "${SSLDIR}" "${PUBKEYDIR}" "${PRIVKEYDIR}" "${CSRDIR}" "${CERTDIR}"
197 | PUBKEYFILE="${PUBKEYDIR}/${CERTNAME}.pem"
198 | CANONICAL_PUBKEY_FILENAME="server.pub"
199 | PRIVKEYFILE="${PRIVKEYDIR}/${CERTNAME}.pem"
200 | CANONICAL_PRIVKEY_FILENAME="server.key"
201 | CANONICAL_PRIVKEYFILE_PK8="${PRIVKEYDIR}/server.private_key.pk8"
202 | CSRFILE="${CSRDIR}/${CERTNAME}.pem"
203 | CERTFILE="${CERTDIR}/${CERTNAME}.pem"
204 | CANONICAL_CERT_FILENAME="server.crt"
205 | CACERTFILE="${CERTDIR}/ca.pem"
206 | CRLFILE="${SSLDIR}/crl.pem"
207 | ALTNAMEFILE="/tmp/altnames.conf"
208 |
209 | CA="/puppet-ca/v1"
210 | CERTSUBJECT="/CN=${CERTNAME}"
211 | CERTHEADER="-----BEGIN CERTIFICATE-----"
212 | HOSTHEADER="Host: ${PUPPETSERVER_HOSTNAME}"
213 |
214 | ### Handle certificate extensions
215 | # NOTE If we want to expand support for more extensions, it would be better
216 | # to define them in a .conf file rather than directly on the CLI.
217 | # That would also work on older versions of openssl that don't support
218 | # the `-addext` flag.
219 | # For now, we explicitly handle DNS alt names because it's simpler.
220 | CERTEXTENSIONS=""
221 | if [ -n "${DNS_ALT_NAMES}" ]; then
222 | names=""
223 | first=true
224 | for name in $(printf "%s" "${DNS_ALT_NAMES}" | tr "," " "); do
225 | if $first; then
226 | first=false
227 | names="DNS:${name}"
228 | else
229 | names="${names},DNS:${name}"
230 | fi
231 | done
232 |
233 | # openssl 1.1.1+ supports -addext subjectAltName=${names}
234 | # previously used Postgres 9.6 image uses openssl 1.1.0 and has no such flag, so have to use -config
235 | # postgres 12.4 has openssl 1.1.1d
236 | printf "[req]\ndistinguished_name=dn\nreq_extensions=ext\n[dn]\n[ext]\nsubjectAltName=%s\n" "${names}" > "${ALTNAMEFILE}"
237 |
238 | CERTEXTENSIONS="-config ${ALTNAMEFILE}"
239 | fi
240 |
241 | ### Print configuration for troubleshooting
242 | msg "Using configuration values:"
243 | # shellcheck disable=SC2039 # Docker injects $HOSTNAME
244 | msg "* HOSTNAME: '${HOSTNAME}'"
245 | msg "* hostname -f: '$(hostname -f)'"
246 | msg "* CERTNAME: '${CERTNAME}' (${CERTSUBJECT})"
247 | msg "* DNS_ALT_NAMES: '${DNS_ALT_NAMES}'"
248 | msg "* CA: '${PUPPETSERVER_HOSTNAME}:${PUPPETSERVER_PORT}${CA}'"
249 | msg "* SSLDIR: '${SSLDIR}'"
250 | msg "* WAITFORCERT: '${WAITFORCERT}' seconds"
251 |
252 | # generate all symlinks, even if targets don't exist yet
253 | # using well known filenames makes these easier to consume in k8s
254 | # also use relative symlinks rather than absolute to ease sharing across differently mounted container volumes
255 | (cd "${CERTDIR}" && ln -s -f "${CERTNAME}.pem" "${CANONICAL_CERT_FILENAME}")
256 | (cd "${PRIVKEYDIR}" && ln -s -f "${CERTNAME}.pem" "${CANONICAL_PRIVKEY_FILENAME}")
257 | (cd "${PUBKEYDIR}" && ln -s -f "${CERTNAME}.pem" "${CANONICAL_PUBKEY_FILENAME}")
258 |
259 | # ensure no error output for empty dir
260 | certnames=$(cd "${PRIVKEYDIR}" && ls -A -m -- *.pem 2> /dev/null)
261 | if [ -s "${CERTFILE}" ]; then
262 | msg "Certificates (${certnames}) have already been generated - exiting!"
263 | set_file_perms
264 | exit 0
265 | # warn when rekeying an existing host as it's typically user error
266 | elif [ -n "${certnames}" ]; then
267 | msg "Warning: Specified new certificate name ${CERTNAME}, but existing certs (${certnames}) found!"
268 | fi
269 |
270 | msg "Waiting for ${PUPPETSERVER_HOSTNAME} to be running to generate certificates..."
271 | while ! ca_running; do
272 | sleep 1
273 | done
274 |
275 | ### Get the CA certificate for use with subsequent requests
276 | ### Fail-fast if openssl errors connecting or the CA certificate can't be parsed
277 | if ! retry_httpsreq_insecure "$(get "${CA}/certificate/ca")" 10 > "${CACERTFILE}"; then
278 | error "cannot reach CA host '${PUPPETSERVER_HOSTNAME}'"
279 | elif ! openssl x509 -subject -issuer -noout -in "${CACERTFILE}"; then
280 | error "invalid CA certificate"
281 | fi
282 |
283 | ### Get the CRL from the CA for use with client-side validation
284 | if ! retry_httpsreq "$(get "${CA}/certificate_revocation_list/ca")" 10 > "${CRLFILE}"; then
285 | error "cannot reach CRL host '${PUPPETSERVER_HOSTNAME}'"
286 | elif ! openssl crl -text -noout -in "${CRLFILE}" > /dev/null; then
287 | error "invalid CRL"
288 | fi
289 |
290 | ### Check if the CA already has a signed certificate for this host to either:
291 | ### * Recover from a submitted CSR attempt that didn't complete
292 | ### * Abort if there are no generated files on disk (i.e. hostname exists / collision)
293 | ### * Abort if generated files don't match (i.e. hostname exists / collision)
294 | ### * Abort if connection problem with server, so script can re-run
295 | CERTREQ=$(get "${CA}/certificate/${CERTNAME}")
296 | if cert=$(httpsreq "$CERTREQ"); then
297 | # if cert exists for name and disk is empty, this DNS name is claimed!
298 | [ ! -s "${PRIVKEYFILE}" ] && error "No keypair on disk and CA already has signed certificate for '${CERTNAME}'"
299 |
300 | # private key file exists, so see if a CSR was submitted but never signed
301 | key_hash=$(openssl rsa –noout –modulus –in "${PRIVKEYFILE}" 2> /dev/null | openssl md5)
302 | cert_hash=$(echo "${cert}" | openssl x509 –noout –modulus 2> /dev/null | openssl md5)
303 | [ "${key_hash}" != "${cert_hash}" ] && error "Private key on disk does not match signed certificate for '${CERTNAME}'"
304 |
305 | # Signed cert matches private key, so write it to disk
306 | msg "Recovered from incomplete signing - retrieved signed certificate matching private key on disk"
307 | printf "%s\n" "${cert}" > "${CERTFILE}"
308 |
309 | verify_cert
310 | exit 0
311 | elif [ $? -ne 4 ]; then
312 | error "${cert}"
313 | fi
314 |
315 | ### Generate keys and CSR for this host if needed
316 | if [ ! -s "${PRIVKEYFILE}" ]; then
317 | openssl genrsa -out "${PRIVKEYFILE}" 4096
318 | else
319 | # No signed cert exists yet, so use existing private key, regenerate pub key, resubmit CSR
320 | msg "Reusing existing private key '${PRIVKEYFILE}'"
321 | fi
322 | [ -f "${CANONICAL_PRIVKEYFILE_PK8}" ] && rm -rf "${CANONICAL_PRIVKEYFILE_PK8}"
323 | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER \
324 | -in "${PRIVKEYFILE}" \
325 | -out "${CANONICAL_PRIVKEYFILE_PK8}"
326 |
327 | [ -s "${PUBKEYFILE}" ] && msg "recreating existing public key '${PUBKEYFILE}'"
328 | openssl rsa -in "${PRIVKEYFILE}" -pubout -out "${PUBKEYFILE}"
329 |
330 | [ -s "${CSRFILE}" ] && msg "recreating existing certificate request '${CSRFILE}'"
331 | # shellcheck disable=SC2086 # $CERTEXTENSIONS shouldn't be quoted
332 | openssl req -new -key "${PRIVKEYFILE}" -out "${CSRFILE}" -subj "${CERTSUBJECT}" ${CERTEXTENSIONS}
333 | [ -f "${ALTNAMEFILE}" ] && rm "${ALTNAMEFILE}"
334 |
335 | ### Submit CSR and fail gracefully on certain error conditions
336 | CSRREQ=$(cat < "${CERTFILE}"
375 |
376 | set_file_perms
377 |
378 | verify_cert
379 |
380 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | ## [v1.7.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.7.0) (2025-01-31)
6 |
7 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.6.0...v1.7.0)
8 |
9 | **Implemented enhancements:**
10 |
11 | - feat: certificate-allowlist setting may only be a file name when used in a container [\#98](https://github.com/voxpupuli/container-puppetdb/pull/98) ([tuxmea](https://github.com/tuxmea))
12 | - feat: add possibility to manage certificate\_allowlist [\#94](https://github.com/voxpupuli/container-puppetdb/pull/94) ([tuxmea](https://github.com/tuxmea))
13 | - feat: update to puppetdb 8.8.1 [\#91](https://github.com/voxpupuli/container-puppetdb/pull/91) ([mababio](https://github.com/mababio))
14 | - feat: streamline Dockerfile [\#87](https://github.com/voxpupuli/container-puppetdb/pull/87) ([rwaffen](https://github.com/rwaffen))
15 | - feat: update to puppetdb 7.20.0 and 8.8.0 [\#86](https://github.com/voxpupuli/container-puppetdb/pull/86) ([rwaffen](https://github.com/rwaffen))
16 | - feat: update to 7.19.1 and 8.7.0 [\#83](https://github.com/voxpupuli/container-puppetdb/pull/83) ([rwaffen](https://github.com/rwaffen))
17 |
18 | **Fixed bugs:**
19 |
20 | - use correct name for certificate-allowlist [\#96](https://github.com/voxpupuli/container-puppetdb/pull/96) ([tuxmea](https://github.com/tuxmea))
21 |
22 | **Closed issues:**
23 |
24 | - Certificate allow list is broken [\#97](https://github.com/voxpupuli/container-puppetdb/issues/97)
25 | - Certificate allow list error [\#95](https://github.com/voxpupuli/container-puppetdb/issues/95)
26 | - Manage cert allowlist [\#88](https://github.com/voxpupuli/container-puppetdb/issues/88)
27 |
28 | **Merged pull requests:**
29 |
30 | - doc: deprecate repo [\#101](https://github.com/voxpupuli/container-puppetdb/pull/101) ([rwaffen](https://github.com/rwaffen))
31 | - Update from voxpupuli modulesync\_config [\#89](https://github.com/voxpupuli/container-puppetdb/pull/89) ([rwaffen](https://github.com/rwaffen))
32 | - Fix docs of PUPPETDB\_JAVA\_ARGS [\#80](https://github.com/voxpupuli/container-puppetdb/pull/80) ([Heap0017](https://github.com/Heap0017))
33 | - Update readme and add hint for the new name [\#77](https://github.com/voxpupuli/container-puppetdb/pull/77) ([rwaffen](https://github.com/rwaffen))
34 |
35 | ## [v1.6.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.6.0) (2024-07-19)
36 |
37 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.5.0...v1.6.0)
38 |
39 | **Implemented enhancements:**
40 |
41 | - Update puppetdb to 7.19.0 and 8.6.0 [\#72](https://github.com/voxpupuli/container-puppetdb/pull/72) ([anders-larsson](https://github.com/anders-larsson))
42 | - Update puppetdb to 8.5.1 [\#70](https://github.com/voxpupuli/container-puppetdb/pull/70) ([anders-larsson](https://github.com/anders-larsson))
43 | - add set -e to all scripts. [\#69](https://github.com/voxpupuli/container-puppetdb/pull/69) ([rwaffen](https://github.com/rwaffen))
44 |
45 | **Merged pull requests:**
46 |
47 | - update link in docu to release how to [\#68](https://github.com/voxpupuli/container-puppetdb/pull/68) ([rwaffen](https://github.com/rwaffen))
48 |
49 | ## [v1.5.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.5.0) (2024-04-15)
50 |
51 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.4.0...v1.5.0)
52 |
53 | **Implemented enhancements:**
54 |
55 | - Enhancement: update puppetdb to 7.18.0 and 8.5.0 [\#65](https://github.com/voxpupuli/container-puppetdb/pull/65) ([j0sh3rs](https://github.com/j0sh3rs))
56 |
57 | **Merged pull requests:**
58 |
59 | - Use shared worflows from crafty [\#66](https://github.com/voxpupuli/container-puppetdb/pull/66) ([rwaffen](https://github.com/rwaffen))
60 |
61 | ## [v1.4.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.4.0) (2024-04-05)
62 |
63 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.3.0...v1.4.0)
64 |
65 | **Implemented enhancements:**
66 |
67 | - update puppetdb to 8.4.1 and 7.17.1 [\#63](https://github.com/voxpupuli/container-puppetdb/pull/63) ([rwaffen](https://github.com/rwaffen))
68 | - disable update check [\#53](https://github.com/voxpupuli/container-puppetdb/pull/53) ([rwaffen](https://github.com/rwaffen))
69 |
70 | **Fixed bugs:**
71 |
72 | - Value does not match schema: {:disable-update-checking \(not \(instance? java.lang.String true\)\)} [\#56](https://github.com/voxpupuli/container-puppetdb/issues/56)
73 | - remove .dockerenv, add it as ENV to Dockerfile [\#62](https://github.com/voxpupuli/container-puppetdb/pull/62) ([rwaffen](https://github.com/rwaffen))
74 | - Add 'ARG UBUNTU\_CODENAME' to final image build so that Podman correctly interprets PUPPET\_DEB environment variable. [\#59](https://github.com/voxpupuli/container-puppetdb/pull/59) ([bschonec](https://github.com/bschonec))
75 | - quote boolean to be string; disable-update-checking has to be a string [\#57](https://github.com/voxpupuli/container-puppetdb/pull/57) ([rwaffen](https://github.com/rwaffen))
76 | - Don't try to chown SSLDIR if it's read-only or we don't have permission [\#49](https://github.com/voxpupuli/container-puppetdb/pull/49) ([bootc](https://github.com/bootc))
77 |
78 | **Closed issues:**
79 |
80 | - Permission denied on ENTRYPOINT when running on Red Hat Openshift [\#61](https://github.com/voxpupuli/container-puppetdb/issues/61)
81 | - Docker image doesn't build correctly when using Podman [\#58](https://github.com/voxpupuli/container-puppetdb/issues/58)
82 | - docker flag "--link" is deprecated and may be removed. [\#51](https://github.com/voxpupuli/container-puppetdb/issues/51)
83 | - Startup fails when running as non-root / read-only [\#48](https://github.com/voxpupuli/container-puppetdb/issues/48)
84 | - We should verify if analytics is disabled upon container start [\#11](https://github.com/voxpupuli/container-puppetdb/issues/11)
85 |
86 | **Merged pull requests:**
87 |
88 | - Remove usage of --link for container examples [\#55](https://github.com/voxpupuli/container-puppetdb/pull/55) ([rwaffen](https://github.com/rwaffen))
89 | - update container links [\#54](https://github.com/voxpupuli/container-puppetdb/pull/54) ([rwaffen](https://github.com/rwaffen))
90 | - update readme, add markdownlint rules [\#52](https://github.com/voxpupuli/container-puppetdb/pull/52) ([rwaffen](https://github.com/rwaffen))
91 |
92 | ## [v1.3.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.3.0) (2024-01-31)
93 |
94 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.2.1...v1.3.0)
95 |
96 | **Implemented enhancements:**
97 |
98 | - PuppetDB 7.16.0 and 8.3.0 [\#44](https://github.com/voxpupuli/container-puppetdb/issues/44)
99 | - Update puppetdb packages [\#45](https://github.com/voxpupuli/container-puppetdb/pull/45) ([tuxmea](https://github.com/tuxmea))
100 |
101 | **Merged pull requests:**
102 |
103 | - add skip-changelog to all release prs [\#46](https://github.com/voxpupuli/container-puppetdb/pull/46) ([rwaffen](https://github.com/rwaffen))
104 | - Add $version-latest tags for Docker images like in puppetserver [\#42](https://github.com/voxpupuli/container-puppetdb/pull/42) ([rwaffen](https://github.com/rwaffen))
105 | - Add option to have custom entry points. [\#41](https://github.com/voxpupuli/container-puppetdb/pull/41) ([tuxmea](https://github.com/tuxmea))
106 | - add shellcheck from reusable workflow [\#38](https://github.com/voxpupuli/container-puppetdb/pull/38) ([rwaffen](https://github.com/rwaffen))
107 | - add documentation on new version schema [\#37](https://github.com/voxpupuli/container-puppetdb/pull/37) ([tuxmea](https://github.com/tuxmea))
108 |
109 | ## [v1.2.1](https://github.com/voxpupuli/container-puppetdb/tree/v1.2.1) (2024-01-03)
110 |
111 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.2.0...v1.2.1)
112 |
113 | **Merged pull requests:**
114 |
115 | - update to new version schema [\#35](https://github.com/voxpupuli/container-puppetdb/pull/35) ([tuxmea](https://github.com/tuxmea))
116 | - incorporate remote scripts [\#33](https://github.com/voxpupuli/container-puppetdb/pull/33) ([tuxmea](https://github.com/tuxmea))
117 |
118 | ## [v1.2.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.2.0) (2023-12-14)
119 |
120 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.1.0...v1.2.0)
121 |
122 | **Implemented enhancements:**
123 |
124 | - Add jre17 to puppetdb [\#30](https://github.com/voxpupuli/container-puppetdb/pull/30) ([tuxmea](https://github.com/tuxmea))
125 |
126 | ## [v1.1.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.1.0) (2023-12-13)
127 |
128 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/v1.0.0...v1.1.0)
129 |
130 | **Closed issues:**
131 |
132 | - update how to release docu [\#20](https://github.com/voxpupuli/container-puppetdb/issues/20)
133 | - add CONTRIBUTING.md [\#18](https://github.com/voxpupuli/container-puppetdb/issues/18)
134 |
135 | **Merged pull requests:**
136 |
137 | - Use correct Xlog:gc syntax [\#28](https://github.com/voxpupuli/container-puppetdb/pull/28) ([tuxmea](https://github.com/tuxmea))
138 | - Remove deprecated Xloggc [\#27](https://github.com/voxpupuli/container-puppetdb/pull/27) ([ldaneliukas](https://github.com/ldaneliukas))
139 | - Add table of contents to README.md [\#26](https://github.com/voxpupuli/container-puppetdb/pull/26) ([rwaffen](https://github.com/rwaffen))
140 | - Fix broken link in README.md [\#25](https://github.com/voxpupuli/container-puppetdb/pull/25) ([rwaffen](https://github.com/rwaffen))
141 | - Update Readme to use containers from github and add contributing link [\#24](https://github.com/voxpupuli/container-puppetdb/pull/24) ([rwaffen](https://github.com/rwaffen))
142 | - add action to update docker hub description [\#23](https://github.com/voxpupuli/container-puppetdb/pull/23) ([rwaffen](https://github.com/rwaffen))
143 | - also push to dockerhub [\#22](https://github.com/voxpupuli/container-puppetdb/pull/22) ([rwaffen](https://github.com/rwaffen))
144 |
145 | ## [v1.0.0](https://github.com/voxpupuli/container-puppetdb/tree/v1.0.0) (2023-11-15)
146 |
147 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.14.0...v1.0.0)
148 |
149 | **Merged pull requests:**
150 |
151 | - Release v1.0.0 [\#21](https://github.com/voxpupuli/container-puppetdb/pull/21) ([rwaffen](https://github.com/rwaffen))
152 | - Update build\_arch to include linux/arm64 [\#19](https://github.com/voxpupuli/container-puppetdb/pull/19) ([rwaffen](https://github.com/rwaffen))
153 | - Add matrix setup to build several versions in parallel specified in a json file [\#17](https://github.com/voxpupuli/container-puppetdb/pull/17) ([rwaffen](https://github.com/rwaffen))
154 | - Update and fix GitHub Actions release workflow [\#16](https://github.com/voxpupuli/container-puppetdb/pull/16) ([ldaneliukas](https://github.com/ldaneliukas))
155 |
156 | ## [7.14.0](https://github.com/voxpupuli/container-puppetdb/tree/7.14.0) (2023-10-19)
157 |
158 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.11.2...7.14.0)
159 |
160 | **Fixed bugs:**
161 |
162 | - Dockerfile: Fix labels for container image [\#7](https://github.com/voxpupuli/container-puppetdb/pull/7) ([bastelfreak](https://github.com/bastelfreak))
163 | - CI: Fix container tags: puppdb-\>puppetdb [\#6](https://github.com/voxpupuli/container-puppetdb/pull/6) ([bastelfreak](https://github.com/bastelfreak))
164 |
165 | **Closed issues:**
166 |
167 | - rename repo [\#8](https://github.com/voxpupuli/container-puppetdb/issues/8)
168 |
169 | **Merged pull requests:**
170 |
171 | - updates to documentation and variable naming [\#15](https://github.com/voxpupuli/container-puppetdb/pull/15) ([rwaffen](https://github.com/rwaffen))
172 | - update documentation [\#14](https://github.com/voxpupuli/container-puppetdb/pull/14) ([rwaffen](https://github.com/rwaffen))
173 | - Cleanup [\#13](https://github.com/voxpupuli/container-puppetdb/pull/13) ([rwaffen](https://github.com/rwaffen))
174 | - set build context to puppetdb [\#12](https://github.com/voxpupuli/container-puppetdb/pull/12) ([rwaffen](https://github.com/rwaffen))
175 | - Update build [\#10](https://github.com/voxpupuli/container-puppetdb/pull/10) ([rwaffen](https://github.com/rwaffen))
176 | - allow to build puppet 8 and 7 versions [\#9](https://github.com/voxpupuli/container-puppetdb/pull/9) ([rwaffen](https://github.com/rwaffen))
177 | - Add CODEOWNERS [\#5](https://github.com/voxpupuli/container-puppetdb/pull/5) ([bastelfreak](https://github.com/bastelfreak))
178 | - fix creds for container build [\#4](https://github.com/voxpupuli/container-puppetdb/pull/4) ([rwaffen](https://github.com/rwaffen))
179 | - Add CI configuration [\#3](https://github.com/voxpupuli/container-puppetdb/pull/3) ([bastelfreak](https://github.com/bastelfreak))
180 | - initial voxpupuli [\#2](https://github.com/voxpupuli/container-puppetdb/pull/2) ([tuxmea](https://github.com/tuxmea))
181 | - dependabot: check for github actions, docker and bundler [\#1](https://github.com/voxpupuli/container-puppetdb/pull/1) ([bastelfreak](https://github.com/bastelfreak))
182 |
183 | ## [7.11.2](https://github.com/voxpupuli/container-puppetdb/tree/7.11.2) (2021-07-01)
184 |
185 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.11.1...7.11.2)
186 |
187 | ## [7.11.1](https://github.com/voxpupuli/container-puppetdb/tree/7.11.1) (2021-07-01)
188 |
189 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.11.0...7.11.1)
190 |
191 | ## [7.11.0](https://github.com/voxpupuli/container-puppetdb/tree/7.11.0) (2021-07-01)
192 |
193 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.10.1...7.11.0)
194 |
195 | ## [7.10.1](https://github.com/voxpupuli/container-puppetdb/tree/7.10.1) (2021-07-01)
196 |
197 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.10.0...7.10.1)
198 |
199 | ## [7.10.0](https://github.com/voxpupuli/container-puppetdb/tree/7.10.0) (2021-07-01)
200 |
201 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.9.2...7.10.0)
202 |
203 | ## [7.9.2](https://github.com/voxpupuli/container-puppetdb/tree/7.9.2) (2021-07-01)
204 |
205 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.9.1...7.9.2)
206 |
207 | ## [7.9.1](https://github.com/voxpupuli/container-puppetdb/tree/7.9.1) (2021-07-01)
208 |
209 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.9.0...7.9.1)
210 |
211 | ## [7.9.0](https://github.com/voxpupuli/container-puppetdb/tree/7.9.0) (2021-07-01)
212 |
213 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.8.0...7.9.0)
214 |
215 | ## [7.8.0](https://github.com/voxpupuli/container-puppetdb/tree/7.8.0) (2021-07-01)
216 |
217 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.7.1...7.8.0)
218 |
219 | ## [7.7.1](https://github.com/voxpupuli/container-puppetdb/tree/7.7.1) (2021-07-01)
220 |
221 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.7.0...7.7.1)
222 |
223 | ## [7.7.0](https://github.com/voxpupuli/container-puppetdb/tree/7.7.0) (2021-07-01)
224 |
225 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.6.0...7.7.0)
226 |
227 | ## [7.6.0](https://github.com/voxpupuli/container-puppetdb/tree/7.6.0) (2021-07-01)
228 |
229 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.5.2...7.6.0)
230 |
231 | ## [7.5.2](https://github.com/voxpupuli/container-puppetdb/tree/7.5.2) (2021-07-01)
232 |
233 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.5.1...7.5.2)
234 |
235 | ## [7.5.1](https://github.com/voxpupuli/container-puppetdb/tree/7.5.1) (2021-07-01)
236 |
237 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.5.0...7.5.1)
238 |
239 | ## [7.5.0](https://github.com/voxpupuli/container-puppetdb/tree/7.5.0) (2021-07-01)
240 |
241 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.22.1...7.5.0)
242 |
243 | ## [6.22.1](https://github.com/voxpupuli/container-puppetdb/tree/6.22.1) (2021-06-30)
244 |
245 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.22.0...6.22.1)
246 |
247 | ## [6.22.0](https://github.com/voxpupuli/container-puppetdb/tree/6.22.0) (2021-06-30)
248 |
249 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.21.0...6.22.0)
250 |
251 | ## [6.21.0](https://github.com/voxpupuli/container-puppetdb/tree/6.21.0) (2021-06-30)
252 |
253 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.20.2...6.21.0)
254 |
255 | ## [6.20.2](https://github.com/voxpupuli/container-puppetdb/tree/6.20.2) (2021-06-30)
256 |
257 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.20.1...6.20.2)
258 |
259 | ## [6.20.1](https://github.com/voxpupuli/container-puppetdb/tree/6.20.1) (2021-06-30)
260 |
261 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.20.0...6.20.1)
262 |
263 | ## [6.20.0](https://github.com/voxpupuli/container-puppetdb/tree/6.20.0) (2021-06-30)
264 |
265 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.19.0...6.20.0)
266 |
267 | ## [6.19.0](https://github.com/voxpupuli/container-puppetdb/tree/6.19.0) (2021-06-30)
268 |
269 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.18.2...6.19.0)
270 |
271 | ## [6.18.2](https://github.com/voxpupuli/container-puppetdb/tree/6.18.2) (2021-06-30)
272 |
273 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.18.1...6.18.2)
274 |
275 | ## [6.18.1](https://github.com/voxpupuli/container-puppetdb/tree/6.18.1) (2021-06-30)
276 |
277 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.18.0...6.18.1)
278 |
279 | ## [6.18.0](https://github.com/voxpupuli/container-puppetdb/tree/6.18.0) (2021-06-30)
280 |
281 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.19.1...6.18.0)
282 |
283 | ## [6.19.1](https://github.com/voxpupuli/container-puppetdb/tree/6.19.1) (2021-06-30)
284 |
285 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.4.0...6.19.1)
286 |
287 | ## [7.4.0](https://github.com/voxpupuli/container-puppetdb/tree/7.4.0) (2021-05-13)
288 |
289 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.4.1...7.4.0)
290 |
291 | ## [7.4.1](https://github.com/voxpupuli/container-puppetdb/tree/7.4.1) (2021-05-13)
292 |
293 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.17.0...7.4.1)
294 |
295 | ## [6.17.0](https://github.com/voxpupuli/container-puppetdb/tree/6.17.0) (2021-05-12)
296 |
297 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.3.1...6.17.0)
298 |
299 | ## [7.3.1](https://github.com/voxpupuli/container-puppetdb/tree/7.3.1) (2021-04-15)
300 |
301 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.3.0...7.3.1)
302 |
303 | ## [7.3.0](https://github.com/voxpupuli/container-puppetdb/tree/7.3.0) (2021-04-15)
304 |
305 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.16.0...7.3.0)
306 |
307 | ## [6.16.0](https://github.com/voxpupuli/container-puppetdb/tree/6.16.0) (2021-04-13)
308 |
309 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.16.1...6.16.0)
310 |
311 | ## [6.16.1](https://github.com/voxpupuli/container-puppetdb/tree/6.16.1) (2021-04-13)
312 |
313 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.2.0...6.16.1)
314 |
315 | ## [7.2.0](https://github.com/voxpupuli/container-puppetdb/tree/7.2.0) (2021-02-19)
316 |
317 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.15.0...7.2.0)
318 |
319 | ## [6.15.0](https://github.com/voxpupuli/container-puppetdb/tree/6.15.0) (2021-02-09)
320 |
321 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.1.0...6.15.0)
322 |
323 | ## [7.1.0](https://github.com/voxpupuli/container-puppetdb/tree/7.1.0) (2021-01-28)
324 |
325 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.14.0...7.1.0)
326 |
327 | ## [6.14.0](https://github.com/voxpupuli/container-puppetdb/tree/6.14.0) (2021-01-27)
328 |
329 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.0.1...6.14.0)
330 |
331 | ## [7.0.1](https://github.com/voxpupuli/container-puppetdb/tree/7.0.1) (2020-11-19)
332 |
333 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.11.0...7.0.1)
334 |
335 | ## [6.11.0](https://github.com/voxpupuli/container-puppetdb/tree/6.11.0) (2020-05-08)
336 |
337 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.11.1...6.11.0)
338 |
339 | ## [6.11.1](https://github.com/voxpupuli/container-puppetdb/tree/6.11.1) (2020-05-08)
340 |
341 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.11.2...6.11.1)
342 |
343 | ## [6.11.2](https://github.com/voxpupuli/container-puppetdb/tree/6.11.2) (2020-05-08)
344 |
345 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.11.3...6.11.2)
346 |
347 | ## [6.11.3](https://github.com/voxpupuli/container-puppetdb/tree/6.11.3) (2020-05-08)
348 |
349 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.12.1...6.11.3)
350 |
351 | ## [6.12.1](https://github.com/voxpupuli/container-puppetdb/tree/6.12.1) (2020-05-08)
352 |
353 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.12.2...6.12.1)
354 |
355 | ## [6.12.2](https://github.com/voxpupuli/container-puppetdb/tree/6.12.2) (2020-05-08)
356 |
357 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.13.0...6.12.2)
358 |
359 | ## [6.13.0](https://github.com/voxpupuli/container-puppetdb/tree/6.13.0) (2020-05-08)
360 |
361 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.13.1...6.13.0)
362 |
363 | ## [6.13.1](https://github.com/voxpupuli/container-puppetdb/tree/6.13.1) (2020-05-08)
364 |
365 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/7.0.0...6.13.1)
366 |
367 | ## [7.0.0](https://github.com/voxpupuli/container-puppetdb/tree/7.0.0) (2020-05-08)
368 |
369 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.12.0...7.0.0)
370 |
371 | ## [6.12.0](https://github.com/voxpupuli/container-puppetdb/tree/6.12.0) (2020-05-08)
372 |
373 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.10.2...6.12.0)
374 |
375 | ## [6.10.2](https://github.com/voxpupuli/container-puppetdb/tree/6.10.2) (2020-04-28)
376 |
377 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.10.1...6.10.2)
378 |
379 | ## [6.10.1](https://github.com/voxpupuli/container-puppetdb/tree/6.10.1) (2020-04-28)
380 |
381 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.10.0...6.10.1)
382 |
383 | ## [6.10.0](https://github.com/voxpupuli/container-puppetdb/tree/6.10.0) (2020-04-21)
384 |
385 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.9.1...6.10.0)
386 |
387 | ## [6.9.1](https://github.com/voxpupuli/container-puppetdb/tree/6.9.1) (2020-02-27)
388 |
389 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.9.0...6.9.1)
390 |
391 | ## [6.9.0](https://github.com/voxpupuli/container-puppetdb/tree/6.9.0) (2020-01-07)
392 |
393 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.8.0...6.9.0)
394 |
395 | ## [6.8.0](https://github.com/voxpupuli/container-puppetdb/tree/6.8.0) (2019-12-12)
396 |
397 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.8.1...6.8.0)
398 |
399 | ## [6.8.1](https://github.com/voxpupuli/container-puppetdb/tree/6.8.1) (2019-12-12)
400 |
401 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.7...6.8.1)
402 |
403 | ## [6.3.7](https://github.com/voxpupuli/container-puppetdb/tree/6.3.7) (2019-12-10)
404 |
405 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.7.3...6.3.7)
406 |
407 | ## [6.7.3](https://github.com/voxpupuli/container-puppetdb/tree/6.7.3) (2019-10-29)
408 |
409 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.7.2...6.7.3)
410 |
411 | ## [6.7.2](https://github.com/voxpupuli/container-puppetdb/tree/6.7.2) (2019-10-19)
412 |
413 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.7.1...6.7.2)
414 |
415 | ## [6.7.1](https://github.com/voxpupuli/container-puppetdb/tree/6.7.1) (2019-10-04)
416 |
417 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.7.0...6.7.1)
418 |
419 | ## [6.7.0](https://github.com/voxpupuli/container-puppetdb/tree/6.7.0) (2019-09-26)
420 |
421 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.6.0...6.7.0)
422 |
423 | ## [6.6.0](https://github.com/voxpupuli/container-puppetdb/tree/6.6.0) (2019-09-13)
424 |
425 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.5.0...6.6.0)
426 |
427 | ## [6.5.0](https://github.com/voxpupuli/container-puppetdb/tree/6.5.0) (2019-08-14)
428 |
429 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.4.0...6.5.0)
430 |
431 | ## [6.4.0](https://github.com/voxpupuli/container-puppetdb/tree/6.4.0) (2019-07-03)
432 |
433 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.4...6.4.0)
434 |
435 | ## [6.3.4](https://github.com/voxpupuli/container-puppetdb/tree/6.3.4) (2019-03-11)
436 |
437 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.6...6.3.4)
438 |
439 | ## [6.3.6](https://github.com/voxpupuli/container-puppetdb/tree/6.3.6) (2019-03-11)
440 |
441 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.3...6.3.6)
442 |
443 | ## [6.3.3](https://github.com/voxpupuli/container-puppetdb/tree/6.3.3) (2019-03-11)
444 |
445 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.2...6.3.3)
446 |
447 | ## [6.3.2](https://github.com/voxpupuli/container-puppetdb/tree/6.3.2) (2019-03-11)
448 |
449 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.1...6.3.2)
450 |
451 | ## [6.3.1](https://github.com/voxpupuli/container-puppetdb/tree/6.3.1) (2019-03-11)
452 |
453 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.0...6.3.1)
454 |
455 | ## [6.3.0](https://github.com/voxpupuli/container-puppetdb/tree/6.3.0) (2019-03-11)
456 |
457 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.3.5...6.3.0)
458 |
459 | ## [6.3.5](https://github.com/voxpupuli/container-puppetdb/tree/6.3.5) (2019-03-11)
460 |
461 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.0.3...6.3.5)
462 |
463 | ## [6.0.3](https://github.com/voxpupuli/container-puppetdb/tree/6.0.3) (2019-02-12)
464 |
465 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.0.4...6.0.3)
466 |
467 | ## [6.0.4](https://github.com/voxpupuli/container-puppetdb/tree/6.0.4) (2019-02-12)
468 |
469 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.12...6.0.4)
470 |
471 | ## [5.2.12](https://github.com/voxpupuli/container-puppetdb/tree/5.2.12) (2019-02-11)
472 |
473 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.11...5.2.12)
474 |
475 | ## [5.2.11](https://github.com/voxpupuli/container-puppetdb/tree/5.2.11) (2019-02-11)
476 |
477 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.10...5.2.11)
478 |
479 | ## [5.2.10](https://github.com/voxpupuli/container-puppetdb/tree/5.2.10) (2019-02-11)
480 |
481 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.15.1...5.2.10)
482 |
483 | ## [5.2.15.1](https://github.com/voxpupuli/container-puppetdb/tree/5.2.15.1) (2019-02-11)
484 |
485 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.8...5.2.15.1)
486 |
487 | ## [5.2.8](https://github.com/voxpupuli/container-puppetdb/tree/5.2.8) (2019-02-11)
488 |
489 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.19...5.2.8)
490 |
491 | ## [5.2.19](https://github.com/voxpupuli/container-puppetdb/tree/5.2.19) (2019-02-11)
492 |
493 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.18...5.2.19)
494 |
495 | ## [5.2.18](https://github.com/voxpupuli/container-puppetdb/tree/5.2.18) (2019-02-11)
496 |
497 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.17...5.2.18)
498 |
499 | ## [5.2.17](https://github.com/voxpupuli/container-puppetdb/tree/5.2.17) (2019-02-11)
500 |
501 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.16...5.2.17)
502 |
503 | ## [5.2.16](https://github.com/voxpupuli/container-puppetdb/tree/5.2.16) (2019-02-11)
504 |
505 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.9...5.2.16)
506 |
507 | ## [5.2.9](https://github.com/voxpupuli/container-puppetdb/tree/5.2.9) (2019-02-11)
508 |
509 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.15...5.2.9)
510 |
511 | ## [5.2.15](https://github.com/voxpupuli/container-puppetdb/tree/5.2.15) (2019-02-11)
512 |
513 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.14...5.2.15)
514 |
515 | ## [5.2.14](https://github.com/voxpupuli/container-puppetdb/tree/5.2.14) (2019-02-11)
516 |
517 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.13...5.2.14)
518 |
519 | ## [5.2.13](https://github.com/voxpupuli/container-puppetdb/tree/5.2.13) (2019-02-11)
520 |
521 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.1.6...5.2.13)
522 |
523 | ## [5.1.6](https://github.com/voxpupuli/container-puppetdb/tree/5.1.6) (2019-02-11)
524 |
525 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.2.0...5.1.6)
526 |
527 | ## [6.2.0](https://github.com/voxpupuli/container-puppetdb/tree/6.2.0) (2019-01-16)
528 |
529 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.0.2...6.2.0)
530 |
531 | ## [6.0.2](https://github.com/voxpupuli/container-puppetdb/tree/6.0.2) (2019-01-02)
532 |
533 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.7...6.0.2)
534 |
535 | ## [5.2.7](https://github.com/voxpupuli/container-puppetdb/tree/5.2.7) (2019-01-02)
536 |
537 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.1.0...5.2.7)
538 |
539 | ## [6.1.0](https://github.com/voxpupuli/container-puppetdb/tree/6.1.0) (2018-12-12)
540 |
541 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.0.1...6.1.0)
542 |
543 | ## [6.0.1](https://github.com/voxpupuli/container-puppetdb/tree/6.0.1) (2018-10-18)
544 |
545 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.5...6.0.1)
546 |
547 | ## [5.2.5](https://github.com/voxpupuli/container-puppetdb/tree/5.2.5) (2018-10-18)
548 |
549 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.6...5.2.5)
550 |
551 | ## [5.2.6](https://github.com/voxpupuli/container-puppetdb/tree/5.2.6) (2018-10-18)
552 |
553 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/6.0.0...5.2.6)
554 |
555 | ## [6.0.0](https://github.com/voxpupuli/container-puppetdb/tree/6.0.0) (2018-09-13)
556 |
557 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.4...6.0.0)
558 |
559 | ## [5.2.4](https://github.com/voxpupuli/container-puppetdb/tree/5.2.4) (2018-06-15)
560 |
561 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/5.2.3...5.2.4)
562 |
563 | ## [5.2.3](https://github.com/voxpupuli/container-puppetdb/tree/5.2.3) (2018-06-15)
564 |
565 | [Full Changelog](https://github.com/voxpupuli/container-puppetdb/compare/64017ff065875698b5bb777c00294b117e239aae...5.2.3)
566 |
567 |
568 |
569 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
570 |
--------------------------------------------------------------------------------