├── 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 | [![CI](https://github.com/voxpupuli/container-puppetdb/actions/workflows/ci.yaml/badge.svg)](https://github.com/voxpupuli/container-puppetdb/actions/workflows/ci.yaml) 8 | [![License](https://img.shields.io/github/license/voxpupuli/container-puppetdb.svg)](https://github.com/voxpupuli/container-puppetdb/blob/main/LICENSE) 9 | [![Donated by Puppet](https://img.shields.io/badge/Donated%20by-Puppet-blue.svg)](https://www.puppet.com) 10 | [![Sponsored by betadots GmbH](https://img.shields.io/badge/Sponsored%20by-betadots%20GmbH-blue.svg)](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 | --------------------------------------------------------------------------------