F5Networks / f5-common-python

Python SDK for configuration and monitoring of F5® BIG-IP® devices via the iControl® REST API.
https://f5-sdk.readthedocs.org
Apache License 2.0
262 stars 134 forks source link

Cannot create FQDN Node using SDK #1487

Closed kblankenship11 closed 6 years ago

kblankenship11 commented 6 years ago

When I use the following code to create a node on the F5:

from f5.bigip import ManagementRoot mgmt = ManagementRoot(big_ip, big_ip_user, big_ip_pass) ltm = mgmt.tm.ltm ltm.nodes.node.create(partition="Common", name="192.168.10.10", description="Created by Python")

I get the following error: f5.sdk_exception.MissingRequiredCreationParameter: Missing required params: ['address']

However in the iControl API reference (https://devcentral.f5.com/Wiki/iControlREST.APIRef_tm_ltm_node.ashx) it states that the 'address' parameter is optional; "IP address of the node. This is an optional field; if empty, the name needs to be of the form ip address".

When I try to create an FQDN node with the Python SDK, i.e.:

ltm.nodes.node.create(partition="Common", name="fqdnnode.test", description="Created by Python", fqdn={'addressFamily': 'ipv4', 'downInterval': '5', 'interval': '3600', 'tmName': arg.lower()}))

It looks for the 'address' parameter--when I don't provide it, I get this error: f5.sdk_exception.MissingRequiredCreationParameter: Missing required params: ['address']

This is a problem because even if I force my code to provide an FQDN as the 'address' the SDK won't let me because it checks that it's an IP address or not:

icontrol.exceptions.iControlUnexpectedHTTPError: 400 Unexpected Error: Bad Request for uri: https://10.23.129.132:443/mgmt/tm/ltm/node/ Text: '{"code":400,"message":"Invalid IP address: \"testnode.test\"","errorStack":[],"apiError":26214401}'

So basically I can't create an FQDN node with the Python SDK, or create an IPv4 node without providing both the name and address parameters.

jasonrahm commented 6 years ago

So we need to support the exclusive attributes of address or fqdn on create. It doesn't appear I can update a node via REST, is that your experience?

kblankenship11 commented 6 years ago

I haven't actually tried that myself with REST directly, so I'm not sure. I submitted a case to F5 support with this issue--and they led me here. This was their consensus:

"Engineering Services notes that the Python SDK is expecting address to be set to "any6" when configuring a fqdn node."

jasonrahm commented 6 years ago

If I set it at all when using fqdn I get an error. I'll work on this this weekend

jasonrahm commented 6 years ago

it's definitely possible currently as shown below, but a little wonky since the SDK requires the address but the REST API does not:

>>> n1 = b.tm.ltm.nodes.node.create(name='192.168.10.10', partition='Common', address='192.168.10.10')
>>> n2 = b.tm.ltm.nodes.node.create(name='fqdn1', partition='Common', fqdn={'tmName':'fqdn1.test.local'})
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/rahm/Documents/PycharmProjects/f5-common-python/f5/bigip/resource.py", line 1053, in create
    return self._create(**kwargs)
  File "/Users/rahm/Documents/PycharmProjects/f5-common-python/f5/bigip/resource.py", line 1001, in _create
    self._check_create_parameters(**kwargs)
  File "/Users/rahm/Documents/PycharmProjects/f5-common-python/f5/bigip/resource.py", line 966, in _check_create_parameters
    raise MissingRequiredCreationParameter(error_message)
f5.sdk_exception.MissingRequiredCreationParameter: Missing required params: ['address']
>>> n2 = b.tm.ltm.nodes.node.create(name='fqdn1', partition='Common', fqdn={'tmName':'fqdn1.test.local'}, address='any6')
>>> b.tm.ltm.nodes.node.exists(name='192.168.10.10')
True
>>> b.tm.ltm.nodes.node.exists(name='fqdn1')
True

It looks like all we have to do is require either address or fqdn to make the experience better. But for now, there is a workaround.

jasonrahm commented 6 years ago

To clarify from the larger message above, the way you can create the fqdn node with the sdk is to provide the address as any6 in addition to specifying the fqdn:

n2 = b.tm.ltm.nodes.node.create(name='fqdn1',
         partition='Common',
         fqdn={'tmName':'fqdn1.test.local'},
         address='any6')
jasonrahm commented 6 years ago

I've updated node resource to only allow address or fqdn, and resulting successes with one or the other and then the error when both are supplied will look like this:

>>> n2 = b.tm.ltm.nodes.node.create(name='fqdn3', partition='Common', fqdn={'tmName':'fqdn3.test.local'})
>>> n1 = b.tm.ltm.nodes.node.create(name='192.168.10.100', address='192.168.10.100')
>>> n1 = b.tm.ltm.nodes.node.create(name='192.168.10.100', address='any6', fqdn={'tmName':'fqdn23.test.local'})
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/rahm/Documents/PycharmProjects/f5-common-python/f5/bigip/tm/ltm/node.py", line 71, in create
    raise RequiredOneOf(required_one_of)
f5.sdk_exception.RequiredOneOf: Creation requires one of the following lists of args ( name,address ) or ( name,fqdn )

Acceptable? If so, I'll get tests written for this change this weekend and submit PR

kblankenship11 commented 6 years ago

Yes, that is exactly what I was looking for!

jasonrahm commented 6 years ago

This has been merged to development and will be in the next dot release. Closing issue.