Forum Discussion

rahvee's avatar
rahvee
Icon for Cirrus rankCirrus
Mar 07, 2023

In BIGREST, how to simultaneously add & remove ssl client profile on virtual server?

I am able to add an ssl client profile to a virtual server via

f5_session.create(f"/mgmt/tm/ltm/virtual/{rest_format(virtual_server_path_str)}/profiles", data)
I am able to remove an ssl client profile via
delete_path = f"/mgmt/tm/ltm/virtual/{rest_format(virtual_server_path_str)}/profiles/{rest_format(profile_path_str)}"
f5_session.delete(delete_path)
But I need to simultaneously add & delete, because I am replacing the ssl client profile that has "default for SNI" enabled. In order to have exactly one profile with this flag enabled, the add & remove must both occur atomically.
 
I've tried every variation I can think of, using `modify()` or `save()`, but still haven't got it right yet. Here is my latest attempt:
 
virtual_server_results = f5_session.load("/mgmt/tm/ltm/virtual")
client_ssl_profile_results = f5_session.load("/mgmt/tm/ltm/profile/client-ssl")

remove_client_ssl_profile = None # Start as None
append_client_ssl_profile = None

for client_ssl_profile in client_ssl_profile_results:
if client_ssl_profile.properties['fullPath'] == '/Common/ssl_client_profile_SNI_1':
assert remove_client_ssl_profile is None # Guarantees I cannot set it more than once
remove_client_ssl_profile = client_ssl_profile
if client_ssl_profile.properties['fullPath'] == '/Common/ssl_client_profile_SNI_2':
assert append_client_ssl_profile is None
append_client_ssl_profile = client_ssl_profile

assert remove_client_ssl_profile is not None # Guarantees I set it at least once
assert append_client_ssl_profile is not None

# Since `remove_client_ssl_profile` and `append_client_ssl_profile` started as None,
# and I have `assert remove_client_ssl_profile is None` guaranteeing it will never be set
# more than once, and I have `assert remove_client_ssl_profile is not None` guaratneeing it
# was set at least once, I am guaranteed to have found exactly one match for each.
# No more, no less.

for virtual_server in virtual_server_results:
# `profilesReference / link` always has the form:
# 'https://localhost/mgmt/tm/ltm/virtual/~Common~LDAP-Intermediate/profiles?ver=14.1.4.6'
# So strip the leading 'https://localhost' from it
strip_len = len('https://localhost')
v_s_profiles_link = virtual_server.properties["profilesReference"]['link'][strip_len:]
v_s_profiles = f5_session.load(v_s_profiles_link)
for v_s_profile in v_s_profiles:
if v_s_profile.properties['fullPath'] == remove_client_ssl_profile.properties['fullPath']:
v_s_profiles.remove(v_s_profile)
v_s_profiles.append(append_client_ssl_profile)
f5_session.save(virtual_server)

This latest attempt doesn't throw any errors, but the virtual server doesn't get changed, so it's not working.

Thanks for any help.

    • rahvee's avatar
      rahvee
      Icon for Cirrus rankCirrus

      Here, I added comments to the code to explain that. But that was never the important part. The important part is to figure out which object I need to modify by which method, in order to make both changes occur in a single operation.

  • So far, the only solution I can find (so this is what I'm currently coding up) is: I have to actually delete all the ssl profiles from the virtual server, saving the `sniDefault` one for last. Then I have to add them all back in, with the new `sniDefault` one first.