From c57702e4641f11e2d118fa7cc4584670134418ef Mon Sep 17 00:00:00 2001 From: Edwin Shin Date: Tue, 24 Dec 2019 11:27:59 +0800 Subject: [PATCH] chore: minor updates to docs, comments, logging. Adds CONTRIBUTING.md --- CHANGELOG.md | 12 +++++-- CONTRIBUTING.md | 23 ++++++++++++ README.md | 52 ++++++++++++++++++++------- src/discreetly/backends/__init__.py | 2 ++ src/discreetly/backends/aws/README.md | 2 ++ src/discreetly/session.py | 4 +-- 6 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 11be95a..623e8ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,13 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Use `LOGLEVEL` environment variable to set log level in the cli +## [v0.1.1] - 2019-12-24 -## [0.1.0] - 2019-12-18 +### Added + +- Use `LOGLEVEL` environment variable to set log level in the cli ([#1]) + +## [v0.1.0] - 2019-12-18 ### Added - Initial release: support for AWS KMS + Parameter Store and GCP KMS + Datastore [unreleased]: https://github.com/tra-sg/discreetly/compare/v0.1.0...HEAD -[0.0.1]: https://github.com/tra-sg/discreetly/releases/tag/v0.1.0 +[v0.1.1]: https://github.com/tra-sg/discreetly/releases/tag/v0.1.1 +[v0.1.0]: https://github.com/tra-sg/discreetly/releases/tag/v0.1.0 +[#1]: https://github.com/tra-sg/discreetly/issues/1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fa1ad24 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +First off, thank you for considering contributing to discreetly! + +This document could use some contributions to make it useful. How meta! + +We definitely want contributions in the form of: + +- documentation + - end-user + - usage + - recommendations for usage (i.e. setting up profiles, using multiple keys, different permissions, etc) + - developer + - how to contribute a new backend (e.g. azure?) +- code + - test coverage for gcp + - new features like improved/new backends + - bug-fixes + +In the meantime, some references for a good CONTRIBUTING.md: + +- https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md +- https://mozillascience.github.io/working-open-workshop/contributing/ diff --git a/README.md b/README.md index 22e1797..bb20135 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ Applications often require access to secrets such as database passwords or API k `discreetly` provides a consistent API for managing secrets across both AWS and GCP. It encourages you to partition your secrets and encryption keys so that your web application only has access to the secrets it needs to run and not, for example, access to infrastructure secrets only needed by your infrastructure management tools. ---- - ## Installation `discreetly` does not set up any infrastructure for you. At a minimum, you need to have i) credentials available for authenticating with AWS and/or Google, ii) permissions to use KMS to encrypt and decrypt secrets, and iii) permissions to read/write to the underlying store. @@ -36,8 +34,6 @@ For use as a library, install `discreetly` specifying which backends you need to $ pip install discreetly[aws,gcp] ``` ---- - ## Configuration `discreetly` can be configured with a JSON file, e.g.: @@ -61,8 +57,6 @@ Because a profile can specify a `keyid`, you can have named profiles not only fo `discreetly` will search for a configuration file at the location provided by the environment variable `DISCREETLY_CONFIG_FILE`, falling back to a file named `discreetly.json` in the current directory. ---- - ## Frequently Asked Questions (FAQ) 1. What about credstash/Chamber/Vault/etc.? @@ -73,8 +67,6 @@ Because a profile can specify a `keyid`, you can have named profiles not only fo Vault is great if you have the resources to support it. ---- - ## Troubleshooting Most issues are related to authentication or permissions with your cloud provider. @@ -87,12 +79,16 @@ $ LOGLEVEL=DEBUG discreetly get my/super/secret ### AWS -Verify that you can use the AWS CLI to access Parameter Store, e.g.: +If you have the AWS CLI installed, verify that you can use it to access Parameter Store, e.g.: ```console $ aws ssm get-parameter /path/to/parameter --with-decryption ``` +If that works, then the problem may very well be with `discreetly` and you should consider opening an issue. + +However, if that's not working, it's likely a configuration or authentication issue. Under the hood, `discreetly` uses Boto 3, so consult their documentation on [setting up your authentication credentials](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html#configuration). + ### GCP Unfortunately, [gcloud](https://cloud.google.com/sdk/gcloud/reference/datastore/) doesn't support much of the Datastore API, so it's a little harder to sanity test any issues in your local environment. @@ -103,8 +99,6 @@ Verify that you've followed the steps in [Obtaining and providing service accoun 2. Saving the JSON file for the service account locally 3. Setting the path to the JSON file in the environment variable, `GOOGLE_APPLICATION_CREDENTIALS` ---- - ## Library usage ```console @@ -138,8 +132,6 @@ acme.set('acme/prod/postgres/password', 'super-secret', keyid='alias/prod_key') acme.get('acme/prod/postgres/password') # no need to specify the keyid for get ``` ---- - ## Development `discreetly` is written in Python and supports Python 2.7 and 3.3+. @@ -147,3 +139,37 @@ acme.get('acme/prod/postgres/password') # no need to specify the keyid for get After cloning the repo, run `pip install -r requirements.txt` to install the required development dependencies (e.g. pytest, flake8, etc.) You can run `pytest` to run the unit tests locally or `tox` to run all the tests under Python 2.7 and 3.x. + +### Releases + +- Review and update `CHANGELOG.md` in a new release branch + + - The following will show commits since the last tag beginning with 'v': + + ```console + $ git log $(git describe --tags --match "v*" --abbrev=0)..HEAD` + ``` + + - Replace `[Unreleased]` with the new [semver](https://semver.org/) and release date, e.g. `[0.1.2] - 2019-12-13` + - Add a new `[Unreleased]` placeholder above the new version you just created + +- Create a new PR + + - The following lists all commits since the last tag, which may be useful for including in the PR description: + + `git log --pretty=format:"* %h %s" $(git describe --tags --abbrev=0 @^)..@` + +- Once the PR is merged to master and passes all status checks, create and push a new signed, annotated tag, e.g.: + + ```console + $ LAST_VERSION=$(git describe --tags --match "v*" --abbrev=0) + $ VERSION=v0.1.1 + $ awk "/^## \[${VERSION}/{flag=1;}/## \[${LAST_VERSION}/{flag=0} flag" CHANGELOG.md | git tag -s -a v0.1.2 --cleanup=whitespace -F - + $ git push --follow-tags + ``` + + The `awk` command above grabs the contents of the CHANGELOG for `$VERSION` to include as the message for the annotated git tag. It's fairly brittle in its assumptions about the format of the CHANGELOG. so you might just run the awk command: + + > `awk "/^## \[${VERSION}/{flag=1;}/## \[${LAST_VERSION}/{flag=0} flag" CHANGELOG.md` + + as a sanity check before creating & pushing the tag. diff --git a/src/discreetly/backends/__init__.py b/src/discreetly/backends/__init__.py index de34277..a64211f 100644 --- a/src/discreetly/backends/__init__.py +++ b/src/discreetly/backends/__init__.py @@ -2,6 +2,8 @@ class AbstractBackend(object): + """Base class for discreetly backends.""" + def __init__(self, config, *args, **kwargs): self.config = config super(AbstractBackend, self).__init__() diff --git a/src/discreetly/backends/aws/README.md b/src/discreetly/backends/aws/README.md index 9dc40f6..fe2bd1c 100644 --- a/src/discreetly/backends/aws/README.md +++ b/src/discreetly/backends/aws/README.md @@ -13,3 +13,5 @@ This backend uses KMS and SSM Parameter Store. ### Notes If `keyid` is not specified, the default is the AWS managed CMK for your account, `alias/aws/ssm`. + +--- diff --git a/src/discreetly/session.py b/src/discreetly/session.py index 2dfe9c7..d149060 100644 --- a/src/discreetly/session.py +++ b/src/discreetly/session.py @@ -35,7 +35,7 @@ def __init__(self, config=None, profile="default"): self.config = json.load(configfile) logger.debug( - "config:\n" + json.dumps(self.config, sort_keys=True, indent=4) + "config:\n%s", json.dumps(self.config, sort_keys=True, indent=4) ) self.profile = self.config.get(profile) @@ -43,7 +43,7 @@ def __init__(self, config=None, profile="default"): raise KeyError('Invalid profile: "%s"' % profile) logger.debug( - "profile:\n" + json.dumps(self.profile, sort_keys=True, indent=4) + "profile:\n%s", json.dumps(self.profile, sort_keys=True, indent=4) ) type = self.profile.get("type")