diff --git a/.github/dependabot.yml b/.github/dependabot.yml index df7b865..d560ad9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,9 +17,13 @@ updates: schedule: interval: "weekly" ignore: + # Managed by cisagov/skeleton-generic - dependency-name: actions/cache - dependency-name: actions/checkout + - dependency-name: actions/setup-go - dependency-name: actions/setup-python + - dependency-name: hashicorp/setup-terraform + - dependency-name: mxschmitt/action-tmate # Managed by cisagov/skeleton-docker - dependency-name: actions/download-artifact - dependency-name: actions/github-script @@ -28,6 +32,7 @@ updates: - dependency-name: docker/login-action - dependency-name: docker/setup-buildx-action - dependency-name: docker/setup-qemu-action + - dependency-name: github/codeql-action - package-ecosystem: "pip" directory: "/" diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..e8813ce --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,70 @@ +--- +# Rather than breaking up descriptions into multiline strings we disable that +# specific rule in yamllint for this file. +# yamllint disable rule:line-length +- color: "eb6420" + description: This issue or pull request is awaiting the outcome of another issue or pull request + name: blocked +- color: "000000" + description: This issue or pull request involves changes to existing functionality + name: breaking change +- color: "d73a4a" + description: This issue or pull request addresses broken functionality + name: bug +- color: "07648d" + description: This issue will be advertised on code.gov's Open Tasks page (https://code.gov/open-tasks) + name: code.gov +- color: "0366d6" + description: Pull requests that update a dependency file + name: dependencies +- color: "2497ed" + description: Pull requests that update Docker code + name: docker +- color: "5319e7" + description: This issue or pull request improves or adds to documentation + name: documentation +- color: "cfd3d7" + description: This issue or pull request already exists or is covered in another issue or pull request + name: duplicate +- color: "b005bc" + description: A high-level objective issue encompassing multiple issues instead of a specific unit of work + name: epic +- color: "000000" + description: Pull requests that update GitHub Actions code + name: github-actions +- color: "0e8a16" + description: This issue or pull request is well-defined and good for newcomers + name: good first issue +- color: "ff7518" + description: Pull request that should count toward Hacktoberfest participation + name: hacktoberfest-accepted +- color: "a2eeef" + description: This issue or pull request will add or improve functionality, maintainability, or ease of use + name: improvement +- color: "fef2c0" + description: This issue or pull request is not applicable, incorrect, or obsolete + name: invalid +- color: "ce099a" + description: This pull request is ready to merge during the next Lineage Kraken release + name: kraken 🐙 +- color: "a4fc5d" + description: This issue or pull request requires further information + name: need info +- color: "fcdb45" + description: This pull request is awaiting an action or decision to move forward + name: on hold +- color: "ef476c" + description: This issue is a request for information or needs discussion + name: question +- color: "00008b" + description: This issue or pull request adds or otherwise modifies test code + name: test +- color: "1d76db" + description: This issue or pull request pulls in upstream updates + name: upstream update +- color: "d4c5f9" + description: This issue or pull request increments the version number + name: version bump +- color: "ffffff" + description: This issue will not be incorporated + name: wontfix diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f7087f..4a0853f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,28 +45,24 @@ jobs: uses: cisagov/setup-env-github-action@develop - uses: actions/checkout@v3 - id: setup-python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: "3.10" # We need the Go version and Go cache location for the actions/cache step, # so the Go installation must happen before that. - - uses: actions/setup-go@v2 + - id: setup-go + uses: actions/setup-go@v3 with: - go-version: "1.16" - - name: Store installed Go version - id: go-version - run: | - echo "::set-output name=version::"\ - "$(go version | sed 's/^go version go\([0-9.]\+\) .*/\1/')" + go-version: "1.19" - name: Lookup Go cache directory id: go-cache run: | - echo "::set-output name=dir::$(go env GOCACHE)" + echo "dir=$(go env GOCACHE)" >> $GITHUB_OUTPUT - uses: actions/cache@v3 env: BASE_CACHE_KEY: "${{ github.job }}-${{ runner.os }}-\ py${{ steps.setup-python.outputs.python-version }}-\ - go${{ steps.go-version.outputs.version }}-\ + go${{ steps.setup-go.outputs.go-version }}-\ packer${{ steps.setup-env.outputs.packer-version }}-\ tf${{ steps.setup-env.outputs.terraform-version }}-" with: @@ -102,7 +98,7 @@ jobs: ${{ env.CURL_CACHE_DIR }}/"${PACKER_ZIP}" sudo mv /usr/local/bin/packer /usr/local/bin/packer-default sudo ln -s /opt/packer/packer /usr/local/bin/packer - - uses: hashicorp/setup-terraform@v1 + - uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ steps.setup-env.outputs.terraform-version }} - name: Install shfmt @@ -178,7 +174,7 @@ jobs: - uses: actions/checkout@v3 - name: Gather repository metadata id: repo - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: script: | const repo = await github.rest.repos.get(context.repo) @@ -219,9 +215,9 @@ jobs: do TAGS="${TAGS},ghcr.io/${i}" done - echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ') - echo ::set-output name=source_version::$(./bump_version.sh show) - echo ::set-output name=tags::${TAGS} + echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + echo "source_version=$(./bump_version.sh show)" >> $GITHUB_OUTPUT + echo "tags=${TAGS}" >> $GITHUB_OUTPUT echo tags=${TAGS} - name: Setup tmate debug session uses: mxschmitt/action-tmate@v3 @@ -305,9 +301,9 @@ jobs: steps: - uses: actions/checkout@v3 - id: setup-python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: "3.10" - name: Cache testing environments uses: actions/cache@v3 env: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 33d1999..bf0d148 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,5 +1,4 @@ --- - # For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # @@ -11,10 +10,12 @@ on: push: # Dependabot triggered push events have read-only access, but uploading code # scanning requires write access. - branches-ignore: [dependabot/**] + branches-ignore: + - dependabot/** pull_request: # The branches below must be a subset of the branches above - branches: [develop] + branches: + - develop schedule: - cron: '0 21 * * 6' @@ -22,48 +23,45 @@ jobs: analyze: name: Analyze runs-on: ubuntu-latest - + permissions: + # required for all workflows + security-events: write strategy: fail-fast: false matrix: # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', - # 'python'] - language: ['python'] + # Supported options are go, javascript, csharp, python, cpp, and java + language: + - python # Learn more... # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a - # config file. By default, queries listed here will override any - # specified in a config file. Prefix the list here with "+" to use - # these queries and those in the config file. queries: - # ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or + # Autobuild attempts to build any compiled languages (C/C++, C#, or # Java). If this step fails, then you should remove it and run the build - # manually (see below) + # manually (see below). - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following - # three lines and modify them (or add more) to build your code if your - # project uses a compiled language + # three lines and modify them (or add more) to build your code if your + # project uses a compiled language # - run: | - # make bootstrap - # make release + # make bootstrap + # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml new file mode 100644 index 0000000..ae7c091 --- /dev/null +++ b/.github/workflows/sync-labels.yml @@ -0,0 +1,29 @@ +--- +name: sync-labels + +on: + push: + paths: + - '.github/labels.yml' + - '.github/workflows/sync-labels.yml' + +permissions: + contents: read + +jobs: + labeler: + permissions: + # actions/checkout needs this to fetch code + contents: read + # crazy-max/ghaction-github-labeler needs this to manage repository labels + issues: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Sync repository labels + if: success() + uses: crazy-max/ghaction-github-labeler@v4 + with: + # This is a hideous ternary equivalent so we only do a dry run unless + # this workflow is triggered by the develop branch. + dry-run: ${{ github.ref_name == 'develop' && 'false' || 'true' }} diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 8950263..0000000 --- a/.lgtm.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -extraction: - python: - python_setup: - version: 3 - requirements_files: - - requirements-test.txt - setup_py: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6cc81b..57af43d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-case-conflict - id: check-executables-have-shebangs @@ -18,6 +18,7 @@ repos: args: - --allow-missing-credentials - id: detect-private-key + # Ignore the fake private key in this repo exclude: src/secrets/privkey.pem - id: end-of-file-fixer exclude: files/(issue|motd) @@ -32,17 +33,17 @@ repos: # Text file hooks - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.31.1 + rev: v0.32.2 hooks: - id: markdownlint args: - --config=.mdl_config.yaml - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.6.1 + rev: v3.0.0-alpha.4 hooks: - id: prettier - repo: https://github.com/adrienverge/yamllint - rev: v1.26.3 + rev: v1.28.0 hooks: - id: yamllint args: @@ -50,14 +51,14 @@ repos: # GitHub Actions hooks - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.14.2 + rev: 0.18.4 hooks: - id: check-github-actions - id: check-github-workflows # pre-commit hooks - repo: https://github.com/pre-commit/pre-commit - rev: v2.17.0 + rev: v2.20.0 hooks: - id: validate_manifest @@ -82,6 +83,7 @@ repos: - id: shell-lint # Python hooks + # Run bandit on the "tests" tree with a configuration - repo: https://github.com/PyCQA/bandit rev: 1.7.4 hooks: @@ -90,19 +92,19 @@ repos: files: tests args: - --config=.bandit.yml - # Run bandit everything but tests directory + # Run bandit on everything except the "tests" tree - repo: https://github.com/PyCQA/bandit - rev: 1.7.0 + rev: 1.7.4 hooks: - id: bandit name: bandit (everything else) exclude: tests - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black - - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 + - repo: https://github.com/PyCQA/flake8 + rev: 5.0.4 hooks: - id: flake8 additional_dependencies: @@ -112,11 +114,11 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.942 + rev: v0.990 hooks: - id: mypy - repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 + rev: v3.2.0 hooks: - id: pyupgrade @@ -129,14 +131,14 @@ repos: # Terraform hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.64.0 + rev: v1.76.0 hooks: - id: terraform_fmt - id: terraform_validate # Docker hooks - repo: https://github.com/IamTheFij/docker-pre-commit - rev: v2.1.0 + rev: v2.1.1 hooks: - id: docker-compose-check diff --git a/.yamllint b/.yamllint index 76a1cce..2a119a6 100644 --- a/.yamllint +++ b/.yamllint @@ -8,6 +8,16 @@ rules: # this behavior. comments-indentation: disable + # yamllint does not allow inline mappings that exceed the line length by + # default. There are many scenarios where the inline mapping may be a key, + # hash, or other long value that would exceed the line length but cannot + # reasonably be broken across lines. + line-length: + # This rule implies the allow-non-breakable-words rule + allow-non-breakable-inline-mappings: true + # Allows a 10% overage from the default limit of 80 + max: 88 + # yamllint doesn't like when we use yes and no for true and false, # but that's pretty standard in Ansible. truthy: disable diff --git a/Dockerfile b/Dockerfile index 332be8c..52927ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,45 +4,75 @@ FROM debian:bullseye-slim ARG VERSION +### # For a list of pre-defined annotation keys and value types see: # https://github.com/opencontainers/image-spec/blob/master/annotations.md +# # Note: Additional labels are added by the build workflow. -LABEL org.opencontainers.image.authors="mark.feldhousen@cisa.dhs.gov" +### +LABEL org.opencontainers.image.authors="vm-fusion-dev-group@trio.dhs.gov" LABEL org.opencontainers.image.vendor="Cybersecurity and Infrastructure Security Agency" -RUN apt-get update && \ -DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ -ca-certificates \ -diceware \ -dovecot-imapd \ -dovecot-lmtpd \ -gettext-base \ -mailutils \ -opendkim \ -opendkim-tools \ -opendmarc \ -postfix \ -procmail \ -sasl2-bin \ -&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +### +# This Docker container does not use an unprivileged user because it +# must be able to modify postfix and opendkim config files and +# therefore must run as root. +### +### +# Upgrade the system +### +RUN apt-get update --quiet --quiet \ + && apt-get upgrade --quiet --quiet + +### +# Install everything we need +### +ENV DEPS \ + ca-certificates \ + diceware \ + dovecot-imapd \ + dovecot-lmtpd \ + gettext-base \ + mailutils \ + opendkim \ + opendkim-tools \ + opendmarc \ + postfix \ + procmail \ + sasl2-bin +RUN DEBIAN_FRONTEND=noninteractive \ + apt-get install --quiet --quiet --yes \ + --no-install-recommends --no-install-suggests \ + $DEPS \ + && apt-get --quiet --quiet clean \ + && rm --recursive --force /var/lib/apt/lists/* /tmp/* /var/tmp/* + +### +# Create a mailarchive user +### RUN adduser mailarchive --quiet --disabled-password \ ---shell /usr/sbin/nologin --gecos "Mail Archive" + --shell /usr/sbin/nologin --gecos "Mail Archive" +### +# Setup entrypoint +### USER root WORKDIR /root -# make backups of configurations. These are modified at startup. +# Make backups of configurations. These are modified at startup. RUN mv /etc/default/opendkim /etc/default/opendkim.orig RUN mv /etc/default/opendmarc /etc/default/opendmarc.orig RUN mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig RUN mv /etc/postfix/master.cf /etc/postfix/master.cf.orig -COPY ./src/templates ./templates/ -COPY ./src/docker-entrypoint.sh ./src/version.txt ./ +COPY src/templates templates/ +COPY src/docker-entrypoint.sh src/version.txt ./ +### +# Prepare to run +### VOLUME ["/var/log", "/var/spool/postfix"] EXPOSE 25/TCP 587/TCP 993/TCP - ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["postfix", "-v", "start-fg"] diff --git a/bump_version.sh b/bump_version.sh index a6c8ed9..963389f 100755 --- a/bump_version.sh +++ b/bump_version.sh @@ -12,6 +12,9 @@ README_FILE=README.md HELP_INFORMATION="bump_version.sh (show|major|minor|patch|prerelease|build|finalize)" old_version=$(sed -n "s/^__version__ = \"\(.*\)\"$/\1/p" $VERSION_FILE) +# Comment out periods so they are interpreted as periods and don't +# just match any character +old_version_regex=${old_version//\./\\\.} if [ $# -ne 1 ]; then echo "$HELP_INFORMATION" @@ -21,9 +24,9 @@ else new_version=$(python -c "import semver; print(semver.bump_$1('$old_version'))") echo Changing version from "$old_version" to "$new_version" tmp_file=/tmp/version.$$ - sed "s/$old_version/$new_version/" $VERSION_FILE > $tmp_file + sed "s/$old_version_regex/$new_version/" $VERSION_FILE > $tmp_file mv $tmp_file $VERSION_FILE - sed "s/$old_version/$new_version/" $README_FILE > $tmp_file + sed "s/$old_version_regex/$new_version/" $README_FILE > $tmp_file mv $tmp_file $README_FILE git add $VERSION_FILE $README_FILE git commit -m"Bump version from $old_version to $new_version" @@ -33,12 +36,12 @@ else new_version=$(python -c "import semver; print(semver.finalize_version('$old_version'))") echo Changing version from "$old_version" to "$new_version" tmp_file=/tmp/version.$$ - sed "s/$old_version/$new_version/" $VERSION_FILE > $tmp_file + sed "s/$old_version_regex/$new_version/" $VERSION_FILE > $tmp_file mv $tmp_file $VERSION_FILE - sed "s/$old_version/$new_version/" $README_FILE > $tmp_file + sed "s/$old_version_regex/$new_version/" $README_FILE > $tmp_file mv $tmp_file $README_FILE git add $VERSION_FILE $README_FILE - git commit -m"Bump version from $old_version to $new_version" + git commit -m"Finalize version from $old_version to $new_version" git push ;; show) diff --git a/src/version.txt b/src/version.txt index 3dc1f76..485f44a 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1"