Forum Discussion

Timothy_Tait's avatar
Timothy_Tait
Icon for Altostratus rankAltostratus
Sep 28, 2022
Solved

Trying to assign a policy to a virtual server

i am trying to change policies on a virtual server, using the python sdk.

i load the vs, i can load the existing policy on the vs, and delete it, but when i try to create a new policy for the vs, i get a 404 error saying that the policy cannot be found.

 

##  load the virtual server
vs = mgmt.tm.ltm.virtuals.virtual.load(name="serviceMain", partition ="partition", subPath = "subPath")

## load the policy.  this works
policy = mgmt.tm.ltm.policys.policy.load(name="pol_name", partition ="partition", subPath = "subPath")

##  load existing policy from the vs and delete it.  this works
pol = vs.policies_s.policies.load(name="pol_name", partition ="partition", subPath = "subPath")
pol.delete()

##  create a new policy.  this fails
mgmt.tm.ltm.policys.policy.create(name="pol_name", partition ="partition", subPath = "subPath")

 

i get this error:

Text: '{"code":404,"message":"01020036:3: The requested policy (pol_name) was not found.","errorStack":[],"apiError":3}'

the policy exists, and was loaded earlier in the script, but it can't be found.  i have tried other methods of attaching the policy, and they have all failed. 

any ideas?

thanks,

-t

  • JRahm's avatar
    JRahm
    Oct 05, 2022

    Ok...so I wasn't able to come up with the warm and fuzzy solution. I get the same error, and I'm not sure why. That said, I have a workaround for you. This works for me with your partition/folder structure loaded on my local test LTM:

    # Use the modify method to PATCH the specific attribute that includes the policies list.
    vip.modify(policiesReference={"items": [{"name": "Portal_QA1", "partition": "QA1_Web", "subPath": "Shared"}]})
    
    # Since policies are subcollections, refresh with expandSubcollections attribute to validate at the vip level
    vip.refresh(requests_params={'params': 'expandSubcollections=true'})

