Search code examples
pythonpython-3.xyamlpyyaml

python variable extracted from nested yaml


Trying to find a way to iterate over the roleprivs and having issues getting to that level of the yaml from python.

testrole.yaml

info: 
  rolename: "testDeveloper"
  desc: "Test Developer Role"
  roletype: "user"
roleprivs:
  admin-appliance:
    name: "Administrate Appliance" # Informational Only Not used in code 
    description: "admin-appliance" # Informational Only Not used in code 
    code: "admin-appliance"
    access: "full"
  admin-backupSettings:
    name: "Administrate Backup Settings" # Informational Only Not used in code 
    description: "admin-appliance" # Informational Only Not used in code 
    code: "admin-backupSettings"
    access: "full"

I have a few different needs / use cases.

  1. Part 1 of the script below - grab all the files in a directory and take the rolename, desc, and roletype and create a role.
  2. Get the Role ID of the newly created role that was above.
  3. HELP Needed - going back to the original yaml file and iterating over it and getting only the roleprivs..code and roleprivs..code --> role type would be something like admin-appliance. Keeping in mind that there are like 50 some odd features that need to be updated with the type of access.

The question: How do i get the code and access in the yaml file into python variables?

def genericRoleCreate(baseURL, bearerToken):
    print("initial")
    files = glob.glob(ROLES_DIR)
    logger.debug('Roles Dir '+ROLES_DIR)
    for file in files:
      yaml_file = file
      logger.debug(yaml_file)
      with open(yaml_file) as f:
        try:
          result=yaml.safe_load(f)
          authority = result['info']['rolename']
          desc = result['info']['desc']
          roletype = result['info']['roletype']
          url = baseURL+"/api/roles"
          payload= json.dumps({"role":{"authority": authority, "description": desc, "roletype": roletype}})
          headers = {'Content-Type': 'application/json','Authorization': 'Bearer ' +bearerToken}
          roleResult = requests.request("POST", url, verify=False, headers=headers, data=payload)
          logger.debug(roleResult.text)
        except yaml.YAMLError as exc:
          logger.error(exc)
        # Getting Role ID
      try:
        with open(yaml_file) as f:
          result = yaml.safe_load(f)
        authority = result['info']['rolename']
        url = baseURL+"/api/roles?phrase="+authority
        headers = {'Content-Type': 'application/json','Authorization': 'Bearer ' +bearerToken}
        roleResult = requests.request("GET", url, verify=False, headers=headers )
        #print(roleResult.text)
        roleID = json.loads(roleResult.text)
        role = roleID['roles'][0]['id']
        #logger.debug(role)
        logger.info("Get Role ID")
        print(role)
        #return role
        #logger.debug("Role ID: "+role)
      except Exception as e:
        logger.error('Exception occurred', exc_info=True)
        logger.error('Error getting roleID')
        # Start Updating
        #role = getRoleId(baseURL, bearerToken)
      try:
        with open(yaml_file) as f:
          result = yaml.safe_load(f)
      except Exception as e:
        logger.error("Broken")
        strRoleID = str(role)
        url = baseURL+"/api/roles/"+strRoleID+"/update-permission"
        #logger.debug(result)
      keys = list(result.keys())
      for features in keys:
        #logger.debug(keys)
        code = result[features]['code']
        access = result[features]['access']
        payload = json.dumps({
          "permissionCode": code,
          "access": access
        })
        headers = {'Content-Type': 'application/json','Authorization': 'Bearer ' +bearerToken}
        requests.request("PUT", url, verify=False, headers=headers, data=payload)

lets keep in mind i do know that i should be breaking that big nasty thing into multiple functions - i have it broken down in other areas - but compiling everything in a single function at the time.

I have been trying multiple iterations of how to get to the feature level. I have looked at many examples and can't seem to figure out how to drop to a level.

update 1

      try:
        with open(yaml_file, 'r') as f:
          result = yaml.safe_load(f)
      except Exception as e:
        logger.error("Broken")
      strRoleID = str(role)
      url = baseURL+"/api/roles/"+strRoleID+"/update-permission"
        #logger.debug(result)
      keys = list(result['roleprivs'].keys())
      
      #code2 = {roleprivs for roleprivs in result['roleprivs'].keys()}
      #print(code2)
    #return inventory, sites

      
      for features in keys:
        print(features)

The code above produces the output:

admin-appliance
admin-backupSettings

now the question is how do i go one step deeper in the chain and get code and access into a variable in python.


Solution

  • I ended up solving the problem after a few hours of testing and researching...The main problem i was encountering was how do i get to the next level after roleprivs. I could easily print the main elements under the roleprivs, but getting the code and access elements were a bit of a challenge.

    I also kept running into an error where the indices needed to be an integer. This cleans up some of the keys that i was doing before and puts it into a one liner. Should help clean up a few for loops that i have been working with.

      for k, v in result['roleprivs'].items():
        print("Code "+result['roleprivs'][k]['code'])
        print("Access: "+result['roleprivs'][k]['access'])
        access = result['roleprivs'][k]['access']
        code = result['roleprivs'][k]['code']
        payload = json.dumps({
          "permissionCode": code,
          "access": access
        })
        headers = {'Content-Type': 'application/json','Authorization': 'Bearer ' +bearerToken}
        requests.request("PUT", url, verify=False, headers=headers, data=payload)
    

    From the original code i may have multiple roles in the ./config/roles/ directory. I needed to make sure i can read all and iterate in a for loop for each one. This solved it for me.

    Final output:

    2021-10-13 01:25:50,212:84:logger:role:genericRoleCreate:DEBUG:./config/roles/testDeveloper.yaml
    2021-10-13 01:25:50,487:110:logger:role:genericRoleCreate:INFO:Get Role ID
    8
    Code admin-appliance
    Access: full
    Code admin-backupSettings
    Access: full