* Update nios_txt_record.py

Fix for Bug #62377

* Fixes for #62377, #64045, #64034

Fixes for #62377 nios_txt_record module cannot handle multiple TXT records

Fix for #64045 nios_a_record is requested to modify IP of existing A record, but attempts to create new A record instead

Fix for #64034 nios_fixed_address not able to add options that don't require use_options

* Update api.py

* Update nios_a_record.py examples

* Update nios_fixed_address.py

* Update nios_txt_record.py

* Update nios_fixed_address.py

* Update nios_fixed_address.py to fix #56301

Fixes #56301

* Update nios_fixed_address.py

* Update nios_a_record.py

* Update api.py
This commit is contained in:
krisvasudevan 2019-12-11 13:12:47 +05:30 committed by Sumit Jaiswal
parent 895c8ce373
commit 0685691d07
3 changed files with 48 additions and 14 deletions

View file

@ -356,16 +356,6 @@ class WapiModule(WapiBase):
res = ref res = ref
if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD, NIOS_PTR_RECORD, NIOS_SRV_RECORD)): if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD, NIOS_PTR_RECORD, NIOS_SRV_RECORD)):
# popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record/srv:record/ptr:record # popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record/srv:record/ptr:record
if 'ipv4addrs' in proposed_object:
if 'add' in proposed_object['ipv4addrs'][0]:
run_update, proposed_object = self.check_if_add_remove_ip_arg_exists(proposed_object)
if run_update:
res = self.update_object(ref, proposed_object)
result['changed'] = True
else:
res = ref
if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD)):
# popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record
proposed_object = self.on_update(proposed_object, ib_spec) proposed_object = self.on_update(proposed_object, ib_spec)
del proposed_object['view'] del proposed_object['view']
res = self.update_object(ref, proposed_object) res = self.update_object(ref, proposed_object)
@ -533,10 +523,46 @@ class WapiModule(WapiBase):
# resolves issue where a_record with uppercase name was returning null and was failing # resolves issue where a_record with uppercase name was returning null and was failing
test_obj_filter = obj_filter test_obj_filter = obj_filter
test_obj_filter['name'] = test_obj_filter['name'].lower() test_obj_filter['name'] = test_obj_filter['name'].lower()
# resolves issue where multiple a_records with same name and different IP address
try:
ipaddr_obj = self.module._check_type_dict(obj_filter['ipv4addr'])
ipaddr = ipaddr_obj['old_ipv4addr']
except TypeError:
ipaddr = obj_filter['ipv4addr']
test_obj_filter['ipv4addr'] = ipaddr
elif (ib_obj_type == NIOS_TXT_RECORD):
# resolves issue where multiple txt_records with same name and different text
test_obj_filter = obj_filter
try:
text_obj = self.module._check_type_dict(obj_filter['text'])
txt = text_obj['old_text']
except TypeError:
txt = obj_filter['text']
test_obj_filter['text'] = txt
# check if test_obj_filter is empty copy passed obj_filter # check if test_obj_filter is empty copy passed obj_filter
else: else:
test_obj_filter = obj_filter test_obj_filter = obj_filter
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=ib_spec.keys()) ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=ib_spec.keys())
elif (ib_obj_type == NIOS_A_RECORD):
# resolves issue where multiple a_records with same name and different IP address
test_obj_filter = obj_filter
try:
ipaddr_obj = self.module._check_type_dict(obj_filter['ipv4addr'])
ipaddr = ipaddr_obj['old_ipv4addr']
except TypeError:
ipaddr = obj_filter['ipv4addr']
test_obj_filter['ipv4addr'] = ipaddr
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=ib_spec.keys())
elif (ib_obj_type == NIOS_TXT_RECORD):
# resolves issue where multiple txt_records with same name and different text
test_obj_filter = obj_filter
try:
text_obj = self.module._check_type_dict(obj_filter['text'])
txt = text_obj['old_text']
except TypeError:
txt = obj_filter['text']
test_obj_filter['text'] = txt
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=ib_spec.keys())
elif (ib_obj_type == NIOS_ZONE): elif (ib_obj_type == NIOS_ZONE):
# del key 'restart_if_needed' as nios_zone get_object fails with the key present # del key 'restart_if_needed' as nios_zone get_object fails with the key present
temp = ib_spec['restart_if_needed'] temp = ib_spec['restart_if_needed']

View file

@ -41,7 +41,6 @@ options:
network: network:
description: description:
- Specifies the network range in which ipaddr exists. - Specifies the network range in which ipaddr exists.
required: true
aliases: aliases:
- network - network
network_view: network_view:
@ -180,15 +179,23 @@ def options(module):
vendor_class: <value> vendor_class: <value>
} }
It will remove any options that are set to None since WAPI will error on It will remove any options that are set to None since WAPI will error on
that condition. It will also verify that either `name` or `num` is that condition. The use_option field only applies
to special options that are displayed separately from other options and
have a use flag. This function removes the use_option flag from all
other options. It will also verify that either `name` or `num` is
set in the structure but does not validate the values are equal. set in the structure but does not validate the values are equal.
The remainder of the value validation is performed by WAPI The remainder of the value validation is performed by WAPI
''' '''
special_options = ['routers', 'router-templates', 'domain-name-servers',
'domain-name', 'broadcast-address', 'broadcast-address-offset',
'dhcp-lease-time', 'dhcp6.name-servers']
options = list() options = list()
for item in module.params['options']: for item in module.params['options']:
opt = dict([(k, v) for k, v in iteritems(item) if v is not None]) opt = dict([(k, v) for k, v in iteritems(item) if v is not None])
if 'name' not in opt and 'num' not in opt: if 'name' not in opt and 'num' not in opt:
module.fail_json(msg='one of `name` or `num` is required for option value') module.fail_json(msg='one of `name` or `num` is required for option value')
if opt['name'] not in special_options:
del opt['use_option']
options.append(opt) options.append(opt)
return options return options
@ -226,7 +233,7 @@ def main():
name=dict(required=True), name=dict(required=True),
ipaddr=dict(required=True, aliases=['ipaddr'], ib_req=True), ipaddr=dict(required=True, aliases=['ipaddr'], ib_req=True),
mac=dict(required=True, aliases=['mac'], ib_req=True), mac=dict(required=True, aliases=['mac'], ib_req=True),
network=dict(required=True, aliases=['network'], ib_req=True), network=dict(required=True, aliases=['network']),
network_view=dict(default='default', aliases=['network_view']), network_view=dict(default='default', aliases=['network_view']),
options=dict(type='list', elements='dict', options=option_spec, transform=options), options=dict(type='list', elements='dict', options=option_spec, transform=options),

View file

@ -43,6 +43,7 @@ options:
per substring, up to a total of 512 bytes. To enter leading, per substring, up to a total of 512 bytes. To enter leading,
trailing, or embedded spaces in the text, add quotes around the trailing, or embedded spaces in the text, add quotes around the
text to preserve the spaces. text to preserve the spaces.
required: true
ttl: ttl:
description: description:
- Configures the TTL to be associated with this tst record - Configures the TTL to be associated with this tst record
@ -106,7 +107,7 @@ def main():
ib_spec = dict( ib_spec = dict(
name=dict(required=True, ib_req=True), name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True),
text=dict(type='str'), text=dict(ib_req=True),
ttl=dict(type='int'), ttl=dict(type='int'),
extattrs=dict(type='dict'), extattrs=dict(type='dict'),
comment=dict(), comment=dict(),