Adds params to the profile-client-ssl module (#44656)

This patch adds new parameters to the client ssl module.
pull/44665/head
Tim Rupp 6 years ago committed by GitHub
parent 990e95eb57
commit 79153b95e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -63,9 +63,7 @@ class F5Client(F5BaseClient):
class F5RestClient(F5BaseClient): class F5RestClient(F5BaseClient):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
params = kwargs.get('module').params super(F5RestClient, self).__init__(*args, **kwargs)
module = kwargs.pop('module')
super(F5RestClient, self).__init__(module=module, **params)
self.provider = self.merge_provider_params() self.provider = self.merge_provider_params()
@property @property
@ -89,7 +87,7 @@ class F5RestClient(F5BaseClient):
if response.status not in [200]: if response.status not in [200]:
raise F5ModuleError('Status code: {0}. Unexpected Error: {1} for uri: {2}\nText: {3}'.format( raise F5ModuleError('Status code: {0}. Unexpected Error: {1} for uri: {2}\nText: {3}'.format(
response.status, response.reason, response.url, response._content response.status, response.reason, response.url, response.content
)) ))
session.headers['X-F5-Auth-Token'] = response.json()['token']['token'] session.headers['X-F5-Auth-Token'] = response.json()['token']['token']

@ -54,6 +54,7 @@ f5_provider_spec = {
default='rest' default='rest'
), ),
'timeout': dict(type='int'), 'timeout': dict(type='int'),
'auth_provider': dict()
} }
f5_argument_spec = { f5_argument_spec = {
@ -88,6 +89,9 @@ f5_top_spec = {
'transport': dict( 'transport': dict(
removed_in_version=2.9, removed_in_version=2.9,
choices=['cli', 'rest'] choices=['cli', 'rest']
),
'auth_provider': dict(
default=None
) )
} }
f5_argument_spec.update(f5_top_spec) f5_argument_spec.update(f5_top_spec)
@ -105,6 +109,13 @@ def load_params(params):
params[key] = value params[key] = value
def is_empty_list(seq):
if len(seq) == 1:
if seq[0] == '' or seq[0] == 'none':
return True
return False
# Fully Qualified name (with the partition) # Fully Qualified name (with the partition)
def fqdn_name(partition, value): def fqdn_name(partition, value):
"""This method is not used """This method is not used
@ -204,7 +215,9 @@ def flatten_boolean(value):
return 'no' return 'no'
def cleanup_tokens(client): def cleanup_tokens(client=None):
if client is None:
return
try: try:
# isinstance cannot be used here because to import it creates a # isinstance cannot be used here because to import it creates a
# circular dependency with teh module_utils.network.f5.bigip file. # circular dependency with teh module_utils.network.f5.bigip file.

@ -7,7 +7,6 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
@ -42,8 +41,7 @@ options:
type of each certificate/key type. This means that you can only have one type of each certificate/key type. This means that you can only have one
RSA, one DSA, and one ECDSA per profile. If you attempt to assign two RSA, one DSA, and one ECDSA per profile. If you attempt to assign two
RSA, DSA, or ECDSA certificate/key combo, the device will reject this. RSA, DSA, or ECDSA certificate/key combo, the device will reject this.
- This list is a complex list that specifies a number of keys. There are - This list is a complex list that specifies a number of keys.
several supported keys.
suboptions: suboptions:
cert: cert:
description: description:
@ -69,6 +67,59 @@ options:
- Device partition to manage resources on. - Device partition to manage resources on.
default: Common default: Common
version_added: 2.5 version_added: 2.5
options:
description:
- Options that the system uses for SSL processing in the form of a list. When
creating a new profile, the list is provided by the parent profile.
- When a C('') or C(none) value is provided all options for SSL processing are disabled.
choices:
- netscape-reuse-cipher-change-bug
- microsoft-big-sslv3-buffer
- msie-sslv2-rsa-padding
- ssleay-080-client-dh-bug
- tls-d5-bug
- tls-block-padding-bug
- dont-insert-empty-fragments
- no-ssl
- no-dtls
- no-session-resumption-on-renegotiation
- no-tlsv1.1
- no-tlsv1.2
- single-dh-use
- ephemeral-rsa
- cipher-server-preference
- tls-rollback-bug
- no-sslv2
- no-sslv3
- no-tls
- no-tlsv1
- pkcs1-check-1
- pkcs1-check-2
- netscape-ca-dn-bug
- netscape-demo-cipher-change-bug
version_added: 2.7
secure_renegotiation:
description:
- Specifies the method of secure renegotiations for SSL connections. When
creating a new profile, the setting is provided by the parent profile.
- When C(request) is set the ssystem request secure renegotation of SSL
connections.
- C(require) is a default setting and when set the system permits initial SSL
handshakes from clients but terminates renegotiations from unpatched clients.
- The C(require-strict) setting the system requires strict renegotiation of SSL
connections. In this mode the system refuses connections to insecure servers,
and terminates existing SSL connections to insecure servers.
choices:
- require
- require-strict
- request
version_added: 2.7
allow_non_ssl:
description:
- Enables or disables acceptance of non-SSL connections.
- When creating a new profile, the setting is provided by the parent profile.
type: bool
version_added: 2.7
state: state:
description: description:
- When C(present), ensures that the profile exists. - When C(present), ensures that the profile exists.
@ -83,6 +134,7 @@ notes:
extends_documentation_fragment: f5 extends_documentation_fragment: f5
author: author:
- Tim Rupp (@caphrim007) - Tim Rupp (@caphrim007)
- Wojciech Wypior (@wojtek0806)
''' '''
EXAMPLES = r''' EXAMPLES = r'''
@ -105,6 +157,28 @@ EXAMPLES = r'''
ciphers: "!SSLv3:!SSLv2:ECDHE+AES-GCM+SHA256:ECDHE-RSA-AES128-CBC-SHA" ciphers: "!SSLv3:!SSLv2:ECDHE+AES-GCM+SHA256:ECDHE-RSA-AES128-CBC-SHA"
delegate_to: localhost delegate_to: localhost
- name: Create client SSL profile with specific SSL options
bigip_profile_client_ssl:
state: present
server: lb.mydomain.com
user: admin
password: secret
name: my_profile
options:
- no-sslv2
- no-sslv3
delegate_to: localhost
- name: Create client SSL profile require secure renegotiation
bigip_profile_client_ssl:
state: present
server: lb.mydomain.com
user: admin
password: secret
name: my_profile
secure_renegotation: request
delegate_to: localhost
- name: Create a client SSL profile with a cert/key/chain setting - name: Create a client SSL profile with a cert/key/chain setting
bigip_profile_client_ssl: bigip_profile_client_ssl:
state: present state: present
@ -125,6 +199,21 @@ ciphers:
returned: changed returned: changed
type: string type: string
sample: "!SSLv3:!SSLv2:ECDHE+AES-GCM+SHA256:ECDHE-RSA-AES128-CBC-SHA" sample: "!SSLv3:!SSLv2:ECDHE+AES-GCM+SHA256:ECDHE-RSA-AES128-CBC-SHA"
options:
description: The list of options for SSL processing.
returned: changed
type: list
sample: ['no-sslv2', 'no-sslv3']
secure_renegotation:
description: The method of secure SSL renegotiation.
returned: changed
type: string
sample: request
allow_non_ssl:
description: Acceptance of non-SSL connections.
returned: changed
type: bool
sample: yes
''' '''
import os import os
@ -141,6 +230,8 @@ try:
from library.module_utils.network.f5.common import cleanup_tokens from library.module_utils.network.f5.common import cleanup_tokens
from library.module_utils.network.f5.common import fq_name from library.module_utils.network.f5.common import fq_name
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
from library.module_utils.network.f5.common import flatten_boolean
from library.module_utils.network.f5.common import is_empty_list
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
@ -153,6 +244,8 @@ except ImportError:
from ansible.module_utils.network.f5.common import cleanup_tokens from ansible.module_utils.network.f5.common import cleanup_tokens
from ansible.module_utils.network.f5.common import fq_name from ansible.module_utils.network.f5.common import fq_name
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
from ansible.module_utils.network.f5.common import flatten_boolean
from ansible.module_utils.network.f5.common import is_empty_list
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
@ -162,20 +255,26 @@ except ImportError:
class Parameters(AnsibleF5Parameters): class Parameters(AnsibleF5Parameters):
api_map = { api_map = {
'certKeyChain': 'cert_key_chain', 'certKeyChain': 'cert_key_chain',
'defaultsFrom': 'parent' 'defaultsFrom': 'parent',
'allowNonSsl': 'allow_non_ssl',
'secureRenegotiation': 'secure_renegotiation',
'tmOptions': 'options',
} }
api_attributes = [ api_attributes = [
'ciphers', 'certKeyChain', 'ciphers', 'certKeyChain',
'defaultsFrom' 'defaultsFrom', 'tmOptions',
'secureRenegotiation', 'allowNonSsl',
] ]
returnables = [ returnables = [
'ciphers' 'ciphers', 'allow_non_ssl', 'options',
'secure_renegotiation',
] ]
updatables = [ updatables = [
'ciphers', 'cert_key_chain' 'ciphers', 'cert_key_chain', 'allow_non_ssl',
'options', 'secure_renegotiation',
] ]
@ -237,6 +336,57 @@ class ModuleParameters(Parameters):
result = sorted(result, key=lambda x: x['name']) result = sorted(result, key=lambda x: x['name'])
return result return result
@property
def allow_non_ssl(self):
result = flatten_boolean(self._values['allow_non_ssl'])
if result is None:
return None
if result == 'yes':
return 'enabled'
return 'disabled'
@property
def options(self):
choices = [
'netscape-reuse-cipher-change-bug',
'microsoft-big-sslv3-buffer',
'msie-sslv2-rsa-padding',
'ssleay-080-client-dh-bug',
'tls-d5-bug',
'tls-block-padding-bug',
'dont-insert-empty-fragments',
'no-ssl',
'no-dtls',
'no-session-resumption-on-renegotiation',
'no-tlsv1.1',
'no-tlsv1.2',
'single-dh-use',
'ephemeral-rsa',
'cipher-server-preference',
'tls-rollback-bug',
'no-sslv2',
'no-sslv3',
'no-tls',
'no-tlsv1',
'pkcs1-check-1',
'pkcs1-check-2',
'netscape-ca-dn-bug',
'netscape-demo-cipher-change-bug'
]
options = self._values['options']
if options is None:
return None
if is_empty_list(options):
return []
if set(options).issubset(set(choices)):
return options
else:
offenders = set(options).difference(set(choices))
raise F5ModuleError('Invalid options specified: {0}'.format(offenders))
class ApiParameters(Parameters): class ApiParameters(Parameters):
@property @property
@ -275,7 +425,13 @@ class UsableChanges(Changes):
class ReportableChanges(Changes): class ReportableChanges(Changes):
pass @property
def allow_non_ssl(self):
if self._values['allow_non_ssl'] is None:
return None
elif self._values['allow_non_ssl'] == 'enabled':
return 'yes'
return 'no'
class Difference(object): class Difference(object):
@ -331,6 +487,22 @@ class Difference(object):
result = self._diff_complex_items(self.want.cert_key_chain, self.have.cert_key_chain) result = self._diff_complex_items(self.want.cert_key_chain, self.have.cert_key_chain)
return result return result
@property
def options(self):
if self.want.options is None:
return None
if not self.want.options:
if self.have.options is None:
return None
if not self.have.options:
return None
if self.have.options is not None:
return self.want.options
if self.have.options is None:
return self.want.options
if set(self.want.options) != set(self.have.options):
return self.want.options
class ModuleManager(object): class ModuleManager(object):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -482,6 +654,39 @@ class ArgumentSpec(object):
name=dict(required=True), name=dict(required=True),
parent=dict(default='/Common/clientssl'), parent=dict(default='/Common/clientssl'),
ciphers=dict(), ciphers=dict(),
allow_non_ssl=dict(type='bool'),
secure_renegotiation=dict(
choices=['require', 'require-strict', 'request']
),
options=dict(
type='list',
choices=[
'netscape-reuse-cipher-change-bug',
'microsoft-big-sslv3-buffer',
'msie-sslv2-rsa-padding',
'ssleay-080-client-dh-bug',
'tls-d5-bug',
'tls-block-padding-bug',
'dont-insert-empty-fragments',
'no-ssl',
'no-dtls',
'no-session-resumption-on-renegotiation',
'no-tlsv1.1',
'no-tlsv1.2',
'single-dh-use',
'ephemeral-rsa',
'cipher-server-preference',
'tls-rollback-bug',
'no-sslv2',
'no-sslv3',
'no-tls',
'no-tlsv1',
'pkcs1-check-1',
'pkcs1-check-2',
'netscape-ca-dn-bug',
'netscape-demo-cipher-change-bug',
]
),
cert_key_chain=dict( cert_key_chain=dict(
type='list', type='list',
options=dict( options=dict(
@ -507,7 +712,6 @@ class ArgumentSpec(object):
def main(): def main():
spec = ArgumentSpec() spec = ArgumentSpec()
module = AnsibleModule( module = AnsibleModule(
argument_spec=spec.argument_spec, argument_spec=spec.argument_spec,
supports_check_mode=spec.supports_check_mode supports_check_mode=spec.supports_check_mode
@ -515,8 +719,9 @@ def main():
if not HAS_F5SDK: if not HAS_F5SDK:
module.fail_json(msg="The python f5-sdk module is required") module.fail_json(msg="The python f5-sdk module is required")
client = F5Client(**module.params)
try: try:
client = F5Client(**module.params)
mm = ModuleManager(module=module, client=client) mm = ModuleManager(module=module, client=client)
results = mm.exec_module() results = mm.exec_module()
cleanup_tokens(client) cleanup_tokens(client)

Loading…
Cancel
Save