Skip to content

Commit

Permalink
Creates ROCK for Vault
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume committed Sep 25, 2023
1 parent 5f5fe88 commit 92be4d5
Show file tree
Hide file tree
Showing 18 changed files with 509 additions and 1 deletion.
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a bug report to help us improve
title: ""
labels: ["bug"]
assignees: ''
---

#### Describe the bug
<!-- A clear and concise description of what the bug is. -->

#### To Reproduce
<!-- Steps that can be taken to reproduce the behaviour -->

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. -->

#### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->

#### Logs
<!-- If applicable, add logs to help explain your problem. -->

#### Environment

- ROCK version: <!-- e.g. 1.2 -->
- Juju version (output from `juju --version`):
- Cloud Environment: <!-- e.g. GKE -->
- Kubernetes version (output from `kubectl version --short`):

#### Additional context

<!-- Add any other context about the problem here. -->
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Description

Please include a summary of the change. Please also include relevant motivation and context. List any dependencies that are required for this change.

## Checklist

- [ ] I have performed a self-review of my own code.
- [ ] I have made corresponding changes to the documentation.
- [ ] I have added tests that validate the behaviour of the software.
- [ ] I validated that new and existing tests pass locally with my changes.
- [ ] Any dependent changes have been merged and published in downstream modules.
17 changes: 17 additions & 0 deletions .github/workflows/build-rock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build ROCK

on:
workflow_call:

jobs:
build-rock:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: canonical/craft-actions/rockcraft-pack@main
id: rockcraft
- uses: actions/upload-artifact@v3
with:
name: rock
path: ${{ steps.rockcraft.outputs.rock }}
32 changes: 32 additions & 0 deletions .github/workflows/integration-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Integration tests

on:
workflow_call:

jobs:
integration-tests:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

- uses: canonical/craft-actions/rockcraft-pack@main
id: rockcraft

- name: Install Skopeo
run: |
sudo snap install skopeo --edge --devmode
- name: Import the image to Docker registry
run: |
sudo skopeo --insecure-policy copy oci-archive:${{ steps.rockcraft.outputs.rock }} docker-daemon:vault:1.14.3
- name: Integration tests
id: test_image
run: cd tests && tox -e integration

- uses: actions/upload-artifact@v3
if: steps.test_image.outcome == 'success'
with:
name: rock
path: ${{ steps.rockcraft.outputs.rock }}
24 changes: 24 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Main

on:
push:
schedule:
- cron: '0 8 * * 2'

jobs:

build:
uses: ./.github/workflows/build-rock.yaml

scan:
needs: build-rock
uses: ./.github/workflows/scan-rock.yaml

integration-tests:
needs: build
uses: ./.github/workflows/integration_tests.yaml

publish:
if: github.ref_name == 'main'
needs: [scan-rock, integration-tests]
uses: ./.github/workflows/publish-rock.yaml
38 changes: 38 additions & 0 deletions .github/workflows/publish-rock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Publish ROCK

on:
workflow_call:

jobs:

publish-rock:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install skopeo
run: |
sudo snap install --devmode --channel edge skopeo
- uses: actions/download-artifact@v3
with:
name: rock

- name: Import and push to github package
run: |
image_name="$(yq '.name' rockcraft.yaml)"
version="$(yq '.version' rockcraft.yaml)"
rock_file=$(ls *.rock | tail -n 1)
sudo skopeo \
--insecure-policy \
copy \
oci-archive:"${rock_file}" \
docker-daemon:"ghcr.io/canonical/${image_name}:${version}"
docker push ghcr.io/canonical/${image_name}:${version}
49 changes: 49 additions & 0 deletions .github/workflows/scan-rock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Scan

on:
workflow_call:

jobs:

scan:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install skopeo
run: |
sudo snap install --devmode --channel edge skopeo
- name: Install yq
run: |
sudo snap install yq
- uses: actions/download-artifact@v3
with:
name: rock

- name: Import
run: |
image_name="$(yq '.name' rockcraft.yaml)"
echo "image_name=${image_name}" >> $GITHUB_ENV
version="$(yq '.version' rockcraft.yaml)"
echo "version=${version}" >> $GITHUB_ENV
rock_file=$(ls *.rock | tail -n 1)
sudo skopeo \
--insecure-policy \
copy \
oci-archive:"${rock_file}" \
docker-daemon:"ghcr.io/canonical/${image_name}:${version}"
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: "ghcr.io/canonical/${{env.image_name}}:${{env.version}}"
format: 'sarif'
output: 'trivy-results.sarif'

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @canonical/telco
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Contributing

