forked from TerryHowe/ansible-modules-hashivault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashivault_pki_ca.py
executable file
·251 lines (233 loc) · 10.9 KB
/
hashivault_pki_ca.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/usr/bin/python
from ansible.module_utils.hashivault import hashivault_auth_client
from ansible.module_utils.hashivault import hashivault_argspec
from ansible.module_utils.hashivault import hashivault_init
from ansible.module_utils.hashivault import hashiwrapper
ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.1'}
DOCUMENTATION = r'''
---
module: hashivault_pki_ca
version_added: "4.5.0"
short_description: Hashicorp Vault PKI Generate Root/Intermediate
description:
- 'WARNING: if king is `intermediate` and signed CSR have not been inported back to vault, module will regenerate
private key and create new CSR.'
- This module generates a new private key and a CSR for signing or a new self-signed CA certificate and private key.
- If using Vault as a root, and for many other CAs, the various parameters on the final certificate are set at
signing time and may or may not honor the parameters set here.
- This will overwrite any previously existing CA private key.
- This is mostly meant as a helper function, and not all possible parameters that can be set in a CSR are supported.
options:
mount_point:
default: pki
description:
- location where secrets engine is mounted. also known as path
type:
type: str
choices: ["exported", "internal"]
default: internal
description:
- Specifies the type of the root to create, If `exported`, the private key will be returned in the
response;
- If it is `internal` the private key will not be returned and cannot be retrieved later.
common_name:
type: str
description:
- Specifies the requested CN for the certificate. [required]
kind:
type: str
choices: ["root", "intermediate"]
default: root
description:
- Specifies the kind of CA certificate.
state:
type: str
choices: ["present", "absent"]
default: present
description:
- Do you want for this config to be present or absent
config:
description:
- Collection of properties for pki generate root. Ref.
U(https://www.vaultproject.io/api-docs/secret/pki#generate-root)
type: dict
suboptions:
alt_names:
type: str
description:
- Specifies the requested Subject Alternative Names, in a comma-delimited list.
- These can be host names or email addresses; they will be parsed into their respective fields.
ip_sans:
type: str
description:
- Specifies the requested IP Subject Alternative Names, in a comma-delimited list.
uri_sans:
type: str
description:
- Specifies the requested URI Subject Alternative Names, in a comma-delimited list.
other_sans:
type: str
description:
- Specifies custom OID/UTF8-string SANs.
- These must match values specified on the role in `allowed_other_sans` (see role creation for
allowed_other_sans globbing rules).
- The format is the same as OpenSSL `<oid>;<type>:<value>` where the only current valid type is
`UTF8`
- This can be a comma-delimited list or a JSON string slice.
ttl:
type: str
description:
- Specifies the requested Time To Live (after which the certificate will be expired).
- This cannot be larger than the engine's max (or, if not set, the system max).
format:
type: str
default: "pem"
choice: ["pem", "der", "pem_bundle"]
description:
- Specifies the format for returned data.
- If `der`, the output is base64 encoded.
- If `pem_bundle`, the `certificate` field will contain the private key (if exported) and
certificate, concatenated;
- if the issuing CA is not a Vault-derived self-signed root, this will be included as well.
private_key_format:
type: str
default: der
description:
- Specifies the format for marshaling the private key.
- Defaults to `der` which will return either base64-encoded DER or PEM-encoded DER, depending on
the value of `format`.
- The other option is `pkcs8` which will return the key marshalled as PEM-encoded PKCS8
key_type:
type: str
default: "rsa"
choice: ["rsa", "ec"]
description:
- Specifies the desired key type.
key_bits:
type: int
default: 2048
description:
- Specifies the number of bits to use
max_path_length:
type: int
default: -1
description:
- Specifies the maximum path length to encode in the generated certificate.
- A limit of `-1` means no limit.
- Unless the signing certificate has a maximum path length set, in which case the path length is set
to one less than that of the signing certificate.
- A limit of `0` means a literal path length of zero.
exclude_cn_from_sans:
type: bool
default: false
description:
- If set, the given `common_name` will not be included in DNS or Email Subject Alternate Names (as
appropriate).
- Useful if the CN is not a hostname or email address, but is instead some human-readable
identifier.
permitted_dns_domains:
type: list
description:
- A list containing DNS domains for which certificates are allowed to be issued or signed by this CA
certificate.
- Note that subdomains are allowed, as per U(https://tools.ietf.org/html/rfc5280#section-4.2.1.10).
ou:
type: list
description:
- Specifies the `OU` (OrganizationalUnit) values in the subject field of the resulting certificate.
organization:
type: list
description:
- Specifies the `O` (Organization) values in the subject field of the resulting certificate.
country:
type: list
description:
- Specifies the `C` (Country) values in the subject field of the resulting certificate.
locality:
type: list
description:
- Specifies the `L` (Locality) values in the subject field of the resulting certificate.
province:
type: list
description:
- Specifies the `ST` (Province) values in the subject field of the resulting certificate.
street_address:
type: list
description:
- Specifies the Street Address values in the subject field of the resulting certificate.
postal_code:
type: list
description:
- Specifies the Postal Code values in the subject field of the resulting certificate.
serial_number:
type: string
description:
- Specifies the Serial Number, if any.
- Otherwise Vault will generate a random serial for you.
- If you want more than one, specify alternative names in the alt_names map using OID 2.5.4.5.
extends_documentation_fragment:
- hashivault
'''
EXAMPLES = r'''
---
- hosts: localhost
tasks:
- name: Delete Root
hashivault_pki_ca:
common_name: my common name
'''
def main():
argspec = hashivault_argspec()
argspec['common_name'] = dict(required=True, type='str')
argspec['mount_point'] = dict(required=False, type='str', default='pki')
argspec['state'] = dict(required=False, type='str', default='present', choices=['present', 'absent'])
argspec['kind'] = dict(required=False, type='str', default='root', choices=['root', 'intermediate'])
argspec['type'] = dict(required=False, type='str', default='internal', choices=['internal', 'exported'])
argspec['config'] = dict(required=False, type='dict', default={})
supports_check_mode = True
module = hashivault_init(argspec, supports_check_mode)
result = hashivault_pki_ca(module)
if result.get('failed'):
module.fail_json(**result)
else:
module.exit_json(**result)
@hashiwrapper
def hashivault_pki_ca(module):
params = module.params
client = hashivault_auth_client(params)
common_name = params.get('common_name')
mount_point = params.get('mount_point').strip('/')
state = params.get('state')
kind = params.get('kind')
type = params.get('type')
config = params.get('config')
exists = False
changed = False
# check if CA certificate exists
if client.secrets.pki.read_ca_certificate(mount_point=mount_point):
# WARNING: if king is `intermediate` and signed CSR have not been inported back to vault, module will regenerate
# private key and create new CSR. This check will not see that CA exist although private key is generate, and
# CSR might be in proccess to be signed.
exists = True
if (exists and state == 'absent') or (not exists and state == 'present'):
changed = True
result = {"changed": changed, "rc": 0}
# make the changes!
if changed and state == 'present' and not module.check_mode:
if kind == 'root':
resp = client.secrets.pki.generate_root(type=type, common_name=common_name, extra_params=config,
mount_point=mount_point)
result['data'] = resp.get('data')
if resp.get('warnings'):
result['warnings'] = resp.get('warnings')
elif kind == 'intermediate':
resp = client.secrets.pki.generate_intermediate(type=type, common_name=common_name, extra_params=config,
mount_point=mount_point)
result['data'] = resp.get('data')
if resp.get('warnings'):
result['warnings'] = resp.get('warnings')
elif changed and state == 'absent' and not module.check_mode:
client.secrets.pki.delete_root(mount_point=mount_point)
return result
if __name__ == '__main__':
main()