11 Replies

  • thank you so much!  that works.  i really appreciate your help with this. it was, as you can imagine, very frustrating, as i couldn't figure out why it was failing.

    cheers, and thanks again!

  • are you saying creating the policy fails, or attaching the new policy to the virtual server fails? Seems the latter, but you indicate the former. See the functional test code below:

    Working with LTM policies: https://github.com/F5Networks/f5-common-python/blob/development/f5/bigip/tm/ltm/test/functional/test_policy.py

    Policies have to be published when created in order to attach to the virtual. You can add the kwarg publish=True when creating the policy, OR load the newly created policy object and just append .publish() and hit enter. Applying to virtual should work at that point.

    • Timothy_Tait's avatar
      Timothy_Tait
      Icon for Altostratus rankAltostratus

      Thanks so much for responding.  And yes, the last line of code is wrong.

      so what i am trying to do is to attach an existing policy to a virtual server.  my understanding was that trying to load a policy that is not already attached to the server would cause a failure:

       

      vs.policies_s.policies.load(name='Portal_QA1', partition ='QA1_Web', subPath = 'Shared')

       

      yields:

      File "C:\Users\ttait\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\f5\bigip\tm\ltm\virtual.py", line 138, in load
      raise NonExtantVirtualPolicy(msg)f5.sdk_exception.NonExtantVirtualPolicy: The Policy named, Portal_QA1, does not exist on the device.

      but was successful if the policy had already been attached to the server (which i tested using the UI)

      when i try to load and publish the existing policy

       

       

      policy = mgmt.tm.ltm.policys.policy.load(name='Portal_QA1', partition ='QA1_Web', subPath = 'Shared') ## <-- this is successful
      policy.publish()

       

       

      i get this error:

      policy.publish()
      File "C:\Users\ttait\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\f5\bigip\tm\ltm\policy.py", line 155, in publish
      assert 'Drafts' in self._meta_data['uri']
      AssertionError

      i have tried using 'create' to attach an existing policy to the virtual server:

       

      vs.policies_s.policies.create(name='Portal_QA1', partition ='QA1_Web', subPath = 'Shared')

       

      and that yields this error:

      File "C:\Users\ttait\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontrol\session.py", line 295, in wrapper
      raise iControlUnexpectedHTTPError(error_message, response=response)
      icontrol.exceptions.iControlUnexpectedHTTPError: 404 Unexpected Error: Not Found for uri: https://10.80.91.172:443/mgmt/tm/ltm/virtual/~QA1_Web~reporting~serviceMain/policies/
      Text: '{"code":404,"message":"01020036:3: The requested policy (Portal_QA1) was not found.","errorStack":[],"apiError":3}'

      i feel like there should be some way to load the policy using mgmt.tm.ltm.policys.policy.load and then attach that to the virtual_server, but i cannot find anything in the documentation, or the examples that allows that.

      the thing that's causing me the headache is that i can load the policy using the ltm.policys, so i know it exists on the f5, but i cannot load it using the vs.policies_s.policies.create() or vs.policies_s.policies.load()

      is there something i need to do to the virtual server in order to allow this?

       

  • Looks like your partition is not being added to the request URI. You can try debug to see what the curl command would be outright, copy that out, add your partition, and see if that works. Then we can troubleshoot why it's not being added. Try removing the subPath kwarg as well.

     

    >>> mgmt = ManagementRoot('ltm3.test.local', 'admin', 'admin', debug=True) # set on instantiation
    >>> mgmt.debug = True  # turn on after instantiation
    >>> mgmt.debug = False # turn off
    >>> for x in mgmt.debug_output:
    ...... print(x)

     

    output will show you with curl what the request URI looks like. You can iterate through the debug_ouput list after you run your commands that fail.

    Also, the nomenclature of "create" is pretty weird, but it is create on the virtual to add an existing policy to it. I wish we had just used the proper REST verbs for the actions...

     

    • JRahm's avatar
      JRahm
      Icon for Admin rankAdmin

      also...this code should *just work* once we get your partitions worked out

      # Load existing virtual with no policy and assert it doesn't exist on the virtual
      v1 = b.tm.ltm.virtuals.virtual.load(‘name’: ‘myvip’, ‘partition’: ‘Common’)
      assert v1.policies_s.policies.exists(‘name’: ‘mypol’, ‘partition’: ‘Common’) is False
      # Add the existing policy to the virtual
      v1_pol = v1.policies_s.policies.create(name=‘mypol’, ‘partition’: ‘Common’)
      # Refresh the virtual object so the newly attached policy is referenced locally
      v1.refresh()
      # assert the policy exists on the virtual
      assert v1.policies_s.policies.exists(‘name’: ‘mypol’, ‘partition’: ‘Common’) is True
    • Timothy_Tait's avatar
      Timothy_Tait
      Icon for Altostratus rankAltostratus

      so i added debugging in to the code, and then tried to run the code you added below.  here's the output:

      loading v1
      asserting policy is not there
      loading policy
      exception caught: 404 Unexpected Error: Not Found for uri: https://10.80.91.172:443/mgmt/tm/ltm/virtual/~QA1_Web~reporting~serviceMain/policies/
      Text: '{"code":404,"message":"01020036:3: The requested policy (Portal_QA1) was not found.","errorStack":[],"apiError":3}'
      debug output
      curl -k -X GET https://10.80.91.172:443/mgmt/tm/ltm/virtual/~QA1_Web~reporting~serviceMain -H 'User-Agent: python-requests/2.26.0 f5-icontrol-rest-python/1.3.13' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'Connection: keep-alive' -H 'Content-Type: application/json' -H 'Cookie: AUTH_TOKEN; BIGIPAuthUsernameCookie=svc-f5scraperlabRO' -H 'Authorization: Basic AUTH'
      curl -k -X GET https://10.80.91.172:443/mgmt/tm/ltm/virtual/~QA1_Web~reporting~serviceMain/policies/ -H 'User-Agent: python-requests/2.26.0 f5-icontrol-rest-python/1.3.13' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'Connection: keep-alive' -H 'Content-Type: application/json' -H 'Cookie: AUTH_TOKEN; BIGIPAuthUsernameCookie=svc-f5scraperlabRO' -H 'Authorization: Basic AUTH'
      curl -k -X POST https://10.80.91.172:443/mgmt/tm/ltm/virtual/~QA1_Web~reporting~serviceMain/policies/ -H 'User-Agent: python-requests/2.26.0 f5-icontrol-rest-python/1.3.13' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'Connection: keep-alive' -H 'Content-Type: application/json' -H 'Cookie: AUTH_TOKEN; BIGIPAuthUsernameCookie=svc-f5scraperlabRO' -H 'Content-Length: 67' -H 'Authorization: Basic AUTH' -d '{"name": "Portal_QA1", "partition": "QA1_Web", "subPath": "Shared"}'

      it seems that the partition and subpath are being added to the request. 

      one thought i had was that there might be something that i have to do differently, as the policy and vs are in different subpaths.  could that be what's causing the issue?

      if i remove the partition/subpath when loading the vs, it gives me a 404 error, so that's not going to work, since none of these are in /Common partition.

      • JRahm's avatar
        JRahm
        Icon for Admin rankAdmin

        could you give me a sanitized version of a dummy virtual and policy folder/subpath from your environment? Honestly haven't done much with them personally so I don't have much experience on the automation side handling that. I can throw what you have up in my environment and figure it out.