views:

99

answers:

3

Say I have a fabfile.py that looks like this:

def setup():                                
    pwd = getpass('mysql password: ')
    run('mysql -umoo -p%s something' % pwd)

The output of this is:

[host] run: mysql -umoo -pTheActualPassword

Is there a way to make the output look like this?

[host] run: mysql -umoo -p*******

Note: This is not a mysql question!

+1  A: 

It may be better to put the password in the user's ~/.my.cnf under the [client] section. This way you don't have to put the password in the python file.

[client]
password=TheActualPassword
Rob Olmos
I clarified the question. I am only using mysql as an example, as the command I'm using does not have an alternate option to the command line.
Gerald Kaszuba
+1  A: 

When you use the Fabric command run, Fabric isn't aware of whether or not the command you are running contains a plain-text password or not. Without modifying/overriding the Fabric source code, I don't think you can get the output that you want where the command being run is shown but the password is replaced with asterisks.

You could, however, change the Fabric output level, either for the entire Fabric script or a portion, so that the command being run is not displayed. While this will hide the password, the downside is that you wouldn't see the command at all.

Take a look at the Fabric documentation on Managing Output.

Matthew Rankin
+2  A: 

Rather than modifying / overriding Fabric, you could replace stdout (or any iostream) with a filter.

Here's an example of overriding stdout to censor a specific password. Note that you could do the same thing with a regular expression, so that you wouldn't have to specify the password in the filter.

I should also mention, this isn't the most efficient code in the world, but if you're using fabric you're likely gluing a couple things together and care more about manageability than speed.

#!/usr/bin/python

import sys
import string

class StreamFilter(object):

    def __init__(self, filter, stream):
        self.stream = stream
        self.filter = filter

    def write(self,data):
        data = data.replace(self.filter, '[[TOP SECRET]]')
        self.stream.write(data)
        self.stream.flush()

if __name__ == '__main__':

    sys.stdout = StreamFilter("myPassWord", sys.stdout)

    print 'Hello there'
    print 'My password is myPassWord'

When run, this will produce:

Hello there
My password is [[TOP SECRET]]
synthesizerpatel
That's a pretty good idea!
Gerald Kaszuba