Skip to content

Commit

Permalink
Merge pull request #8 from mgvalverde/develop
Browse files Browse the repository at this point in the history
First release
  • Loading branch information
mgvalverde authored Aug 30, 2024
2 parents c3bb4e4 + b500886 commit 6467d8e
Show file tree
Hide file tree
Showing 46 changed files with 4,170 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Dependencies**
List of dependencies and version used.


**Additional context**
Add any other context about the problem here.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Additional context**
Add any other context or screenshots about the feature request here.
145 changes: 145 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: Release
run-name: Release 🚀

on:
push:
branches:
- main

permissions:
contents: read

env:
POETRY_VERSION: "1.8.3"
PYTHON_VERSION: "3.9"


jobs:

build:
name: Build and Release
runs-on: ubuntu-latest

permissions:
id-token: write
contents: write

outputs:
target_version: ${{ steps.export_version.outputs.target_version }}

steps:
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install Poetry v${{ env.POETRY_VERSION }}
run: pipx install poetry==${{ env.POETRY_VERSION }}

- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Use Python Semantic Release to prepare release
id: release
uses: python-semantic-release/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
if-no-files-found: 'error'

- name: Save Tag reference
id: export_version
run: echo "target_version=$(git describe --exact-match | cut -c2-)" >> $GITHUB_OUTPUT


publish-to-test-pypi:
name: Publish to Test PyPI
runs-on: ubuntu-latest
needs:
- build

permissions:
id-token: write
contents: write

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

test-installation-testpypi:
name: Test installation from Test PyPI
runs-on: ubuntu-latest
needs:
- build
- publish-to-test-pypi
steps:
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Installation test (with retry)
uses: nick-fields/retry@v2
env:
TARGET_VERSION: ${{needs.build.outputs.target_version}}
with:
timeout_minutes: 5
max_attempts: 3
command: |
pip install -i https://test.pypi.org/simple/ omegaconf_cloud_resolvers[aws,gcp]=="${TARGET_VERSION}"
python -c "import omegaconf_cloud_resolvers; print('Base import: OK')"
python -c "from omegaconf_cloud_resolvers.resolvers.aws import AWSParameterStoreResolver; print('AWS import: OK')"
python -c "from omegaconf_cloud_resolvers.resolvers.gcp import GCPSecretManagerResolver; print('GCP import: OK')"
publish-to-pypi:
name: Publish to PyPI
runs-on: ubuntu-latest
needs:
- test-installation-testpypi

permissions:
id-token: write
contents: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

publish-docs:
name: Publish Docs
uses: ./.github/workflows/release_docs.yml

needs:
- build
- test-installation-testpypi

permissions:
id-token: write
contents: write

with:
ref_tag: "v${{needs.build.outputs.target_version}}"


62 changes: 62 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Test Package
run-name: Test Package 🔧

on:
pull_request:
branches:
- main
- develop

workflow_dispatch:

env:
POETRY_VERSION: "1.8.3"
PCKG_SRC: "omegaconf_cloud_resolvers"


defaults:
run:
shell: bash

jobs:

ci:
name: Continuous Integration
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ "3.9", "3.10", "3.11", "3.12" ]

steps:
- uses: actions/checkout@v4

- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}

- name: Set up python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: poetry install --all-extras

- name: Lint with ruff
run: poetry run ruff check . --exit-non-zero-on-fix --show-fixes

- name: Lint with bandit
run: poetry run bandit -r . -x "./.venv/*,./tests/*,.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg" --quiet

- name: Test with pytest
run: poetry run pytest tests/ --cov=${{env.PCKG_SRC}} --cov-report=xml # store in cov

- name: Archive code coverage html report #
if: ${{ matrix.python-version == '3.9'}}
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: htmlcov

- name: Test build docs
run: poetry run mkdocs build
47 changes: 47 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-toml
always_run: true
- id: check-yaml
always_run: true
- id: end-of-file-fixer
always_run: true
- id: trailing-whitespace
always_run: true

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.5
hooks:
- id: ruff
types_or: [ python, pyi ]
args: [ --fix, --exit-non-zero-on-fix, --show-fixes ]
always_run: true

- id: ruff-format
types_or: [ python, pyi ]
always_run: true

- repo: https://github.com/PyCQA/bandit
rev: 1.7.9
hooks:
- id: bandit
args: ["-r", "-x", "./.venv/*,./tests/*", "targets", "."]

- repo: local
hooks:
- id: pytest-check
name: pytest-check
entry: pytest
language: system
pass_filenames: false
always_run: true
- repo: https://github.com/python-poetry/poetry
rev: 1.8.2
hooks:
- id: poetry-check
always_run: true
- id: poetry-lock
args: ["--no-update"]
always_run: true
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Omegaconf Plugin: Cloud Secrets

This package is a plugin designed to enhance OmegaConf by providing additional custom resolvers to **securely retrieve
sensitive values** that should not be hard-coded in your configuration files.

Currently, there are resolvers for:

* AWS:
* Secrets Manager
* Parameter Store
* Google Cloud Platform (GCP):
* Secret Manager

## Installation

* AWS:
```
pip install omegaconf-cloud-resolvers[aws]
```

* GCP:
```
pip install omegaconf-cloud-resolvers[gcp]
```

## Quickstart

The following is an introductory example using a secret stored in AWS Secrets Manager.

First create a secret in the AWS Secrets Manager. You can use the CLI:

```bash
aws secretsmanager create-secret --name secret_jwt --secret-string 'thiscouldbe.a.jwt'
```

```python
from omegaconf import OmegaConf
from omegaconf_cloud_resolvers import register_custom_resolvers
from omegaconf_cloud_resolvers.resolvers.aws import AWSSecretsManagerResolver

# Option A. Define an env var: `AWS_DEFAULT_PROFILE=<your-aws-profile>`
# If you do, there is no need to pass a Session to the PluginResolver

# Option B. Alternatively you can create a boto3 session and pass it to the `AWSSecretsManagerResolver`
# Check `.aws/config` to see what are your profiles.
# from boto3 import Session
# session = Session(profile_name="<your-aws-profile>")

# Define the custom resolver. The dict key is the name that you will use in your config
resolvers = {
"aws_secretsmanager": AWSSecretsManagerResolver(),
}
# Use CustomResolverInjector to declare the resolver. You cannot inject twice the same key.
register_custom_resolvers(**resolvers)

# The syntax is: <resolver-name>:<secret-name>
conf = OmegaConf.create({"secret": "${aws_secretsmanager:secret_jwt}"})
print("Your secret is:", conf["secret"]) # THAT IS AN ILLUSTRATIVE EXAMPLE, NEVER DO THIS IN PRODUCTION
```

## Roadmap

- [ ] Resolver for Azure Key Vault
- [ ] Support for older version for the AWS Secrets Manager Resolver
- [ ] Examples using AWS services - Lambda
- [ ] Examples using Google Cloud Platform services - Functions


# WARNING

This package is in a very early and experimental stage, use it under your own responsibility.

# Troubleshooting

* NoCredentialsError raised while resolving interpolation: Unable to locate credentials
You might not have configured a default profile or provided with a session to a AWS Resolver.
3 changes: 3 additions & 0 deletions docs/api/register.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Register Custom Resolvers

::: omegaconf_cloud_resolvers
11 changes: 11 additions & 0 deletions docs/api/resolvers/aws/parameterstore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
tags:
- AWS
---

# AWS Parameter Store

::: omegaconf_cloud_resolvers.resolvers.aws.AWSParameterStoreResolver
options:
show_source: true
heading_level: 2
Loading

0 comments on commit 6467d8e

Please sign in to comment.