diff --git a/logman.py b/logman.py
deleted file mode 100755
index 05ca191..0000000
--- a/logman.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/env python
-
-from subprocess import call
-import sys
-import subprocess
-import dbus
-import string
-import socket
-import os
-import fcntl
-import time
-import glib
-import gobject
-import dbus.service
-import dbus.mainloop.glib
-
-DBUS_NAME = 'org.openbmc.LogManager'
-ERRL_INTF_NAME = 'org.openbmc.Errl'
-SRVC_INTF_NAME = 'org.openbmc.Service'
-OBJ_NAME_RSYSLOG = '/org/openbmc/LogManager/rsyslog'
-
-'''
-    Object Path > /org/openbmc/LogManager/rsyslog
-        Interface:Method > org.openbmc.Service.Enable dict:string:string
-        Interface:Method > org.openbmc.Service.Disable
-'''
-
-class JournalUtils ():
-    def _isvalidip(self, family, ipaddr):
-        if family == socket.AF_INET:
-            try:
-                socket.inet_pton(socket.AF_INET, ipaddr)
-            except AttributeError:  # no inet_pton here, sorry
-                try:
-                    socket.inet_aton(ipaddr)
-                except socket.error:
-                    return False
-                return ipaddr.count('.') == 3
-            except socket.error:  # not a valid address
-                return False
-
-            return True
-
-        elif family == socket.AF_INET6:
-            try:
-                socket.inet_pton(socket.AF_INET6, ipaddr)
-            except socket.error:  # not a valid address
-                return False
-            return True
-
-        else: return False
-
-class Rsyslog (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    @dbus.service.method(dbus.PROPERTIES_IFACE, "ss", "v")
-    def Get(self, iface, ppty):
-        return self.GetAll(iface)[ppty]
-
-    @dbus.service.method(dbus.PROPERTIES_IFACE, 's', 'a{sv}')
-    def GetAll(self, iface):
-        if iface == ERRL_INTF_NAME:
-            status, remote_ip, remote_port = self.Status()
-            return {'status': status, 'ipaddr': remote_ip, 'port': remote_port }
-        else:
-            raise dbus.exceptions.DBusException('org.openbmc.UnknownInterface',
-                                'This object does not implement the %s interface' % iface)
-
-    @dbus.service.method(SRVC_INTF_NAME, "a{sv}", "x")
-    def Enable (self, argv_dict):
-        remote_ip = ""
-        remote_port = 0
-
-        params = len (argv_dict)
-        if params > 2 : ValueError("Invalid Parameters")
-
-        for property_name in argv_dict:
-            if property_name == "ipaddr":
-                remote_ip = argv_dict [property_name]
-            elif property_name == "port":
-                remote_port = argv_dict [property_name]
-            else: 
-                raise ValueError("Invalid Argument: IP Address/Port expected.")
-
-        if not remote_ip: 
-            cur_remote = self._GetConfig ('Remote')
-            if not cur_remote: 
-                raise ValueError("Invalid Remote Syslog IP Address")
-            else:
-                cur_remote = cur_remote[3:]
-                remote_ip, port_str = cur_remote.split (":")
-                remote_port = int(port_str)
-        if not util._isvalidip (socket.AF_INET, remote_ip): raise ValueError, "Malformed IP Address"
-        if not remote_port : remote_port = 514
-        if remote_port > 65535 : raise ValueError("Invalid Remote Syslog Port")
-        
-        remote_addr = remote_ip + ":" + str(remote_port)
-        r = self._ModifyService('Remote', remote_addr)
-
-        cur_options = self._GetConfig ('Options')
-        new_options = self._GetOptions()
-
-        if cur_options != new_options:
-            r = self._ModifyService('Options', new_options)
-            r = self._RestartService ()
-
-        return r
-
-    @dbus.service.method(SRVC_INTF_NAME, "as", "x")
-    def Disable (self, argv_list):
-        params = len (argv_list)
-        if params : ValueError("Invalid Parameters")
-
-        remote = self._GetConfig ('Remote')
-        if not remote : return 0
-
-        r = self._ModifyService('Options', '-C') # FIXME: Restore current options minus the remote.
-        r = self._RestartService ()
-        return r
-
-    def Status (self):
-        remote = self._GetConfig ('Remote')
-        if not remote : return ("Disabled", "0.0.0.0", 0)
-
-        cur_remote = remote[3:]
-        remote_ip, remote_port = cur_remote.split (":")
-        
-        options = self._GetConfig ('Options')
-        if not options : return ("Disabled", remote_ip, remote_port)
-
-        if remote in options : return ("Enabled", remote_ip, remote_port)
-
-        return ("Disabled", remote_ip, remote_port)
-
-    def _ModifyService (self, opt, val):
-        if not os.path.isfile(syslog_service_bbx_file):
-            r = call (["cp", syslog_service_lib_file, syslog_service_bbx_file])
-            r = call (["ln", "-s", syslog_service_bbx_file, syslog_service_cfg_file])
-
-        if not os.path.isfile(syslog_service_env_file):
-            env_file = open(syslog_service_env_file, 'w')
-            env_file.write ("OPTIONS=\"-C\"")
-            env_file.close()
-
-        if opt not in OptionKeys: raise ValueError("Invalid Option")
-
-        self._ModifyParam (opt, val)
-
-        return 0
-
-    def _StopService (self):
-        r = call (["systemctl", "stop", "syslog"])
-        r = call (["systemctl", "--no-reload", "kill", "syslog"])
-        return r
-
-    def _StartService (self):
-        r = call (["systemctl", "daemon-reload"])
-        r = call (["systemctl", "start", "syslog"])
-        return r
-
-    def _RestartService (self):
-        r = self._StopService()
-        r = self._StartService()
-        return r
-    
-    def _ModifyParam (self, opt, val):
-        env_file = open(syslog_service_env_file, 'r') 
-        tmp_file = open(syslog_service_tmp_file, 'w')
-
-        optkey = OptionKeySwitchMap [opt]['key']
-        for line in env_file:
-            if line[0] == '#': 
-                tmp_file.write(line)
-                continue
-            curkey = line.strip().split ("=")[0]
-            if curkey != optkey : 
-                tmp_file.write(line)
-
-        tmp_file.write(optkey + "=\""  + OptionKeySwitchMap[opt]['switch'] + val + "\"" + "\n")
-
-        env_file.close ()
-        tmp_file.close ()
-
-        r = call (["cp", syslog_service_tmp_file, syslog_service_env_file])
-        return r
-
-    def _GetConfig (self, opt):
-        with open(syslog_service_env_file, "r") as f:
-            for line in f:
-                if line[0] == '#': continue
-                config = line.split ("=")
-                var = config [0]
-                if var == OptionKeySwitchMap[opt]['key']:
-                    val = config [1]
-                    val = val[1:-2] # FIXME: Why is there a trailing space ???
-                    return val
-        return ""
-
-    def _GetOptions(self):
-        cfg = {}
-        i = 0
-
-        for opt in OptionKeys:
-            if opt == 'Options' : continue
-            cfg [i] = self._GetConfig(opt)
-            i+=1
-            
-        options = ''
-        j = 0
-        while j<i-1:
-            if cfg[j] : options += cfg [j]
-            j+=1
-
-        return options
-
-def main():
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus()
-    name = dbus.service.BusName(DBUS_NAME, bus)
-
-    global util
-    global rsys
-    global syslog_service_lib_file
-    global syslog_service_bbx_file
-    global syslog_service_cfg_file
-    global syslog_service_env_file
-    global syslog_service_tmp_file
-    global OptionKeys
-    global OptionKeySwitchMap
-
-    OptionKeys = ['Options', 'Outfile', 'Priority', 'Smaller', 'RotateSize', 'RotateNum', 'Remote', 'LocalAndNet', 'DropDup', 'SharedMem', 'ConfFile', 'MarkTime', 'Printk']
-    OptionKeySwitchMap = {
-        'Options'       : { 'switch' : "",    'key' : "OPTIONS" },
-        'Outfile'       : { 'switch' : "-O ", 'key' : "OBMC_SYSLOG_OUTFILE" },
-        'Priority'      : { 'switch' : "-O ", 'key' : "OBMC_SYSLOG_PRIORITY" },
-        'Smaller'       : { 'switch' : "-S ", 'key' : "OBMC_SYSLOG_SMALLER" },
-        'RotateSize'    : { 'switch' : "-s ", 'key' : "OBMC_SYSLOG_ROTATESIZE" },
-        'RotateNum'     : { 'switch' : "-b ", 'key' : "OBMC_SYSLOG_ROTATENUM" },
-        'Remote'        : { 'switch' : "-R ", 'key' : "OBMC_SYSLOG_REMOTE" },
-        'LocalAndNet'   : { 'switch' : "-L ", 'key' : "OBMC_SYSLOG_LOCALNET" },
-        'DropDup'       : { 'switch' : "-D ", 'key' : "OBMC_SYSLOG_DROPDUP" },
-        'SharedMem'     : { 'switch' : "-C ", 'key' : "OBMC_SYSLOG_SHAREDMEM" },
-        'ConfFile'      : { 'switch' : "-f ", 'key' : "OBMC_SYSLOG_CONFFILE" },
-        'MarkTime'      : { 'switch' : "-m ", 'key' : "OBMC_SYSLOG_MARKTIME" },
-        'Printk'        : { 'switch' : "-K ", 'key' : "OBMC_SYSLOG_PRINTK" }
-    }
-
-    syslog_service_lib_file = '/lib/systemd/system/busybox-syslog.service'
-    syslog_service_bbx_file = '/etc/systemd/system/busybox-syslog.service'
-    syslog_service_cfg_file = '/etc/systemd/system/syslog.service'
-    syslog_service_env_file = '/etc/default/busybox-syslog'
-    syslog_service_tmp_file = '/tmp/busybox-syslog.tmp'
-
-    util    = JournalUtils ()
-    rsys    = Rsyslog (bus, OBJ_NAME_RSYSLOG)
-
-    mainloop = gobject.MainLoop()
-    print("Started")
-    mainloop.run()
-
-if __name__ == '__main__':
-    sys.exit(main())
-
diff --git a/netman.py b/netman.py
deleted file mode 100755
index e419ab6..0000000
--- a/netman.py
+++ /dev/null
@@ -1,513 +0,0 @@
-#!/usr/bin/env python
-
-from subprocess import call, Popen, PIPE
-from IPy import IP
-import sys
-import subprocess
-import dbus
-import string
-import socket
-import re
-import os
-import fcntl
-import glib
-import gobject
-import dbus.service
-import dbus.mainloop.glib
-from ConfigParser import SafeConfigParser
-import glob
-import obmc.mapper
-
-#MAC address mask for locally administered.
-MAC_LOCAL_ADMIN_MASK = 0x20000000000
-BROADCAST_MAC = 0xFFFFFFFFFFFF
-DBUS_NAME = 'org.openbmc.NetworkManager'
-OBJ_NAME = '/org/openbmc/NetworkManager/Interface'
-INV_INTF_NAME = 'xyz.openbmc_project.Inventory.Item.NetworkInterface'
-INVENTORY_ROOT = '/xyz/openbmc_project/inventory'
-MAC_PROPERTY = 'MACAddress'
-
-network_providers = {
-    'networkd' : {
-        'bus_name' : 'org.freedesktop.network1',
-        'ip_object_name' : '/org/freedesktop/network1/network/default',
-        'hw_object_name' : '/org/freedesktop/network1/link/_31',
-        'ip_if_name' : 'org.freedesktop.network1.Network',
-        'hw_if_name' : 'org.freedesktop.network1.Link',
-        'method' : 'org.freedesktop.network1.Network.SetAddr'
-    },
-    'NetworkManager' : {
-        'bus_name' : 'org.freedesktop.NetworkManager',
-        'ip_object_name' : '/org/freedesktop/NetworkManager',
-        'hw_object_name' : '/org/freedesktop/NetworkManager',
-        'ip_if_name' : 'org.freedesktop.NetworkManager',
-        'hw_if_name' : 'org.freedesktop.NetworkManager',
-        'method' : 'org.freedesktop.NetworkManager' # FIXME: 
-    },  
-}
-
-def getPrefixLen(mask):
-    prefixLen = sum([bin(int(x)).count('1') for x in mask.split('.')])
-    return prefixLen
-
-# Enable / Disable the UseDHCP setting in .network file
-def modifyNetConfig(confFile, usentp):
-    parser = SafeConfigParser()
-    parser.optionxform = str
-    parser.read(confFile)
-    sections = parser.sections()
-
-    if "Match" not in sections:
-        raise NameError, "[Match] section not found"
-
-    interface = parser.get('Match', 'Name')
-    if interface == '':
-        raise NameError, "Invalid interface"
-
-    if "DHCP" not in sections:
-        parser.add_section("DHCP")
-    if usentp.lower() == "yes":
-        parser.set('DHCP', 'UseNTP', "true")
-    elif usentp.lower() == "no":
-        parser.set('DHCP', 'UseNTP', "false")
-
-    print "Updating" + confFile + '\n'
-    with open(confFile, 'wb') as configfile:
-        parser.write(configfile)
-
-    rc = call(["ip", "addr", "flush", interface])
-    rc = call(["systemctl", "restart", "systemd-networkd.service"])
-    rc = call(["systemctl", "try-restart", "systemd-timesyncd.service"])
-    return rc
-
-
-# Get Mac address from the eeprom
-def get_mac_from_eeprom():
-    bus = dbus.SystemBus()
-    mapper = obmc.mapper.Mapper(bus)
-
-    # Get the inventory subtree, limited
-    # to objects that implement NetworkInterface.
-    for path, info in \
-        mapper.get_subtree(
-            path=INVENTORY_ROOT,
-            interfaces=[INV_INTF_NAME]).iteritems():
-            # Find a NetworkInterface with 'bmc' in the path.
-            if 'bmc' not in path:
-                continue
-
-            # Only expecting a single service to implement
-            # NetworkInterface.  Get the service connection
-            # from the mapper response
-            conn = info.keys()[0]
-
-            # Get the inventory object implementing NetworkInterface.
-            obj = bus.get_object(conn, path)
-
-            # Get the MAC address
-            mproxy = obj.get_dbus_method('Get', dbus.PROPERTIES_IFACE)
-            return mproxy(INV_INTF_NAME, MAC_PROPERTY)
-
-class IfAddr ():
-    def __init__ (self, family, scope, flags, prefixlen, addr, gw):
-        self.family     = family
-        self.scope      = scope
-        self.flags      = flags
-        self.prefixlen  = prefixlen
-        self.addr       = addr
-        self.gw         = gw
-
-class NetMan (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    def setNetworkProvider(self, provider):
-        self.provider = provider
-
-    def _isvaliddev(self, device):
-        devices = os.listdir ("/sys/class/net")
-        if not device in devices : return False
-        else: return True
-
-    def _ishwdev (self, device):
-        f = open ("/sys/class/net/"+device+"/type")
-        type = f.read()
-        return False if (int(type) ==  772) else True
-
-    def _isvalidmask (self, mask):
-        for x in mask.split('.'):
-            try:
-                y = int(x)
-            except:
-                return False
-            if y > 255: return False
-        return mask.count('.') == 3
-
-    def validatemac(self, mac):
-        macre = '([a-fA-F0-9]{2}[:|\-]?){6}'
-        if re.compile(macre).search(mac) is None:
-            raise ValueError("Malformed MAC address")
-
-        # Don't allow Broadcast or global unique mac
-        int_mac = int(mac.replace(":", ""), 16)
-        if not (int_mac ^ BROADCAST_MAC):
-            raise ValueError("Given Mac is BroadCast Mac Address")
-
-        if not int_mac & MAC_LOCAL_ADMIN_MASK:
-            eep_mac = get_mac_from_eeprom()
-            if eep_mac:
-                int_eep_mac = int(eep_mac, 16)
-                if int_eep_mac != int_mac:
-                    raise ValueError("Given MAC address is neither a local Admin type \
-                                   nor is same as in eeprom")
-
-
-    def _isvalidipv4(self, ipstr, netmask):
-        ip_parts = ipstr.split(".")
-        if len(ip_parts) != 4:
-            return "Malformed"
-
-        first, second, third, fourth = [int(part) for part in ip_parts]
-        if first == 0 and second == 0 and third == 0 and fourth == 0:
-            return "Invalid" 	# "this" network disallowed
-        if first == 169 and second == 254:
-            return "Link Local"
-        if first >= 224:
-            return "Invalid"	# class D multicast and class E disallowed
-        if first == 192 and second == 88 and third == 99:
-            return "Invalid"	# ipv6 relay
-
-        # check validity against netmask
-        if netmask != '0':
-            ip_bin = (first << 24) + (second << 16) + (third << 8) + fourth
-            mask_parts = netmask.split(".")
-            if len(mask_parts) == 4:	# long form netmask
-                mask_bin = (int(mask_parts[0]) << 24) + (int(mask_parts[1]) << 16) + (int(mask_parts[2]) << 8) + int(mask_parts[3])
-            elif netmask.count(".") == 0:	# short form netmask
-                mask_bin = 0xffffffff ^ (1 << 32 - int(netmask)) - 1
-            else:
-                return "Malformed"	# bad netmask
-
-            if ip_bin & ~mask_bin == 0:
-                return "Invalid"	# disallowed by this netmask
-            if ip_bin | mask_bin == 0xFFFFFFFF:
-                return "Invalid"	# disallowed by this netmask
-
-        return "Valid"
-
-
-    def _isvalidip(self, ipaddr, netmask = '0'):
-        try:
-            ip = IP(ipaddr)
-        except ValueError:
-            return "Malformed"
-
-        ipstr = ip.strNormal(0)
-        ipstr_masked = ip.strNormal(2)
-        if ipstr_masked.count("/") != 0 and netmask == '0':
-            netmask = ipstr_masked.split("/")[1]
-
-        if ip.version() == 4:	# additional checks for ipv4
-            return self._isvalidipv4(ipstr, netmask)
-        # TODO: check ipv6 openbmc/openbmc#496
-
-        return "Valid"
-
-    def _getAddr (self, target, device):
-        netprov     = network_providers [self.provider]
-        bus_name    = netprov ['bus_name']
-
-        if (target == "ip"):
-            ipaddr = ""
-            defgw = ""
-            prefixlen = "0"
-
-            proc = subprocess.Popen(["ip", "addr", "show", "dev", device], stdout=PIPE)
-            procout = proc.communicate()
-            if procout: 
-                ipout = procout[0].splitlines()[2].strip()
-                ipaddr,prefixlen = ipout.split ()[1].split("/")
-
-            proc = subprocess.Popen(["ip", "route", "show", "dev", device, "default", "0.0.0.0/0"], stdout=PIPE)
-            procout = proc.communicate()
-            if procout[0]:
-                ipout = procout[0].splitlines()[0].strip()
-                defgw = ipout.split ()[2]
-
-            return 2, int(prefixlen), ipaddr, defgw
-
-        if (target == "mac"):
-            proc = subprocess.Popen(["ip", "link", "show", "dev", device], stdout=PIPE)
-            ipout = proc.communicate()[0].splitlines()[1].strip()
-            mac = ipout.split ()[1]
-            return mac
-
-    def _checkNetworkForRequiredFields(self, device):
-        parser = SafeConfigParser()
-        parser.optionxform = str
-        parser.read("/etc/systemd/network/00-bmc-" + device + ".network")
-        sections = parser.sections()
-        if "Match" not in sections:
-            parser.add_section("Match")
-            parser.set("Match", "Name", device)
-
-        if "Network" not in sections:
-            parser.add_section("Network")
-
-        if "Link" not in sections:
-            parser.add_section("Link")
-            mac = self._getAddr("mac", device)
-            try:
-                self.validatemac(mac)
-                parser.set("Link", MAC_PROPERTY, mac)
-            except ValueError as e:
-                print("System MAC Address invalid:" + e)
-
-        return parser
-
-    def _upDownNetworkService(self, device, mac=None):
-        print "Restarting networkd service..."
-        subprocess.check_call(["ip", "link", "set", "dev", device, "down"])
-        if mac is not None:
-            subprocess.check_call(["fw_setenv", "ethaddr", mac])
-            subprocess.check_call(
-                ["ip", "link", "set", "dev", device, "address", mac])
-
-        subprocess.check_call(
-            ["systemctl", "restart", "systemd-networkd.service"])
-
-        return 0
-
-    @dbus.service.method(DBUS_NAME, "sas", "x")
-    def SetNtpServer (self, device, ntpservers):
-        if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
-
-        # Convert the array into space separated value string
-        ntp_ip = " ".join(ntpservers)
-        if not ntp_ip : raise ValueError, "Invalid Data"
-
-        confFile = "/etc/systemd/network/00-bmc-" + device + ".network"
-
-        parser = SafeConfigParser()
-        parser.optionxform = str
-        parser.read(confFile)
-        sections = parser.sections()
-        if "Match" not in sections:
-            raise NameError, "[Match] section not found"
-
-        interface = parser.get('Match', 'Name')
-        if interface != device:
-            raise ValueError, "Device [" + device + "] Not Configured"
-
-        if "Network" not in sections:
-            raise NameError, "[Network] section not found"
-
-        parser.set('Network', 'NTP', ntp_ip)
-        print "Updating " + confFile + '\n'
-        with open(confFile, 'wb') as configfile:
-            parser.write(configfile)
-        rc = call(["ip", "addr", "flush", device])
-        rc = call(["systemctl", "restart", "systemd-networkd.service"])
-        rc = call(["systemctl", "try-restart", "systemd-timesyncd.service"])
-        return rc
-
-    @dbus.service.method(DBUS_NAME, "s", "x")
-    def UpdateUseNtpField (self, usentp):
-        filelist = glob.glob("/etc/systemd/network/*.network")
-        for configfile in filelist:
-            modifyNetConfig(configfile,usentp)
-        return 0
-
-    @dbus.service.method(DBUS_NAME, "s", "x")
-    def EnableDHCP(self, device):
-        if not self._isvaliddev(device):
-            raise ValueError("Invalid Device")
-        parser = self._checkNetworkForRequiredFields(device)
-        parser.set("Network", "DHCP", "yes")
-
-        if "DHCP" not in parser.sections():
-            parser.add_section("DHCP")
-        parser.set("DHCP", "ClientIdentifier", "mac")
-
-        # Write to config file
-        with open("/etc/systemd/network/00-bmc-" + device + ".network", 'w') \
-                as configfile:
-            parser.write(configfile)
-
-        return (subprocess.check_call(
-            ["systemctl", "restart", "systemd-networkd.service"]))
-
-    @dbus.service.method(DBUS_NAME, "ssss", "x")
-    def SetAddress4(self, device, ipaddr, netmask, gateway):
-        if not self._isvaliddev(device): raise ValueError, "Invalid Device"
-        if not self._isvalidmask(netmask): raise ValueError, "Invalid Mask"
-        prefixLen = getPrefixLen(netmask)
-        if prefixLen == 0: raise ValueError, "Invalid Mask"
-        valid = self._isvalidip(ipaddr, netmask)
-        if valid != "Valid": raise ValueError, valid + " IP Address"
-        valid = self._isvalidip(gateway)
-        if valid != "Valid": raise ValueError, valid + " IP Address"
-
-        parser = self._checkNetworkForRequiredFields(device)
-        parser.set("Network", "DHCP", "no")
-        parser.set("Network", "Address", '{}/{}'.format(ipaddr, prefixLen))
-        parser.set("Network", "Gateway", gateway)
-        with open("/etc/systemd/network/00-bmc-" + device + ".network", 'w') \
-                as configfile:
-            parser.write(configfile)
-
-        return (subprocess.check_call(
-            ["systemctl", "restart", "systemd-networkd.service"]))
-
-    @dbus.service.method(DBUS_NAME, "s", "s")
-    def GetAddressType (self, device):
-        if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
-
-        confFile = "/etc/systemd/network/00-bmc-" + device + ".network"
-        if not os.path.exists(confFile): 
-            print "Config file (%s) not found !" % confFile
-            netprov     = network_providers [self.provider]
-            bus_name    = netprov ['bus_name']
-            obj_name    = netprov ['ip_object_name']
-            o = self.bus.get_object(bus_name, obj_name, introspect=False)
-            i = dbus.Interface(o, 'org.freedesktop.DBus.Properties')
-            f = i.Get (netprov ['ip_if_name'], "SourcePath")
-            print "Using default networkd config file (%s)" % f
-            confFile = f
-
-        parser = self._checkNetworkForRequiredFields(device)
-
-        if parser.has_option("Network", "DHCP") is True:
-            mode = parser.get("Network", "DHCP")
-        else:
-            return "Unknown"
-
-        setting = {
-            'yes': 'DHCP',
-            'true': 'DHCP',
-            'no': 'STATIC'
-        }
-        setting.get(mode.lower(), "Unknown")
-
-        return setting
-
-    #family, prefixlen, ip, defgw
-    @dbus.service.method(DBUS_NAME, "s", "iyss")
-    def GetAddress4 (self, device):
-        if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
-        return self._getAddr ("ip", device)
-
-    @dbus.service.method(DBUS_NAME, "s", "s")
-    def GetHwAddress (self, device):
-        if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
-        return self._getAddr ("mac", device)
-
-    @dbus.service.method(DBUS_NAME, "ss", "i")
-    def SetHwAddress (self, device, mac):
-        if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
-        if not self._ishwdev (device) : raise ValueError, "Not a Hardware Device"
-
-        self.validatemac(mac)
-
-        parser = self._checkNetworkForRequiredFields(device)
-        parser.set("Link", MAC_PROPERTY, mac)
-        with open("/etc/systemd/network/00-bmc-" + device + ".network", 'w') as configfile:
-            parser.write(configfile)
-
-        rc = subprocess.call(["fw_setenv", "ethaddr", mac])
-
-        print("Restarting networkd service...")
-        rc = call(["ip", "link", "set", "dev", device, "down"])
-        rc = call(["ip", "link", "set", "dev", device, "address", mac])
-        rc = call(["ip", "link", "set", "dev", device, "up"])
-
-        rc = call(["systemctl", "restart", "systemd-networkd.service"])
-        return rc
-
-    #string of nameservers
-    @dbus.service.method(DBUS_NAME,"s", "s")
-    def SetNameServers (self, nameservers):
-        dns_entry = nameservers.split()
-        fail_msg = ''
-        dhcp_auto = False
-        file_opened = False
-        if len(dns_entry) > 0:
-            for dns in dns_entry:
-                valid = self._isvalidip (dns)
-                if valid != "Valid":
-                    if dns == "DHCP_AUTO=":
-                        #This DNS is supplied by DHCP.
-                        dhcp_auto = True
-                    else:
-                        print valid + " DNS Address [" + dns + "]"
-                        fail_msg = fail_msg + '[' + dns + ']'
-                else:
-                    #Only over write on a first valid input
-                    if file_opened == False:
-                        resolv_conf = open("/etc/resolv.conf",'w')
-                        file_opened = True
-                        if dhcp_auto == True:
-                            resolv_conf.write("### Generated automatically via DHCP ###\n")
-                        else:
-                            resolv_conf.write("### Generated manually via dbus settings ###\n")
-                    dns_ip = 'nameserver ' + dns + '\n'
-                    resolv_conf.write(dns_ip)
-            if file_opened == True:
-                resolv_conf.close()
-        else:
-            raise ValueError, "Invalid DNS entry"
-        if len(fail_msg) > 0:
-            return 'Failures encountered processing' + fail_msg
-        else:
-            return "DNS entries updated Successfully"
-
-    @dbus.service.method(DBUS_NAME, "s", "x")
-    def SetHostname(self, hostname):
-        subprocess.check_call(["hostnamectl", "set-hostname", hostname])
-        subprocess.check_call(
-            ["systemctl", "restart", "systemd-networkd.service"])
-        return 0
-
-    @dbus.service.method(DBUS_NAME, "", "s")
-    def GetHostname(self):
-        value = subprocess.check_output("hostname")
-        return value.rstrip()
-
-    @dbus.service.method(DBUS_NAME, "ss", "x")
-    def SetGateway(self, device, gateway):
-        if not self._isvaliddev(device):
-            raise ValueError("Invalid Device")
-        valid = self._isvalidip(gateway)
-        if valid != "Valid":
-            raise ValueError(valid + " IP Address")
-        parser = self._checkNetworkForRequiredFields(device)
-        if "no" not in parser.get("Network", "DHCP"):
-            raise EnvironmentError("DHCP is on")
-        parser.set("Network", "Gateway", gateway)
-        with open("/etc/systemd/network/00-bmc-" + device + ".network", 'w') \
-                as configfile:
-            parser.write(configfile)
-        return (subprocess.check_call(
-            ["systemctl", "restart", "systemd-networkd.service"]))
-
-    @dbus.service.method(DBUS_NAME, "s", "s")
-    def GetGateway(self, device):
-        if not self._isvaliddev(device):
-            raise ValueError("Invalid Device")
-        return self._getAddr("ip", device)[3]
-
-
-def main():
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus()
-    name = dbus.service.BusName(DBUS_NAME, bus)
-    obj = NetMan (bus, OBJ_NAME)
-    obj.setNetworkProvider ("networkd")
-    mainloop = gobject.MainLoop()
-    print("Started")
-    mainloop.run()
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/userman.py b/userman.py
deleted file mode 100644
index 69f5e95..0000000
--- a/userman.py
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/usr/bin/env python
-
-from subprocess import call
-import sys
-import subprocess
-import dbus
-import string
-import os
-import fcntl
-import time
-import pexpect
-import glib
-import gobject
-import dbus.service
-import dbus.mainloop.glib
-
-DBUS_NAME = 'org.openbmc.UserManager'
-INTF_NAME = 'org.openbmc.Enrol'
-OBJ_NAME_GROUPS = '/org/openbmc/UserManager/Groups'
-OBJ_NAME_GROUP = '/org/openbmc/UserManager/Group'
-OBJ_NAME_USERS = '/org/openbmc/UserManager/Users'
-OBJ_NAME_USER = '/org/openbmc/UserManager/User'
-
-'''
-    Object Path > /org/openbmc/UserManager/Groups
-        Interface:Method > org.openbmc.Enrol.GroupAddSys string:"groupname"
-        Interface:Method > org.openbmc.Enrol.GroupAddUsr string:"groupname"
-        Interface:Method > org.openbmc.Enrol.GroupListUsr
-        Interface:Method > org.openbmc.Enrol.GroupListSys
-    Object Path > /org/openbmc/UserManager/Group
-        Interface:Method > org.openbmc.Enrol.GroupDel string:"groupname"
-    Object Path > /org/openbmc/UserManager/Users
-       Interface:Method > org.openbmc.Enrol.UserAdd string:"comment" string:"username" string:"groupname" string:"passwd"
-        Interface:Method > org.openbmc.Enrol.UserList
-    Object Path > /org/openbmc/UserManager/User
-        Interface:Method > org.openbmc.Enrol.UserDel string:"username"
-        Interface:Method > org.openbmc.Enrol.Passswd string:"username" string:"passwd"
-'''
-
-userman_providers = {
-    'pam' : {
-        'adduser' : 'user add',
-    },
-    'ldap' : {
-        'adduser' : 'ldap command to add user',
-    },
-}
-
-class UserManGroups (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    def setUsermanProvider(self, provider):
-        self.provider = provider
-
-    @dbus.service.method(INTF_NAME, "", "")
-    def test(self):
-        print("TEST")
-
-    @dbus.service.method(INTF_NAME, "s", "x")
-    def GroupAddUsr (self, groupname):
-        if not groupname : raise ValueError("Invalid Groupname")
-
-        groups = self.GroupListAll ()
-        if groupname in groups: raise ValueError("Group ", groupname, " Exists")
-
-        r = call (["addgroup", groupname])
-        return r
-
-    #@dbus.service.method(INTF_NAME, "s", "x")
-    def GroupAddSys (self, groupname):
-        if not groupname : raise ValueError("Invalid Groupname")
-
-        groups = self.GroupListAll ()
-        if groupname in groups: raise ValueError("Group ", groupname, " Exists")
-
-        r = call (["addgroup", "-S", groupname])
-        return r
-
-    @dbus.service.method(INTF_NAME, "", "as")
-    def GroupListUsr (self):
-        groupList = []
-        with open("/etc/group", "r") as f:
-            for grent in f:
-                groupParams = grent.split (":")
-                if (int(groupParams[2]) >= 1000 and int(groupParams[2]) != 65534):
-                    groupList.append(groupParams[0])
-        return groupList
-
-    @dbus.service.method(INTF_NAME, "", "as")
-    def GroupListSys (self):
-        groupList = []
-        with open("/etc/group", "r") as f:
-            for grent in f:
-                groupParams = grent.split (":")
-                if (int(groupParams[2]) > 100 and int(groupParams[2]) < 1000): groupList.append(groupParams[0])
-        return groupList
-
-    def GroupListAll (self):
-        groupList = []
-        with open("/etc/group", "r") as f:
-            for grent in f:
-                groupParams = grent.split (":")
-                groupList.append(groupParams[0])
-        return groupList
-
-class UserManGroup (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    def setUsermanProvider(self, provider):
-        self.provider = provider
-
-    @dbus.service.method(INTF_NAME, "", "")
-    def test(self):
-        print("TEST")
-
-    @dbus.service.method(INTF_NAME, "", "x")
-    def GroupDel (self, groupname):
-        if not groupname : raise ValueError("Invalid Groupname")
-
-        groups = Groupsobj.GroupListAll ()
-        if groupname not in groups: raise ValueError("No such Group: ", groupname)
-
-        r = call (["delgroup", groupname])
-        return r
-
-class UserManUsers (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    def setUsermanProvider(self, provider):
-        self.provider = provider
-
-    @dbus.service.method(INTF_NAME, "", "")
-    def test(self):
-        print("TEST")
-
-    @dbus.service.method(INTF_NAME, "ssss", "x")
-    def UserAdd (self, gecos, username, groupname, passwd):
-        if not username : raise ValueError("Invalid Username")
-
-        users = self.UserListAll ()
-        if username in users : raise ValueError("User ", username, " Exists")
-
-        if groupname:
-            groups = Groupsobj.GroupListAll ()
-            if groupname not in groups: raise ValueError("No such Group: ", groupname)
-
-        opts = ""
-        if gecos: opts = " -g " + '"' + gecos + '"'
-
-        if groupname:
-            cmd = "adduser "  + opts + " " + " -G " + groupname + " " + "-s /bin/sh" + " " + username
-        else:
-            cmd = "adduser "  + opts + " " + "-s /bin/sh" + " " + username
-
-        prompts = ['New password: ', 'Retype password: ', 'Re-enter new password: ']
-        proc = pexpect.spawn (cmd)
-        proc.expect (prompts)
-        proc.sendline (passwd)
-        proc.expect (prompts)
-        proc.sendline (passwd)
-
-        if proc.expect(prompts + [pexpect.EOF]) != len(prompts):
-            proc.sendline (passwd)
-
-        r = proc.wait()
-        return r if r else 0
-
-    @dbus.service.method(INTF_NAME, "", "as")
-    def UserList (self):
-        userList = []
-        with open("/etc/passwd", "r") as f:
-            for usent in f:
-                userParams = usent.split (":")
-                if (int(userParams[2]) >= 1000 and int(userParams[2]) != 65534):
-                    userList.append(userParams[0])
-        return userList
-
-    def UserListAll (self):
-        userList = []
-        with open("/etc/passwd", "r") as f:
-            for usent in f:
-                userParams = usent.split (":")
-                userList.append(userParams[0])
-        return userList
-
-class UserManUser (dbus.service.Object):
-    def __init__(self, bus, name):
-        self.bus = bus
-        self.name = name
-        dbus.service.Object.__init__(self,bus,name)
-
-    @dbus.service.method(INTF_NAME, "", "")
-    def test(self):
-        print("TEST")
-
-    def setUsermanProvider(self, provider):
-        self.provider = provider
-
-    @dbus.service.method(INTF_NAME, "s", "x")
-    def UserDel (self, username):
-        if not username : raise ValueError("Invalid Username")
-
-        users = Usersobj.UserList ()
-        if username not in users : raise ValueError("No such User: ", username)
-
-        r = call (["deluser", username])
-        return r
-
-    @dbus.service.method(INTF_NAME, "ss", "x")
-    def Passwd (self, username, passwd):
-        if not username : raise ValueError("Invalid Username")
-
-        users = Usersobj.UserList ()
-        if username not in users : raise ValueError("No such User: ", username)
-
-        cmd = "passwd" + " " + username
-        prompts = ['New password: ', 'Retype password: ', 'Re-enter new password: ']
-        proc = pexpect.spawn (cmd)
-        proc.expect (prompts)
-        proc.sendline (passwd)
-        proc.expect (prompts)
-        proc.sendline (passwd)
-
-        if proc.expect(prompts + [pexpect.EOF]) != len(prompts):
-            proc.sendline (passwd)
-
-        r = proc.wait()
-        return r if r else 0
-
-def main():
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus()
-    name = dbus.service.BusName(DBUS_NAME, bus)
-
-    global Groupsobj
-    global Groupobj
-    global Usersobj
-    global Userobj
-
-    Groupsobj   = UserManGroups (bus, OBJ_NAME_GROUPS)
-    Groupobj    = UserManGroup  (bus, OBJ_NAME_GROUP)
-    Usersobj    = UserManUsers  (bus, OBJ_NAME_USERS)
-    Userobj     = UserManUser   (bus, OBJ_NAME_USER)
-
-    Groupsobj.setUsermanProvider ("pam")
-    Groupobj.setUsermanProvider ("pam")
-    Usersobj.setUsermanProvider ("pam")
-    Userobj.setUsermanProvider ("pam")
-
-    mainloop = gobject.MainLoop()
-    print("Started")
-    mainloop.run()
-
-if __name__ == '__main__':
-    sys.exit(main())
-
