Az mod keyvault ops (#33606)

* keyvault_operations module init + template

* Created KeyVault Secrets Module. No Tests

* Passing 2.7/3.x sanity tests

* added intergration tests for keyvault secrets noop

* integration test pass/need keyvault module

* Added az env cleanup to intergration tests

* Updated auth to 0.3.6 ver

* fixed typo in integration tests

* Added check_mode

* Added tags

* Updated tags test, sanity + integration passed

* checked mode

* updated tests

* fixing sanity

* fix copyright
This commit is contained in:
Ian Philpot 2018-02-06 23:40:15 -05:00 committed by Matt Davis
parent 11382fac7a
commit e62c1cd050
4 changed files with 268 additions and 0 deletions

View file

@ -0,0 +1,199 @@
#!/usr/bin/python
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: azure_rm_keyvaultsecret
version_added: 2.5
short_description: Use Azure KeyVault Secrets.
description:
- Create or delete a secret within a given keyvault. By using Key Vault, you can encrypt
keys and secrets (such as authentication keys, storage account keys, data encryption keys, .PFX files, and passwords).
options:
keyvault_uri:
description:
- URI of the keyvault endpoint.
required: true
secret_name:
description:
- Name of the keyvault secret.
required: true
secret_value:
description:
- Secret to be secured by keyvault.
required: false
aliases:
- secret
state:
description:
- Assert the state of the subnet. Use 'present' to create or update a secret and
'absent' to delete a secret .
required: false
default: present
choices:
- absent
- present
extends_documentation_fragment:
- azure
- azure_tags
author:
- "Ian Philpot (@tripdubroot)"
'''
EXAMPLES = '''
- name: Create a secret
azure_rm_keyvaultsecret:
secret_name: MySecret
secret_value: My_Pass_Sec
keyvault_uri: https://contoso.vault.azure.net/
tags:
testing: testing
delete: never
- name: Delete a secret
azure_rm_keyvaultsecret:
secret_name: MySecret
keyvault_uri: https://contoso.vault.azure.net/
state: absent
'''
RETURN = '''
state:
description: Current state of the secret.
returned: success
type: complex
contains:
secret_id:
description: Secret resource path.
type: str
example: https://contoso.vault.azure.net/secrets/hello/e924f053839f4431b35bc54393f98423
'''
from ansible.module_utils.azure_rm_common import AzureRMModuleBase
try:
from azure.keyvault import KeyVaultClient, KeyVaultAuthentication, KeyVaultId
from azure.common.credentials import ServicePrincipalCredentials
from azure.keyvault.models.key_vault_error import KeyVaultErrorException
except ImportError:
# This is handled in azure_rm_common
pass
class AzureRMKeyVaultSecret(AzureRMModuleBase):
''' Module that creates or deletes secrets in Azure KeyVault '''
def __init__(self):
self.module_arg_spec = dict(
secret_name=dict(type='str', required=True),
secret_value=dict(type='str', aliases=['secret'], no_log=True),
keyvault_uri=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent'])
)
required_if = [
('state', 'present', ['secret_value'])
]
self.results = dict(
changed=False,
state=dict()
)
self.secret_name = None
self.secret_value = None
self.keyvault_uri = None
self.state = None
self.data_creds = None
self.client = None
self.tags = None
super(AzureRMKeyVaultSecret, self).__init__(self.module_arg_spec,
supports_check_mode=True,
required_if=required_if,
supports_tags=True)
def exec_module(self, **kwargs):
for key in list(self.module_arg_spec.keys()) + ['tags']:
setattr(self, key, kwargs[key])
# Create KeyVault Client using KeyVault auth class and auth_callback
self.client = KeyVaultClient(self.azure_credentials)
results = dict()
changed = False
try:
results['secret_id'] = self.get_secret(self.secret_name)
# Secret exists and will be deleted
if self.state == 'absent':
changed = True
except KeyVaultErrorException:
# Secret doesn't exist
if self.state == 'present':
changed = True
self.results['changed'] = changed
self.results['state'] = results
if not self.check_mode:
# Create secret
if self.state == 'present' and changed:
results['secret_id'] = self.create_secret(self.secret_name, self.secret_value, self.tags)
self.results['state'] = results
self.results['state']['status'] = 'Created'
# Delete secret
elif self.state == 'absent' and changed:
results['secret_id'] = self.delete_secret(self.secret_name)
self.results['state'] = results
self.results['state']['status'] = 'Deleted'
else:
if self.state == 'present' and changed:
self.results['state']['status'] = 'Created'
elif self.state == 'absent' and changed:
self.results['state']['status'] = 'Deleted'
return self.results
def get_secret(self, name, version=''):
''' Gets an existing secret '''
secret_bundle = self.client.get_secret(self.keyvault_uri, name, version)
if secret_bundle:
secret_id = KeyVaultId.parse_secret_id(secret_bundle.id)
return secret_id.id
def create_secret(self, name, secret, tags):
''' Creates a secret '''
secret_bundle = self.client.set_secret(self.keyvault_uri, name, secret, tags)
secret_id = KeyVaultId.parse_secret_id(secret_bundle.id)
return secret_id.id
def delete_secret(self, name):
''' Deletes a secret '''
deleted_secret = self.client.delete_secret(self.keyvault_uri, name)
secret_id = KeyVaultId.parse_secret_id(deleted_secret.id)
return secret_id.id
def main():
AzureRMKeyVaultSecret()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,3 @@
cloud/azure
posix/ci/cloud/azure
destructive

View file

@ -0,0 +1,2 @@
dependencies:
- setup_azure

View file

@ -0,0 +1,64 @@
- name: Prepare random number
set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
run_once: yes
- name: Create instance of Key Vault
azure_rm_keyvault:
resource_group: "{{ resource_group }}"
vault_name: "vault{{ rpfx }}"
enabled_for_deployment: yes
vault_tenant: "{{ azure_tenant }}"
sku:
name: standard
family: A
access_policies:
- tenant_id: "{{ azure_tenant }}"
object_id: 97567bfa-cf13-4217-8fa3-cc56bc1867fe
keys:
- get
- list
- update
- create
- import
- delete
- recover
- backup
- restore
secrets:
- get
- list
- set
- delete
- recover
- backup
- restore
register: output
- name: create a kevyault secret
block:
- azure_rm_keyvaultsecret:
keyvault_uri: https://vault{{ rpfx }}.vault.azure.net
secret_name: testsecret
secret_value: 'mysecret'
tags:
testing: test
delete: on-exit
register: output
- assert:
that: output.changed
rescue:
- azure_rm_keyvaultsecret:
keyvault_uri: https://vault{{ rpfx }}.vault.azure.net
state: absent
secret_name: testsecret
- name: delete a kevyault secret
azure_rm_keyvaultsecret:
keyvault_uri: https://vault{{ rpfx }}.vault.azure.net
state: absent
secret_name: testsecret
register: output
- assert:
that: output.changed