简体   繁体   中英

python replace an element in a list

I want to build a ssh_config and an .alias file out of password manager database. From the database I get all my information via JSON. The ssh_config should then look like the following:

Servername
    User foo
    Port 22
    Hostname Servername

Additional values can occur. The alias file gets the same values, but in one line:

alias Servername="ssh -p 22 foo@Servername"

So far so good this works fine. But now the password database has several entries and some are the same server, but different users. I want a file for usernames only start with "foo" or "bar" and for any other I assume there are admin users and if there is an entry with such an admin user I'd like to have this user instead of any "foo" or "bar" This is currently my function to create ssh_config and alias file

# define function to add values to files
def fillSSH ( item, ssh_config, alias ):
    # split item name, first is customer server
    shortname = item.get('name').split()            
    # append Host entry to ssh_config
    ssh_config.append('Host ' + shortname[0])
    # append User entry to ssh_config
    ssh_config.append('   User ' + access_url[3])
    # If there is a :[port] at the end, we have 6 objects
    if len(access_url) >= 6:
        # append Port entry to ssh_config if it exists
        ssh_config.append('   Port ' + access_url[5])
        # create the alias entry just once
        aliasurl = 'alias ' + shortname[0] + '="ssh -p' + access_url[5] + ' ' + access_url[3] + '@' + access_url[4] + '"'
    else: 
        # create the alias entry just once
        aliasurl = 'alias ' + shortname[0] + '="ssh ' + access_url[3] + '@' + access_url[4] + '"'
    # append HostName entry to ssh_config
    ssh_config.append('   HostName ' + access_url[4])
    # append empty line 
    ssh_config.append('')

    # append entry for alias to list
    alias.append(aliasurl)

Now I am not sure how to proceed with my different users. I have something like

    # split access url by : / @
    access_url = re.split(':|/|@',item.get('access_info'))   
    # if foo or bar, for everyone
    if access_url[3] == 'foo' or access_url[3] == 'bar':
        fillSSH (item, ssh_config, alias)
    # else just for admins if not seen before
    else:
        fillSSH (item, ssh_config_admins, alias_admins)

So currently I have two ideas how I could proceed here. 1) I have to add a var "seen" where I add all server names. If I have seen a Servername and the new user is either "foo" or "bar" I can ignore the entry for my admin list and add it to the normal list instead. But if I have seen the Servername and the new user isn't "foo" or "bar", then I need to find the old entry in ssh_config_admins to replace it.

2) Another idea would be to just create a list with all "foo" and "bar" users and a list with all other users. But I'd like to have "foo" and "bar" users for my admins as well if there is no other login for that server, so how to merge them in this case? I think then I have to walk twice through the list, once to get all non-"foo" and "bar" users and the second time to get just foo and bar and if the servername is already in my list I just add them to the all list and not to the admins list.

So for both cases I have no idea how to really solve them, maybe someone knows how or even another way I could go here.

If I understand correctly, you're trying to build two config files:

  • one with all the known hosts, with one entry per server, with the credentials of users "foo" or "bar" only if there is no other user specified
  • one will all the credentials of users "foo" and "bar", so not necessarily all the known hosts

Is this correct?

If so, one solution would be to do two passes:

  1. Build a dict containing the parsed info for all the known hosts, separating between admin and foo/bar user credential. For example, it could take that form

     { 'server1': { 'admin': { 'username': 'blah', 'port': 22, etc. }, 'foobar': { 'username': 'foo', 'port': 22', etc. } }, 'server2': { 'foobar': { 'username': 'bar', 'port': 332, etc. } } } 
  2. Loop through this created dict, and build your admin file by either taking the "admin" credentials, or the "foobar" credentials if there is no "admin" credential. For example, something like this:

     for server, creds in enumerate(hosts): credentials = creds.get('admin') or creds.get('foobar') fill_admin_file(credentials) 

Is that what you're trying to do?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM