1
1
mirror of https://gitlab.archlinux.org/archlinux/infrastructure.git synced 2024-11-15 17:13:09 +01:00

misc: Replace vault-reading shell scripts with python

This commit is contained in:
Jan Alexander Steffens (heftig) 2019-06-13 23:40:33 +02:00
parent 4130787f62
commit 0abfe90ea5
No known key found for this signature in database
GPG Key ID: A5E9288C4FA415FA
7 changed files with 98 additions and 26 deletions

@ -19,7 +19,7 @@ run the provisioning script: `ansible-playbook playbooks/tasks/install-arch.yml
The provisioning script configures a sane basic systemd with sshd. By design, it is NOT idempotent.
After the provisioning script has run, it is safe to reboot.
Once in the new system, run the regular playbook: `HCLOUD_TOKEN=$(misc/get_hcloud_api_key_ansible.sh) ansible-playbook playbooks/$hostname.yml`.
Once in the new system, run the regular playbook: `HCLOUD_TOKEN=$(misc/get_key.py misc/vault_hetzner.yml hetzner_cloud_api_key) ansible-playbook playbooks/$hostname.yml`.
This playbook is the one regularity used for administrating the server and is entirely idempotent.
#### Note about Ansible dynamic inventories
@ -44,7 +44,7 @@ Note that some roles already run this automatically.
We use packer to build snapshots on hcloud to use as server base images.
In order to use this, you need to install packer and then run
packer build -var $(./misc/get_hetzner_cloud_api_key_packer.sh) packer/archlinux.json
packer build -var $(misc/get_key.py misc/vault_hetzner.yml hetzner_cloud_api_key env) packer/archlinux.json
This will take some time after which a new snapshot will have been created on the primary hcloud archlinux project.
@ -53,7 +53,7 @@ This will take some time after which a new snapshot will have been created on th
We use terraform to provision a part of the infrastructure on hcloud.
The very first time you run terraform on your system, you'll have to init it:
terraform init -backend-config="conn_str=postgres://terraform:$(ansible-vault view group_vars/all/vault_terraform.yml | grep vault_terraform_db_password | cut -f2 -d'"')@state.cloud.archlinux.org"
terraform init -backend-config="conn_str=postgres://terraform:$(misc/get_key.py group_vars/all/vault_terraform.yml vault_terraform_db_password)@state.cloud.archlinux.org"
After making changes to the infrastructure in `archlinux.fg`, run

@ -3,7 +3,7 @@ terraform {
}
data "external" "hetzner_cloud_api_key" {
program = ["bash", "${path.module}/misc/get_hetzner_cloud_api_key_terraform.sh"]
program = ["${path.module}/misc/get_key.py", "misc/vault_hetzner.yml", "hetzner_cloud_api_key", "json"]
}
# Find the id using `hcloud image list`

@ -9,10 +9,7 @@ import sys
from hcloud import Client
from ansible import constants as C
from ansible.parsing.vault import VaultLib
from ansible.cli import CLI
from ansible.parsing.dataloader import DataLoader
from misc.get_key import load_vault
def parse_args():
@ -36,14 +33,7 @@ def get_host_details(client, host):
def main():
args = parse_args()
loader = DataLoader()
vault_secret = CLI.setup_vault_secrets(
loader=loader,
vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST
)
vault = VaultLib(vault_secret)
decrypted = vault.decrypt(open('misc/vault_hetzner.yml').read())
loaded = yaml.load(decrypted)
loaded = load_vault('misc/vault_hetzner.yml')
client = Client(token=loaded["hetzner_cloud_api_key"])
if args.list:

@ -1,4 +1,2 @@
#!/bin/bash
exec gpg --batch --decrypt --quiet $(dirname $0)/vault-password.gpg
#!/bin/sh
exec gpg --batch --decrypt --quiet "$(dirname $0)/vault-password.gpg"

@ -1,3 +0,0 @@
#!/bin/bash
echo "hetzner_cloud_api_key=$(ansible-vault view misc/vault_hetzner.yml | grep hetzner_cloud_api_key | cut -f2 -d' ')"

@ -1,3 +0,0 @@
#!/bin/bash
echo "{\"hetzner_cloud_api_key\": \"$(ansible-vault view misc/vault_hetzner.yml | grep hetzner_cloud_api_key | cut -f2 -d' ')\"}"

90
misc/get_key.py Executable file

@ -0,0 +1,90 @@
#!/usr/bin/python3
from contextlib import contextmanager
from enum import Enum
from pathlib import Path
import argparse
import json
import os
import sys
import yaml
@contextmanager
def chdir(path):
oldcwd = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(oldcwd)
root = Path(__file__).resolve().parents[1]
with chdir(root):
from ansible.cli import CLI
from ansible.constants import DEFAULT_VAULT_IDENTITY_LIST
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.vault import VaultLib
data_loader = DataLoader()
data_loader.set_basedir(root)
vault_lib = VaultLib(
CLI.setup_vault_secrets(
data_loader, DEFAULT_VAULT_IDENTITY_LIST, auto_prompt=False
)
)
def load_vault(path):
with chdir(root):
return yaml.load(
vault_lib.decrypt(Path(path).read_text()), Loader=yaml.SafeLoader
)
class Output(Enum):
BARE = "bare"
ENV = "env"
JSON = "json"
def __str__(self):
return self.value
def parse_args():
parser = argparse.ArgumentParser(
description="Retrieve a password from an Ansible vault."
)
parser.add_argument(dest="vault", type=Path, help="vault to open")
parser.add_argument(dest="key", help="key to extract")
parser.add_argument(
dest="output",
nargs="?",
type=Output,
choices=Output,
default=Output.BARE,
help="style of output",
)
return parser.parse_args()
def main():
args = parse_args()
value = load_vault(args.vault)[args.key]
if args.output == Output.BARE:
print(value)
elif args.output == Output.ENV:
print(f"{args.key}={value}")
elif args.output == Output.JSON:
json.dump({args.key: value}, sys.stdout)
print()
else:
assert False
if __name__ == "__main__":
main()