f5-common-python icon indicating copy to clipboard operation
f5-common-python copied to clipboard

Add rest-proxy URI support

Open chen23 opened this issue 8 years ago • 16 comments

This is related to: https://github.com/F5Networks/f5-icontrol-rest-python/issues/111

iWorkflow / BIG-IQ (?) support REST proxy URI. This makes it possible to apply tenant RBAC on the REST endpoints (i.e. limit a user to only be able to modify a single BIG-IP LTM pool in a single Partition).

Documented here: https://devcentral.f5.com/wiki/iControl.REST_proxy_APIs.ashx

Example of one of the changes required (this is not meant to be a "good" example, but it gets the job done). This was done to monkey patch the library:


class ManagementRootProxy(ManagementRoot):
    """An interface to a multiple BIG-IP"""
    def __init__(self, hostname, username, password, device_uuid, **kwargs):
        timeout = kwargs.pop('timeout', 30)
        port = kwargs.pop('port', 443)
        icontrol_version = kwargs.pop('icontrol_version', '')
        if kwargs:
            raise TypeError('Unexpected **kwargs: %r' % kwargs)
        # _meta_data variable values
        iCRS = iControlRESTSession(username, password, timeout=timeout)
        # define _meta_data
        self._meta_data = {
            'allowed_lazy_attributes': [Tm, Cm, Shared],
            'hostname': hostname,
            'port': port,
            'uri': 'https://%s:%s/mgmt/shared/resolver/device-groups/cm-cloud-managed-devices/devices/%s/rest-proxy/mgmt/' % (hostname, port,device_uuid),
            'icr_session': iCRS,
            'device_name': None,
            'local_ip': None,
            'bigip': self,
            'icontrol_version': icontrol_version,
            'username': username,
            'password': password,
            'tmos_version': None,
        }
        self._get_tmos_version()

chen23 avatar Jul 13 '16 12:07 chen23

@chen23 is this still a desirable feature for your use-case?

zancas avatar Aug 04 '16 18:08 zancas

@caphrim007 @pjbreaux my understanding is that @chen23 is using the SDK to integrate F5 devices with Kubernetes.

I'm very interested in supporting this use-case.

Is it the case that adding URI-proxy support will facilitate Kubernetes integrations?

Is there potential for implementing Kubernetes integrations in Ansible playbooks?

zancas avatar Aug 04 '16 19:08 zancas

@zancas we could do ansible playbooks for kubernetes. I dont know the details about what @chen23 had in mind. I have iWorkflow vagrant boxes we can use for functional tests of this proxy feature

caphrim007 avatar Aug 04 '16 19:08 caphrim007

@zancas @caphrim007 @pjbreaux The URI-proxy support is intended to provide support for use-cases where a customer may want to limit access to the REST API to only allow limited actions (i.e. up/down pool members). https://devcentral.f5.com/questions/iworkflow-20-allowed-rest-uri-mask-in-user-roles-48058 This is useful in a multi-tenant environment and/or shared services.

chen23 avatar Aug 05 '16 18:08 chen23

@zancas so then, "yes", @chen23 still wants this.

caphrim007 avatar Aug 05 '16 18:08 caphrim007

@chen23 this functionality now exists in the iworkflow portion of the SDK. Do you want it for BIG-IQ as well?

caphrim007 avatar Mar 27 '17 15:03 caphrim007

@caphrim007 iWf is good for now. Thank you for adding!

chen23 avatar Mar 27 '17 19:03 chen23

I only have BIG-IQ and currently use the rest-proxy with some homebrew scripts. If it's not too much effort, I'd appreciate it if the BIG-IQ API could have this feature too.

vsnine avatar Mar 27 '17 19:03 vsnine

@vsnine I will take a look.

caphrim007 avatar Mar 27 '17 19:03 caphrim007

@vsnine do you use it for managed, or unmanaged devices? or both? fwiw I have no idea if it supports both.

caphrim007 avatar Mar 27 '17 19:03 caphrim007

@chen23 here are the docs about it

http://f5-sdk.readthedocs.io/en/latest/userguide/rest_proxies.html

caphrim007 avatar Mar 27 '17 20:03 caphrim007

@caphrim007 currently all of our devices are fully managed.

vsnine avatar Mar 27 '17 22:03 vsnine

I'd appreciate it if the proxy class for BigIQ was added to the API

edit: Github says I just unassigned some people from the issue. I have no idea how that happened. I shouldn't have permissions on this repo

nugend avatar Apr 18 '18 19:04 nugend

I looked into this more as I am beginning more serious work with the SDK, and ran into a few issues with the iWorkflow REST proxy as it is when used with BIG-IQ CM.

In _get_device_uuid the code assumes that the devices are located in the device group cm_cloud_managed_devices which I don't believe exists in BIG-IQ by default. The SDK is hard-coded so adding other groups is a problem. https://github.com/F5Networks/f5-common-python/blob/af2746d73d7f888cf64fe7db8dfe254867ceafd7/f5/iworkflow/init.py#L178

A workaround in BIG-IQ is to create the group cm-cloud-managed-devices by sending a POST with the needed json payload. (Creating it via the webui results in the name of the group using underscores instead of dashes. )

{ "autoManageLocalhost": true,
  "displayName": "cm-cloud-managed-devices",
  "groupName": "cm-cloud-managed-devices",
  "infrastructure": false,
  "isViewGroup": false,
  "kind": "shared:resolver:device-groups:devicegroupstate",
  "properties": { "cm:gui:module": [ "adc",
                                       "device",
                                       "networksecurity",
                                       "asmsecurity"]},
  "selfLink": "https://localhost/mgmt/shared/resolver/device-groups/cm-cloud-managed-devices"}

I found an additional issue when attempting to create the group as a dynamic type and telling it to include all devices in BIG-IQ. If the group is a dynamic type, it seems to be returned as a different type of object, and _get_device_uuid fails with AttributeError: '<class 'f5.iworkflow.shared.resolver.device_groups.cm_cloud_managed_devices.Device'>' object has no attribute 'pop' I added a try/except block which catches the issue: https://github.com/F5Networks/f5-common-python/blob/af2746d73d7f888cf64fe7db8dfe254867ceafd7/f5/iworkflow/init.py#L196

            try:
                return resource.pop('uuid', None)
            except AttributeError:  # needed if group is a dynamic group
                return resource.uuid

vsnine avatar Apr 19 '18 05:04 vsnine

@vsnine I'm new to using this package, but my assumption from up above was that a different proxy class using a slightly different API would have to be written for BigIQ. However, I'm 99% certain that the hard coded reference to cm_cloud_managed_devices is a bug given that device group is an argument to that class.

In any case, I find it odd that the Proxy is composed the way it is. It'd make more sense to me that a iWorkflow or BigIQ MangementRoot instance would be passed in as a proxy argument to a BigIP ManagementRoot (or maybe a specific BigIP ManagementRootProxy class) as an argument so that multiple BigIP instances could be constructed from the "master" instance.

But, like I said, I'm new to using this package.

nugend avatar Apr 19 '18 15:04 nugend

@nugend I'd say you are right that a BIG-IQ flavoured proxy is needed. It probably is possible to pull the ManagementProxy functions out and place them in a spot where they can be used for both BIG-IQ and iWorkflow.

vsnine avatar Apr 20 '18 15:04 vsnine