Skip to content

Commit

Permalink
Update readme to include generate secret action.
Browse files Browse the repository at this point in the history
  • Loading branch information
nzlosh committed Jun 7, 2022
1 parent f644de0 commit 06bfb51
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 48 deletions.
9 changes: 8 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# Change Log

## 2.0.0

- Add action to generate secrets.
- Add profile support to pack to define multiple Vault end-points.
- Updated README with full list of available actions.
- Fixes TLS support for server and client certificates.

## 1.0.0

* Drop Python 2.7 support
- Drop Python 2.7 support

## 0.6.0

Expand Down
9 changes: 0 additions & 9 deletions README.jinja
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
# {{ pack["pack.yaml"].name }} integration pack
_{{ pack["pack.yaml"].description }}_

{{ pack["pack.yaml"].author }} <{{ pack["pack.yaml"].email }}>

### Contributors
{% for contributor in pack["pack.yaml"].contributors -%}
- {{ contributor }}
{% endfor %}

{% if pack and pack["config.schema.yaml"] -%}
## Configuration

Expand Down Expand Up @@ -81,8 +74,6 @@ The following string sets are available
```0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c```
- alphanumeric
```abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789```
- alphanumeric
```abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789```

### Update tactic

Expand Down
65 changes: 56 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
# vault integration pack

> HashiCorp Vault
steve.neuharth <[email protected]>
### Contributors
- Andy Moore <[email protected]>
- Jacob Floyd <[email protected]>

_HashiCorp Vault_

## Configuration

Expand Down Expand Up @@ -36,6 +29,17 @@ _Delete value from Vault server_
| Parameter | Type | Required | Secret | Description |
|---|---|---|---|---|
| `path` | string | True | default | _Path to delete from Vault_ |
### generate_secret
_Generate a secret and write it to vault._
| Parameter | Type | Required | Secret | Description |
|---|---|---|---|---|
| `profile_name` | string | False | default | _The profile to use to run this action._ |
| `mount_point` | string | False | default | _Vault moint point in the URL_ |
| `path` | string | True | default | _Path to the secrets_ |
| `key_name` | string | True | default | _Name of the key to write the secret._ |
| `update_tactic` | string | False | default | _The logic to use when writing secret to Vault. See readme for details._ |
| `string_set` | string | default | default | _Unavailable_ |
| `secret_length` | integer | default | default | _The number of characters to use in the secret._ |
### read
_Read value from Vault server_
| Parameter | Type | Required | Secret | Description |
Expand All @@ -49,7 +53,7 @@ _Create a new Token_
| Items are of type | ||||
| `policies` | array | False | default | _List of policy names to associate with this token._ |
| `meta` | string | False | default | _Metadata to associate with the token. This metadata will show in the audit log when the token is used._ |
| `no_parent` | boolean | False | default | __ |
| `no_parent` | boolean | False | default | _Unavailable_ |
| `display_name` | string | False | default | _Name to associate with this token. This is a non-sensitive value that can be used to help identify created secrets (e.g. prefixes)._ |
| `num_uses` | string | False | default | _Number of times this token can be used. After the last use, the token is automatically revoked._ |
| `no_default_policy` | boolean | False | default | _Detach the 'default' policy from the policy set for this token._ |
Expand Down Expand Up @@ -88,18 +92,61 @@ _Create a new Vault policy_
| `rules` | string | True | default | _Policy rules_ |
### list_policies
_List Policies from Vault server_
### write_secret
_Write a secret to Vault._
| Parameter | Type | Required | Secret | Description |
|---|---|---|---|---|
| `profile_name` | string | False | default | _The profile to use to run this action._ |
| `mount_point` | string | False | default | _Vault moint point in the URL_ |
| `path` | string | True | default | _Path to the secrets_ |
| `key_name` | string | True | default | _Name of the key to write the secret._ |
| `secret` | string | True | True | _Secret contents to be written._ |
| `decode_json` | boolean | False | default | _Secret is formatted as a json and should be decode to be sent to Vault_ |
| `update_tactic` | string | False | default | _The logic to use when writing secret to Vault. See readme for details._ |
### is_initialized
_Read initialization status from Vault server_




### generate secret

This action is written to pre-populate keys with a random secret.

The following string sets are available

- ascii_letters
```abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ```
- ascii_lowercase
```abcdefghijklmnopqrstuvwxyz```
- ascii_uppercase
```ABCDEFGHIJKLMNOPQRSTUVWXYZ```
- digits
```0123456789```
- punctuation
```!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~```
- printable
```0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c```
- alphanumeric
```abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789```

