Gerald Kaszuba Gerald Kaszuba - 17 days ago 9
Python Question

How to hide the password in fabric when the command is printed out?

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!

Answer

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. It gets the password from Fabric's env.password variable, set by the -I argument. 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
from fabric.api import *
from fabric.tasks import *
from fabric.contrib import *

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()

    def flush(self):
        self.stream.flush()

@task
def can_you_see_the_password():
    sys.stdout = StreamFilter(env.password, sys.stdout)
    print 'Hello there'
    print 'My password is %s' % env.password 

When run:

fab -I can_you_see_the_password
Initial value for env.password:

this will produce:

Hello there
My password is [[TOP SECRET]]