Developer

 View Only
last person joined: 9 days ago 

Expand all | Collapse all

Change WLAN pre-shared key?

This thread has been viewed 53 times
  • 1.  Change WLAN pre-shared key?

    Posted Mar 22, 2023 09:26 AM

    I'm trying to change a WLAN pre-shared key via Aruba Central API.  I'm authenticating with the python SDK and I think I want to change the "wpa_passphrase" through the "Update an existing WLAN" api - 

    PUT/configuration/full_wlan/{group_name_or_guid_or_serial_number}/{wlan_name}

    The get is working in swagger, but not the put.  I think I'm putting the wlan_data in wrong - I'm trying:

    {
    "wpa_passphrase":"testing1234"
    }

    But I'm getting a 500 Response code.

    Should I be trying to change the password through Central?  Or should I connect to the IAP and change it locally in the controller AP?



    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------


  • 2.  RE: Change WLAN pre-shared key?

    Posted Mar 24, 2023 05:10 AM

    I can not test it right now, but I had some settings where you need to always send the full settings and it is not possible to only send the changed values.

    I needed to do this when I want to set the AP hostname. I first download all settings, then adjust the hostname and send it all again.



    ------------------------------
    Thanks,
    Bjarne
    ------------------------------



  • 3.  RE: Change WLAN pre-shared key?

    Posted Mar 24, 2023 08:16 AM

    Hi Bjarne,

    Thanks.  I'm able to pull down all the WLAN settings with a GET.  I imported them into a python dictionary with json.loads() and changed the value of a key.  Then exported the dict back to a string with json.dumps().  I tried to send the string back with a PUT and the SDK but I get a 500 error in swagger and in py code.

    I just can't figure out the format the PUT wants - and the documentation doesn't explain it.

    There's virtually NO instructions on how to do a PUT to Central API - all the blogs, videos, etc. are using GETs.



    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------



  • 4.  RE: Change WLAN pre-shared key?

    Posted Mar 29, 2023 07:33 AM

    Hi Brannen,

    if you are using PyCentral as your connection library, you don't need to loads and dumps JSON because it is based on request and that takes care of that automatically.

    Looking at the documentation it should work like this:

    from pycentral.base import ArubaCentralBase  
    
    
    def update_psk(central: ArubaCentralBase, group_name: str, wlan_name: str, essid: str, new_psk: str,
                   wlan_type: str = 'employee', **kwargs) -> dict:
        wlan = {
            'essid': essid,
            'type': wlan_type,
            'wpa_passphrase': new_psk,
            'wpa_passphrase_changed': True
        }
        body = {
            'wlan': wlan
        }
        response = central.command(
            apiMethod='PUT',
            apiPath=f'configuration/v2/wlan/{group_name}/{wlan_name}',
            apiParams=kwargs,
            apiData=body
        )
        return response
    

    But I can't test it right now.



    ------------------------------
    Thanks,
    Bjarne
    ------------------------------



  • 5.  RE: Change WLAN pre-shared key?

    Posted Mar 29, 2023 08:14 AM

    Hi Bjarne,

    Thanks for the code.  Would you mind sharing a link to the documentation you were referencing?

    I tried to bring your code into mine.  I didn't follow where you were bring **kwargs into the function, and then passing them to central.command as apiParams ... where is wlan used?

    Note - I commented out my original code, and put the changed code below it.

    I tried the code below, and got a 400 "detail LTTEST is not of type 'object':

    wlan = {
        'essid':"LTTEST",
        'type':"employee",
        'wpa_passphrase':'testing123',
        'wpa_passphrase_changed':True
    }
    
    body = {'wlan':'LTTEST'}
    
    # apiPath = "/configuration/full_wlan/IAP_LT_VantagePark/LTTEST" # the api endpoint.
    apiPath = "/configuration/v2/wlan/IAP_LT_VantagePark/LTTEST" # the api endpoint. from: community.arubanetworks.com discusion post.
    apiMethod = "PUT"
    apiParams = cfg_string
    
    
    '''
    .command is a method of the ArubaCentralBase class.  Since we instantiated the class as the object
    central, the .command method is under the central object.
    
    From the sdk doc:
    This function calls requestURL to make an API call to Aruba Central after gathering parameters required for API call.
    When an API call fails with HTTP 401 error code, the same API call is retried once after an attempt to refresh access token or
    create new access token is made.
    '''
    # This command will make the api call to central.  The paramaters were created above.
    # The api response will be saved into variable, "data"
    # response = central.command(apiMethod=apiMethod, apiPath=apiPath, apiParams=apiParams)
    response = central.command(apiMethod=apiMethod, apiPath=apiPath, apiParams=wlan, apiData=body)
    print(response)

    Response:

    {'code': 400, 'msg': {'detail': "'LTTEST' is not of type 'object'", 'status': 400, 'title': 'Bad Request', 'type': 'about:blank'}, 'headers': {'Content-Type': 'application/problem+json', 'Content-Length': '119', 'Connection': 'keep-alive', 'X-RateLimit-Limit-day': '1000', 'X-RateLimit-Remaining-day': '998', 'X-RateLimit-Limit-second': '7', 'X-RateLimit-Remaining-second': '6', 'Date': 'Wed, 29 Mar 2023 12:06:01 GMT', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache, no-store, must-revalidate, private', 'Pragma': 'no-cache', 'X-Frame-Options': 'SAMEORIGIN', 'X-Request-Start': 't=1680091561.277', 'X-XSS-Protection': '1; mode=block', 'X-Kong-Upstream-Latency': '70', 'X-Kong-Proxy-Latency': '150', 'Via': 'kong/0.14.1'}}


    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------



  • 6.  RE: Change WLAN pre-shared key?
    Best Answer

    Posted Mar 29, 2023 09:13 AM

    Hi Brannen,

    here are the docs I'm referring:

    https://developer.arubanetworks.com/aruba-central/reference/apiwlanupdate_wlan_v2

    You need to put the wlan object into the body and not the SSID name

    wlan = {
        'essid':"LTTEST",
        'type':"employee",
        'wpa_passphrase':'testing123',
        'wpa_passphrase_changed':True
    }
    
    body = {'wlan':wlan}
    
    apiPath = "/configuration/v2/wlan/IAP_LT_VantagePark/LTTEST" # the api endpoint. from: community.arubanetworks.com discusion post.
    apiMethod = "PUT"
    
    response = central.command(
        apiMethod=apiMethod, 
        apiPath=apiPath, 
        apiData=body)
    
    print(response)

    The API params are not used in every API endpoint. These can be used as query parameters, aka what is behind the ? in the URL, for example page number or page size when you query a few hundred APs.

    These are not to be confused with the body parameter of the API endpoint.



    ------------------------------
    Thanks,
    Bjarne
    ------------------------------



  • 7.  RE: Change WLAN pre-shared key?

    Posted Mar 29, 2023 09:39 AM

    Thanks Bjarne

    I'm not following you on the body.  Is wlan a string?  Or was that passed in somewhere?  What is wlan, if it's not the SSID?

    body = {'wlan':wlan}


    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------



  • 8.  RE: Change WLAN pre-shared key?

    Posted Mar 29, 2023 10:16 AM

    I think I'm getting closer.  Now getting code 400, API Northbound not enabled.  (And I figured out body = {'wlan':wlan}

    # The code below instantiates an object, we're calling "central", of the ArubaCentralBase class.
    central = ArubaCentralBase(central_info=central_info, ssl_verify=False)
    
    wlan = {
        'essid':"LTTEST",
        'type':"employee",
        "hide_ssid": False,
        "vlan": "15",
        'wpa_passphrase':'testing123',
        'wpa_passphrase_changed':True
    }
    
    body = {'wlan':wlan}
    
    apiPath = "/configuration/v2/wlan/IAP_LT_VantagePark/LTTEST" # the api endpoint. from: community.arubanetworks.com discusion post.
    apiMethod = "PUT"
    
    response = central.command(apiMethod=apiMethod, apiPath=apiPath, apiData=body)
    print(response)

    Response: 

    {'code': 400, 'msg': {'description': 'WLAN Northbound API is not enabled for customer id: 2004548.', 'error_code': '0001', 'service_name': 'Configuration'},

    I already have a request into support to enable Northbound API



    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------



  • 9.  RE: Change WLAN pre-shared key?

    EMPLOYEE
    Posted Mar 28, 2023 04:49 AM

    Have you seen the Swagger interface in Central? There you can find and check the API syntax. From there I found that the /configuration/v2/wlan/ call probably will work better for your case:

    I found this by first taking the call 3 lines up (Get the information of an existing WLAN), there you can get the current config; and see what fields are there, then compile and test the PUT call, where I first did not have the essid and type fields, but the response code mentioned that these were mandatory.

    Working with the Swagger documentation, you can find the correct calls, then with Postman I typically test the call outside of Central to then put it in python code.



    ------------------------------
    Herman Robers
    ------------------------
    If you have urgent issues, always contact your Aruba partner, distributor, or Aruba TAC Support. Check https://www.arubanetworks.com/support-services/contact-support/ for how to contact Aruba TAC. Any opinions expressed here are solely my own and not necessarily that of Hewlett Packard Enterprise or Aruba Networks.

    In case your problem is solved, please invest the time to post a follow-up with the information on how you solved it. Others can benefit from that.
    ------------------------------



  • 10.  RE: Change WLAN pre-shared key?

    Posted Mar 29, 2023 07:39 AM

    Hi Herman.

    Yes, I've seen and used the swagger interfaces in both the central API doc and the aruba.developer page.  They seem almost the same, but the developer one is slightly more helpful.

    What's not helpful are:

    1. The put/post methods don't tell you the format to send the data up to them.  Is it a straight dictionary?  Is it a string?  Is it encoded?  I've tried various methods, none of them worked.
    2. Both the swagger interfaces are listing multiple commands to do the same thing.  In your post, there's a "get wlan list" at the top of the options, and right below the one you have highlighted, there's another "get wlan list".  It's unclear, to me at least, which one (of any pair) to use and why there's two of them.  It seems that one is depracated, but which?  One says "no northbound api" access ... and googling says to open a ticket.  The other one doesn't give the northbound error, it just doesn't work - hence my post.

    After my post, I've put in a ticket about it, and they said I need to get northbound access approved, which I'm working on getting now.

    Also, there seems to be little to no blogs, videos, etc. about how to change configs via an api.  I can GET config all day long - but doing a PUT or a POST is a different story.  It'd be helpful to have more examples, blogs, videos about how to make changes, not just get information out.



    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------



  • 11.  RE: Change WLAN pre-shared key?

    EMPLOYEE
    Posted Mar 29, 2023 10:27 AM

    This is the python code that I use to do a put call:

        def put_call(self, url, header, data):
            header = {"authorization": f"Bearer {self.access_token}"}
            r = requests.put(self.vars["base_url"] + url, headers=header, json=data)
    

    and I probably 'borrowed' that from someone else. The requests library will automatically encode the dictionary 'data' into a JSON body. This is how I call the function:

    url=f'/msp_api/v1/customers/{customer_id}/devices'
    header = {"Authorization": f"Bearer {self.access_token}"}
    data={ "devices": [ { "serial": grpap, "mac": grpmac } ], "group": grpname }
    resp=self.put_call(url, header, data)

    The request library will then use the 'url', add the entries in 'header' as headers, and json encode the data dictionary to json as the body of the PUT request.

    I have seen many products document it similar and with REST calls it seems industry standard to encode the data like this. It took me a while to learn this, but after that many products and APIs work the same.

    If you have the PUT data already JSON encoded, you can also use data=myjsondata instead of json=data in the requests call. Difference is that data=raw and json=does encoding for you. Here is some more info on that one. The PyCentral library abstracts the actual calls which may make things easier as you don't need to care about it anymore.



    ------------------------------
    Herman Robers
    ------------------------
    If you have urgent issues, always contact your Aruba partner, distributor, or Aruba TAC Support. Check https://www.arubanetworks.com/support-services/contact-support/ for how to contact Aruba TAC. Any opinions expressed here are solely my own and not necessarily that of Hewlett Packard Enterprise or Aruba Networks.

    In case your problem is solved, please invest the time to post a follow-up with the information on how you solved it. Others can benefit from that.
    ------------------------------



  • 12.  RE: Change WLAN pre-shared key?

    Posted Apr 13, 2023 02:49 PM

    For the people that come upon this question:
    1. Make sure you have your Northbound API enabled - you have to open an Aruba TAC case for this.  It might take a few weeks (as of this writing).

    2.  As soon as we got our Northbound API turned on, here's the code that worked right away.

    #!/usr/bin/env python3
    '''Connects to Aruba Central and changes a HARDCODED WLAN - change to paramater.
    python 3.10.9
    
    uses external functions to manage the API token using the Aruba Central SDK - not shown.
    '''
    from pycentral.base import ArubaCentralBase
    from pprint import pprint
    import json
    
    # Importing our script, that uses the pycentral.base.ArubaCentralBase to manage the token.
    from aruba_central_authenticate import get_token
    from aruba_central_save_dict import save_data
    
    # Disable the untrusted ssl certificate for self signed cert warning.
    import urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    # Call the function to get the oauth2 token
    # It will make an oauth2 api call to central to pass in credentials and keys
    # to retrieve a token and store it in a temp directory.
    token = get_token()
    
    # Sets the code to use a self signed cert and not complain about it.
    ssl_verify = False
    
    # Build a dictionary with the base url and the token
    central_info = {
        "base_url": "https://apigw-prod2.central.arubanetworks.com",
        "token": token
    }
    
    '''
    ArubaCentralBase is a class in pycentral.
    You can find it here: https://github.com/aruba/pycentral/blob/master/pycentral/base.py
    
    From the SDK:
        """This is the Base class for Aruba Central which handles.
        1. token management (OAUTH2.0, cache/storage for reuse and refresh token). Default token caching
        is in unencrypted file. Override with your implementation for secure handling of access tokens.
        2. command function makes API requests, handles token expiry and auto-refresh expired tokens.
        Auto-refreh feature is functional only when OAUTH2.0 is provided. Otherwise, refresh expired
        tokens at your convenience.
    '''    
    # The code below instantiates an object, we're calling "central", of the ArubaCentralBase class.
    central = ArubaCentralBase(central_info=central_info, ssl_verify=False)
    
    # This is where we define the variables of the given WLAN that we want to change the password.
    wlan = {
        'essid':"TESTING",
        'type':"employee",
        "hide_ssid": False,
        "vlan": "15",
        'wpa_passphrase':'changeme1234',
        'wpa_passphrase_changed':True
    }
    
    body = {'wlan':wlan}
    
    # Hard coded group name and wlan below, substituted with generic variable, which is not shown in code.
    apiPath = "/configuration/v2/wlan/GROUP_NAME/WLAN" # the api endpoint. from: community.arubanetworks.com discusion post.
    apiMethod = "PUT"
    
    '''
    .command is a method of the ArubaCentralBase class.  Since we instantiated the class as the object
    central, the .command method is under the central object.
    
    From the sdk doc:
    This function calls requestURL to make an API call to Aruba Central after gathering parameters required for API call.
    When an API call fails with HTTP 401 error code, the same API call is retried once after an attempt to refresh access token or
    create new access token is made.
    '''
    # This command will make the api call to central.  The paramaters were created above.
    # The api response will be saved into variable, "response"
    response = central.command(apiMethod=apiMethod, apiPath=apiPath, apiData=body)
    print(f"Changing wlan: {wlan['essid']} pre-shared key to: {wlan['wpa_passphrase']}")
    if response['code']==200:
        print(f"wlan: {wlan['essid']} password changed successfully to: {wlan['wpa_passphrase']}")
    else:
        print(f"Something went wrong. The password was not changed.")
    
    
    


    ------------------------------
    Brannen Taylor
    LendingTree
    Manager, Network Operations
    ------------------------------