#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
NetRC client
Compatibility:
- Linux/Mac
- Python 2.7.x
"""
# stdlib imports
import os
import logging
import netrc
# Define logger
logging.basicConfig(level=logging.CRITICAL)
log = logging.getLogger(__file__)
# Home directory
HOME = os.path.expanduser("~")
NETRC_FILE_PATH = os.path.abspath(os.path.join(HOME, ".netrc"))
class NetRc(object):
"""
Read, write and update netrc file
"""
def __init__(self, machine, login="", password="",
account=""):
self.machine = machine
self.login = login
self.password = password
self.account = account
def create_or_update(self, path=NETRC_FILE_PATH):
"""
Update netrc, if does not exist create new netrc
"""
# get netrc
machines, macros = self.get(path=path)
# update netrc
machines = self.update(machines)
# write netrc
self.write({
"machines": machines,
"macros": macros
}, path=NETRC_FILE_PATH)
def write(self, content, path=""):
"""
Write content to netrc file
"""
try:
with open(path, "w+") as fl:
# machine content
for machine, auth in content["machines"].iteritems():
log.debug("Writing machine {0} to {1}".format(machine, path))
fl.writelines("\n".join([
"machine {0}".format(machine),
"login {0}".format(auth[0]),
"password {0}\n".format(auth[2]),
]))
# netrc account field is optional
if auth[1]:
log.debug("Writing machine account {0} to {1}".format(auth[1], path))
fl.writelines("\naccount {0}\n".format(auth[1]))
# macro content
for macro, commands in content["macros"].iteritems():
log.debug("Writing macro {0} to {1}".format(macro, path))
fl.writelines("\nmacdef {0}\n".format(macro))
fl.writelines(commands)
# 0600 permissions are required for netrc
# TODO: Fix this for windows
os.chmod(path, 0600)
log.debug("Changed {0} permissions to 0600".format(path))
except Exception, e:
log.error(e)
raise Exception(e)
def update(self, machines):
"""
Update netrc content
"""
if self.machine.lower() in machines.keys():
machines[self.machine] = (self.login,
machines[self.machine][1], self.password)
log.debug("Updated netrc machine {0} with login {1}".format(
self.machine, self.login))
else:
machines[self.machine] = (self.login, None, self.password)
log.debug("Added new netrc machine {0} with login {1}".format(
self.machine, self.login))
return machines
def get(self, path=""):
"""
Get netrc content
"""
try:
auth = netrc.netrc(path)
log.debug("Read netrc from location {0}".format(path))
return auth.hosts, auth.macros
except IOError:
log.debug("{0} file missing, will be created automatically".format(path))
return dict(), dict()
except Exception, e:
message = "{0} {1}".format(path, e)
log.error(message)
raise Exception(message)
if __name__ == "__main__":
# craete client
netrc_instance = NetRc(
"product.company.com",
login="username",
password="password",
account="", # account is optional
)
netrc_instance.create_or_update(NETRC_FILE_PATH)