## Build and deploy

```bash
rockcraft pack -v
sudo skopeo --insecure-policy copy oci-archive:vault_1.14.3_amd64.rock docker-daemon:vault:1.14.3
docker run sdcore-amf:1.3
```
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
# vault-rock
# vault-rock

A ROCK image for Vault.

## Usage

```console
docker pull ghcr.io/canonical/vault:1.14.3
docker run -it ghcr.io/canonical/vault:1.14.3
```
13 changes: 13 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"platformAutomerge": true
}
20 changes: 20 additions & 0 deletions rockcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: vault
base: ubuntu:22.04
build-base: ubuntu:22.04
version: "1.14.3"
summary: A ROCK container image for Vault
description: |
A ROCK container image for Vault, a tool for secrets management, encryption as a service, and privileged access management.
license: Apache-2.0
platforms:
amd64:

parts:

vault:
plugin: go
source: https://github.com/hashicorp/vault.git
source-tag: v1.14.3
source-type: git
build-snaps:
- go/1.20/stable
13 changes: 13 additions & 0 deletions tests/config/config.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ui = true
cluster_addr = "https://127.0.0.1:8201"
api_addr = "https://127.0.0.1:8200"
disable_mlock = true

storage "file" {
path = "/vault/data"
}

listener "tcp" {
address = "[::]:8200"
tls_disable = true
}
52 changes: 52 additions & 0 deletions tests/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[tool.coverage.run]
branch = true

[tool.coverage.report]
show_missing = true

[tool.black]
line-length = 99
target-version = ["py38"]

[tool.isort]
profile = "black"

[tool.flake8]
max-line-length = 99
max-doc-length = 99
max-complexity = 10
exclude = [".git", "__pycache__", ".tox", "build", "dist", "*.egg_info", "venv"]
select = ["E", "W", "F", "C", "N", "R", "D", "H"]
per-file-ignores = ["tests/*:D100,D101,D102,D103,D107"]
docstring-convention = "google"
copyright-check = "True"
copyright-author = "Canonical Ltd."
copyright-regexp = "Copyright\\s\\d{4}([-,]\\d{4})*\\s+%(author)s"

[tool.mypy]
pretty = true
python_version = 3.8
mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/lib:$MYPY_CONFIG_FILE_DIR/tests/unit"
follow_imports = "normal"
warn_redundant_casts = true
warn_unused_ignores = true
warn_unused_configs = true
show_traceback = true
show_error_codes = true
namespace_packages = true
explicit_package_bases = true
check_untyped_defs = true
allow_redefinition = true

# Ignore libraries that do not have type hint nor stubs
[[tool.mypy.overrides]]
module = ["ops.*", "kubernetes.*", "flatten_json.*", "git.*"]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = ["charms.*"]
follow_imports = "silent"

[tool.pytest.ini_options]
minversion = "6.0"
log_cli_level = "INFO"
2 changes: 2 additions & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hvac
requests
53 changes: 53 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.

"""Integration tests to validate that the Vault ROCK works as expected."""

import logging
import subprocess
import time
import unittest

from vault import Vault

logger = logging.getLogger(__name__)


def wait_for_vault_to_be_available(timeout: int = 30):
"""Wait for Vault to be available."""
initial_time = time.time()
vault = Vault("http://localhost:8200")
while time.time() - initial_time < timeout:
if vault.is_api_available():
logger.info("Vault API is available")
return True
else:
time.sleep(1)
raise TimeoutError("Vault is not available after {} seconds".format(timeout))


class TestVaultRock(unittest.TestCase):
"""Integration tests to validate that the Vault ROCK works as expected."""

def setUp(self):
"""Starts a Vault container."""
subprocess.check_call(
"docker run -d -p 8200:8200 -v ${PWD}/config:/vault/config --entrypoint /bin/bash vault:1.14.3 -c 'vault server -config=/vault/config/config.hcl'", # noqa: E501
shell=True,
)

def test_given_vault_container_running_when_initialize_then_properly_responds_to_commands(
self,
):
"""Runs basic CLI commands to initialize and unseal Vault."""
vault = Vault("http://localhost:8200")

wait_for_vault_to_be_available()

root_token, unseal_keys = vault.initialize()

vault.unseal(unseal_keys)

self.assertEqual(vault.is_initialized(), True)
self.assertEqual(vault.is_sealed(), False)
Loading

0 comments on commit 92be4d5

Please sign in to comment.