Skip to content

Commit

Permalink
init repo hostsed
Browse files Browse the repository at this point in the history
  • Loading branch information
socrateslee committed Jun 8, 2016
1 parent 62a5dab commit 0c50da3
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# hostsed -- A tiny hosts file command line edit tool

hostsed is a simple python tool for editing hosts file(/etc/hosts), you can add or delete a DNS entry via command line shell(e.x. bash).


Usage:

```
# Add an entry
sudo hostsed add <ip address> <hostname1> <hostname2> ...
Example:
sudo hostsed add 192.168.1.1 gateway
sudo hostsed add 172.17.0.5 mongo-store-1 mysql-02
# Delete an entry
sudo hosted del <ip address> <hostname>
hosted remove 192.168.1.1 gateway
```
1 change: 1 addition & 0 deletions hosts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

109 changes: 109 additions & 0 deletions hosts/editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'''
Utilities for adding or deleting entries on hosts file
as /etc/hosts.
'''
import os
import sys
import socket
import argparse


def is_valid_ip_address(ip):
'''
Check whether an ip address is valid, both for ipv4
and ipv6.
'''
try:
socket.inet_pton(socket.AF_INET, ip)
return True
except socket.error:
pass

try:
socket.inet_pton(socket.AF_INET, ip)
return True
except socket.error:
pass
return False


def parse_line(line):
pos = line.find("#")
new_line = line[:pos].strip()
if new_line:
parts = map(lambda x: x.strip(), new_line.split())
return (line, parts)
else:
return (line, None)


class HostEditor(object):
def __init__(self, filename='/etc/hosts'):
self.filename = filename
self._parse()

def add(self, ip, *hostnames):
'''
Add an entry to hosts file.
'''
ret = []
added = False
for (line, parts) in self.entries:
if parts and parts[0] == ip and not added:
for hostname in hostnames:
if hostname not in parts[1:]:
parts.append(hostname)
line = ' '.join(['\t'.join(parts), line[line.find('#'):]])
added = True
ret.append((line, parts))
if not added:
parts = [ip] + list(hostnames)
line = '\t'.join(parts)
ret.append((line, parts))
self.entries = ret

def delete(self, ip, hostname):
'''
Delete an entry from hosts file.
'''
if not is_valid_ip_address(ip):
raise Exception("Ip %s is not valid." % ip)
ret = []
for (line, parts) in self.entries:
if parts and parts[0] == ip:
parts = filter(lambda x: x != hostname, parts)
if not parts[1:]:
continue
line = ' '.join(['\t'.join(parts), line[line.find('#'):]])
ret.append((line, parts))
self.entries = ret

def _parse(self):
'''
Parse the files into entries.
'''
self.entries = []
for line in open(self.filename).readlines():
self.entries.append(parse_line(line))

def output(self, fd=None):
if fd is None:
fd = sys.stdout
fd.write('\n'.join(map(lambda x: x[0].strip(), self.entries)))

def write(self):
fd = open(self.filename, 'w')
self.output(fd=fd)
fd.close()


def main():
he = HostEditor()
if len(sys.argv) >= 4 and sys.argv[1] == 'add':
he.add(sys.argv[2], *sys.argv[3:])
he.write()
elif len(sys.argv) == 4 and sys.argv[1] in ('rm', 'remove',
'del', 'delete'):
he.delete(sys.argv[2], sys.argv[3])
he.write()
he.output()
5 changes: 5 additions & 0 deletions hostsed
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python
import hosts.editor

if __name__ == '__main__':
hosts.editor.main()
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[metadata]
description-file = README.md
21 changes: 21 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python

sdict = {
'name': 'hostsed',
'version': "0.1.0",
'packages': ['hosts'],
'zip_safe': False,
'author': 'lichun',
'scripts': ['hostsed'],
'classifiers': [
'Environment :: Console',
'Intended Audience :: Developers',
'Programming Language :: Python']
}

try:
from setuptools import setup
except ImportError:
from distutils.core import setup

setup(**sdict)

0 comments on commit 0c50da3

Please sign in to comment.