diff --git a/.VERSION b/.VERSION new file mode 100644 index 0000000..3e1ad72 --- /dev/null +++ b/.VERSION @@ -0,0 +1 @@ +1.5.0 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2e32c23 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug report +about: Report bugs and errors found while using the Operator. +title: '' +labels: bug +assignees: '' + +--- + +### Your environment + + +Operator Version: + + +Connect Server Version: + + +Kubernetes Version: + +## What happened? + + +## What did you expect to happen? + + +## Steps to reproduce +1. + + +## Notes & Logs + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e7edc69 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,9 @@ +# docs: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser +blank_issues_enabled: true +contact_links: + - name: 1Password Community + url: https://1password.community/categories/secrets-automation + about: Please ask general Secrets Automation questions here. + - name: 1Password Security Bug Bounty + url: https://bugcrowd.com/agilebits + about: Please report security vulnerabilities here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..9b3d4c3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,32 @@ +--- +name: Feature request +about: Suggest an idea for the Operator +title: '' +labels: feature-request +assignees: '' + +--- + +### Summary + + +### Use cases + + +### Proposed solution + + +### Is there a workaround to accomplish this today? + + +### References & Prior Work + + +* +* diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..827f1be --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,21 @@ +name: Build and Test +on: [push, pull_request] + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.18 + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Build + run: go build -v ./... + + - name: Test + run: make test diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml new file mode 100644 index 0000000..e4340c6 --- /dev/null +++ b/.github/workflows/release-pr.yml @@ -0,0 +1,85 @@ +on: + create: + branches: + +name: Open Release PR for review + +jobs: + # This job is necessary because GitHub does not (yet) support + # filtering `create` triggers by branch name. + # See: https://github.community/t/trigger-job-on-branch-created/16878/5 + should_create_pr: + name: Check if PR for branch already exists + runs-on: ubuntu-latest + outputs: + result: ${{ steps.is_release_branch_without_pr.outputs.result }} + steps: + - id: is_release_branch_without_pr + name: Find matching PR + uses: actions/github-script@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // Search for an existing PR with head & base + // that match the created branch + + const [releaseBranchName] = context.ref.match("release/v[0-9]+\.[0-9]+\.[0-9]+") || [] + + if(!releaseBranchName) { return false } + + const {data: prs} = await github.pulls.list({ + ...context.repo, + state: 'open', + head: `1Password:${releaseBranchName}`, + base: context.payload.master_branch + }) + + return prs.length === 0 + + create_pr: + needs: should_create_pr + if: needs.should_create_pr.outputs.result == 'true' + name: Create Release Pull Request + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Parse release version + id: get_version + run: echo "::set-output name=version::$(echo $GITHUB_REF | sed 's|^refs/heads/release/v?*||g')" + + - name: Prepare Pull Request + id: prep_pr + run: | + CHANGELOG_PATH=$(printf "%s/CHANGELOG.md" "${GITHUB_WORKSPACE}") + + LOG_ENTRY=$(awk '/START\/v[0-9]+\.[0-9]+\.[0-9]+*/{f=1; next} /---/{if (f == 1) exit} f' "${CHANGELOG_PATH}") + export PR_BODY=$(cat <. tags. + +--- + +[//]: # "START/v1.0.0" + +# v1.0.0 + +## Features: + +- Option to automatically deploy 1Password Connect via the operator +- Ignore restart annotation when looking for 1Password annotations +- Release Automation +- Upgrading apiextensions.k8s.io/v1beta apiversion from the operator custom resource +- Adding configuration for auto rolling restart on deployments +- Configure Auto Restarts for a OnePasswordItem Custom Resource +- Update Connect Dependencies to latest +- Add Github action for building and testing operator + +## Fixes: + +- Fix spec field example for OnePasswordItem in readme +- Casing of annotations are now consistent + +--- + +[//]: # "START/v0.0.2" + +# v0.0.2 + +## Features: + +- Items can now be accessed by either `vaults//items/` or `vaults//items/` + +--- + +[//]: # "START/v0.0.1" + +# v0.0.1 + +Initial 1Password Operator release + +## Features + +- watches for deployment creations with `onepassword` annotations and creates an associated kubernetes secret +- watches for `onepasswordsecret` crd creations and creates an associated kubernetes secrets +- watches for changes to 1Password secrets associated with kubernetes secrets and updates the kubernetes secret with changes +- restart pods when secret has been updated +- cleanup of kubernetes secrets when deployment or `onepasswordsecret` is deleted + +--- diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5af7158 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 1Password + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 5d652d2..e2f2d93 100644 --- a/Makefile +++ b/Makefile @@ -233,3 +233,31 @@ catalog-build: opm ## Build a catalog image. .PHONY: catalog-push catalog-push: ## Push a catalog image. $(MAKE) docker-push IMG=$(CATALOG_IMG) + +## Release functions ===================== + +release/prepare: .check_git_clean ## Updates changelog and creates release branch (call with 'release/prepare version=') + + @test $(version) || (echo "[ERROR] version argument not set."; exit 1) + @git fetch --quiet origin $(MAIN_BRANCH) + + @echo $(version) | tr -d '\n' | tee $(versionFile) &>/dev/null + + @NEW_VERSION=$(version) $(SCRIPTS_DIR)/prepare-release.sh + +release/tag: .check_git_clean ## Creates git tag + @git pull --ff-only + @echo "Applying tag 'v$(curVersion)' to HEAD..." + @git tag --sign "v$(curVersion)" -m "Release v$(curVersion)" + @echo "[OK] Success!" + @echo "Remember to call 'git push --tags' to persist the tag." + +## Helper functions ===================== + +.check_git_clean: +ifneq ($(GIT_BRANCH), $(MAIN_BRANCH)) + @echo "[ERROR] Please checkout default branch '$(MAIN_BRANCH)' and re-run this command."; exit 1; +endif +ifneq ($(WORKTREE_CLEAN), 0) + @echo "[ERROR] Uncommitted changes found in worktree. Address them and try again."; exit 1; +endif diff --git a/scripts/prepare-release.sh b/scripts/prepare-release.sh new file mode 100755 index 0000000..9271428 --- /dev/null +++ b/scripts/prepare-release.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +# +# prepare-release.sh +# (Note: This should be called by `make release/prepare` because it depends +# on several variables set by the Makefile) +# +# Performs release preparation tasks: +# - Creates a release branch +# - Renames "LATEST" section to the new version number +# - Adds new "LATEST" entry to the changelog +# +############################################## +set -Eeuo pipefail + +if [[ -z "${NEW_VERSION:-}" ]]; then + echo "[ERROR] NEW_VERSION environment variable not defined." >&2 + exit 1 +fi + +# Script called from within a git repo? +if [[ $(git rev-parse --is-inside-work-tree &>/dev/null) -ne 0 ]]; then + echo "[ERROR] Current directory (${SRCDIR}) is not a git repository" >&2 + exit 1 +fi + +REPO_ROOT=$(git rev-parse --show-toplevel) +CHANGELOG_FILENAME=${CHANGELOG:-"CHANGELOG.md"} + +# normalize version by removing `v` prefix +VERSION_NUM=${NEW_VERSION/#v/} +RELEASE_BRANCH=$(printf "release/v%s" "${VERSION_NUM}") + +function updateChangelog() { + local tmpfile + + trap '[ -e "${tmpfile}" ] && rm "${tmpfile}"' RETURN + + local changelogFile + changelogFile=$(printf "%s/%s" "${REPO_ROOT}" "${CHANGELOG_FILENAME}") + + # create Changelog file if not exists + if ! [[ -f "${REPO_ROOT}/${CHANGELOG_FILENAME}" ]]; then + touch "${REPO_ROOT}/${CHANGELOG_FILENAME}" && \ + git add "${REPO_ROOT}/${CHANGELOG_FILENAME}" + fi + + tmpfile=$(mktemp) + + # Replace "Latest" in the top-most changelog block with new version + # Then push a new "latest" block to top of the changelog + awk 'NR==1, /---/{ sub(/START\/LATEST/, "START/v'${VERSION_NUM}'"); sub(/# Latest/, "# v'${VERSION_NUM}'") } {print}' \ + "${changelogFile}" > "${tmpfile}" + + # Inserts "Latest" changelog HEREDOC at the top of the file + cat - "${tmpfile}" << EOF > "${REPO_ROOT}/${CHANGELOG_FILENAME}" +[//]: # (START/LATEST) +# Latest + +## Features + * A user-friendly description of a new feature. {issue-number} + +## Fixes + * A user-friendly description of a fix. {issue-number} + +## Security + * A user-friendly description of a security fix. {issue-number} + +--- + +EOF +} + +function _main() { + + # Stash version changes + git stash push &>/dev/null + + if ! git checkout -b "${RELEASE_BRANCH}" origin/"${MAIN_BRANCH:-main}"; then + echo "[ERROR] Could not check out release branch." >&2 + git stash pop &>/dev/null + exit 1 + fi + + # Add the version changes to release branch + git stash pop &>/dev/null + + updateChangelog + + cat << EOF + +[SUCCESS] Changelog updated & release branch created: + New Version: ${NEW_VERSION} + Release Branch: ${RELEASE_BRANCH} + +Next steps: + 1. Edit the changelog notes in ${CHANGELOG_FILENAME} + 2. Commit changes to the release branch + 3. Push changes to remote => git push origin ${RELEASE_BRANCH} + +EOF + exit 0 +} + +_main