### Update tactic

The update tactic allows control of how the action will update existing secrets. The currently supported
tactics are:
- `update`: Overwrite an existing secret.
- `abstain`: Do not overwrite an existing secret.

## Sensors

There are no sensors available for this pack.


## Authentication methods

Authentication methods are defined per profile and are mutally exclusive. Only configure the
method that should be used.

### Supported
- approle
- token
Expand Down
17 changes: 11 additions & 6 deletions actions/lib/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@


class VaultBaseAction(Action):
"""
Base Action includes st2 profile and vault client functions
for child classes.
"""
def __init__(self, config):
super().__init__(config)
self.config = config
Expand All @@ -17,9 +21,9 @@ def run(self, profile_name=None):
if profile_name is None:
raise Exception("No default profile found, check the pack configuration.")

for p in self.config.get("profiles", []):
if profile_name == p["name"]:
self._configure_client(p)
for profile in self.config.get("profiles", []):
if profile_name == profile["name"]:
self._configure_client(profile)
break
else:
raise Exception(
Expand All @@ -44,9 +48,10 @@ def _configure_client(self, profile):
cert = (profile.get("client_cert_path"), profile.get("client_key_path"))
if bool(cert[0]) ^ bool(cert[1]):
raise Exception(
f"Client-side TLS requires the certificate and key, check the pack configuration"
"Client-side TLS requires the certificate and key, check the pack configuration."
)
elif cert[0] and cert[1]:

if cert[0] and cert[1]:
client_kwargs["cert"] = cert

# Create a connection to vault
Expand All @@ -62,7 +67,7 @@ def _configure_client(self, profile):

if self.vault.token is None:
raise Exception(
f"Failed to set a valid token for the client, check the pack configuration."
"Failed to set a valid token for the client, check the pack configuration."
)

def _auth_token(self, profile):
Expand Down
6 changes: 2 additions & 4 deletions actions/read_kv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ def run(self, path, kv_version, mount_point, version, profile=None):
value = None

if kv_version == 1:
value = self.vault.secrets.kv.v1.read_secret(
path=path, mount_point=mount_point
)
value = self.vault.secrets.kv.v1.read_secret(path=path, mount_point=mount_point)
elif kv_version == 2:
value = self.vault.secrets.kv.v2.read_secret_version(
path=path, mount_point=mount_point, version=version
)

if value:
return value['data']
return value["data"]
else:
raise KeyError("Key was not found in Vault")
35 changes: 17 additions & 18 deletions actions/write_secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ def generate_secret(string_set="ascii_letters", length=8):


def read_secret(client, mount_point, path):
"""
Read secret from Vault and return it.
"""
try:
tmp = client.secrets.kv.v1.read_secret(path=path, mount_point=mount_point)
res = tmp.get("data", {})
except hvac.exceptions.InvalidPath as e:
except hvac.exceptions.InvalidPath:
res = {}
return res

Expand Down Expand Up @@ -89,29 +92,25 @@ def run(
" secret_length parameters to generate a secret."
)

if update_tactic == "abstain":
r = read_secret(self.vault, mount_point, path)
if key_name in r.keys():
write_ok = False
msg = f"Abstained from updating existing secret {mount_point}/{path}"
else:
write_ok = True
res = r
elif update_tactic == "update":
write_ok = True
res = read_secret(self.vault, mount_point, path)
else:
if update_tactic not in ["abstain", "update"]:
raise ValueError(f"Unknown update tactic '{update_tactic}'")

current_secret = read_secret(self.vault, mount_point, path)
if update_tactic == "abstain" and key_name in current_secret.keys():
write_ok = False
msg = f"Abstained from updating existing secret {mount_point}/{path}"
else:
write_ok = True

if write_ok:
if decode_json:
secret = json.loads(secret)
res.update({key_name: secret})
r = write_secret(self.vault, mount_point, path, res)
if not r.ok:
current_secret.update({key_name: secret})
r = write_secret(self.vault, mount_point, path, current_secret)
if r.ok:
msg = f"Wrote secret {key_name} to {mount_point}/{path}"
else:
write_ok = r.ok
msg = r.reason
else:
msg = f"Written secret {key_name} to {mount_point}/{path}"

return (True, {"updated": write_ok, "message": msg})
2 changes: 1 addition & 1 deletion pack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
ref: vault
name: vault
description: HashiCorp Vault
version: 1.0.0
version: 2.0.0
python_versions:
- "3"
author: steve.neuharth
Expand Down

0 comments on commit 06bfb51

Please sign in to comment.