-
-
Save rmorlang/7225451 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
class HoverException(Exception): | |
pass | |
class HoverAPI(object): | |
def __init__(self, username, password): | |
params = {"username": username, "password": password} | |
r = requests.post("https://www.hover.com/api/login", params=params) | |
if not r.ok or "hoverauth" not in r.cookies: | |
raise HoverException(r) | |
self.cookies = {"hoverauth": r.cookies["hoverauth"]} | |
def call(self, method, resource, data=None): | |
url = "https://www.hover.com/api/{0}".format(resource) | |
r = requests.request(method, url, data=data, cookies=self.cookies) | |
if not r.ok: | |
raise HoverException(r) | |
if r.content: | |
body = r.json() | |
if "succeeded" not in body or body["succeeded"] is not True: | |
raise HoverException(body) | |
return body | |
# connect to the API using your account | |
client = HoverAPI("myusername", "mypassword") | |
# get details of a domains without DNS records | |
client.call("get", "domains") | |
# get all domains and DNS records | |
client.call("get", "dns") | |
# notice the "id" field of domains in response to the above calls - that's needed | |
# to address the domains individually, like so: | |
# get details of a specific domain without DNS records | |
client.call("get", "domains/dom123456") | |
# get DNS records of a specific domain: | |
client.call("get", "domains/dom123456/dns") | |
# create a new A record: | |
record = {"name": "mysubdomain", "type": "A", "content": "127.0.0.1"} | |
client.call("post", "domains/dom123456/dns", record) | |
# create a new SRV record | |
# note that content is "{priority} {weight} {port} {target}" | |
record = {"name": "mysubdomain", "type": "SRV", "content": "10 10 123 __service"} | |
client.call("post", "domains/dom123456/dns", record) | |
# create a new MX record | |
# note that content is "{priority} {host}" | |
record = {"name": "mysubdomain", "type": "MX", "content": "10 mail"} | |
client.call("post", "domains/dom123456/dns", record) | |
# notice the "id" field of DNS records in the above calls - that's | |
# needed to address the DNS records individually, like so: | |
# update an existing DNS record | |
client.call("put", "dns/dns1234567", {"content": "127.0.0.1"}) | |
# delete a DNS record: | |
client.call("delete", "dns/dns1234567") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import ConfigParser | |
import requests | |
import optparse | |
import sys | |
# This is a command-line script to import and export DNS records for a | |
# single domain into or out of a hover account. Run it like so: | |
# ./bulkhover.py -u USERNAME -p PASSWORD (import|export) DOMAIN DNS_FILE | |
# or create a config file like this: | |
# | |
# [hover] | |
# username=USERNAME | |
# password=PASSWORD | |
# | |
# and run it like this: | |
# ./bulkhover.py -c PATH_TO_CONF (import|export) DOMAIN DNS_FILE | |
# | |
# The DNS file should have one record per line, in the format: | |
# {name} {type} {content} | |
# | |
# For example: | |
# | |
# www A 127.0.0.1 | |
# @ MX 10 example.com | |
# | |
# You can even copy the entire contents of one domain to another, like so: | |
# ./bulkhover.py -c CONF export example.com - | ./bulkhover.py -c CONF -f import other.com - | |
class HoverException(Exception): | |
pass | |
class HoverAPI(object): | |
def __init__(self, username, password): | |
params = {"username": username, "password": password} | |
r = requests.post("https://www.hover.com/api/login", params=params) | |
if not r.ok or "hoverauth" not in r.cookies: | |
raise HoverException(r) | |
self.cookies = {"hoverauth": r.cookies["hoverauth"]} | |
def call(self, method, resource, data=None): | |
url = "https://www.hover.com/api/{0}".format(resource) | |
r = requests.request(method, url, data=data, cookies=self.cookies) | |
if not r.ok: | |
raise HoverException(r) | |
if r.content: | |
body = r.json() | |
if "succeeded" not in body or body["succeeded"] is not True: | |
raise HoverException(body) | |
return body | |
def import_dns(username, password, domain, filename, flush=False): | |
try: | |
client = HoverAPI(username, password) | |
except HoverException as e: | |
raise HoverException("Authentication failed") | |
if flush: | |
records = client.call("get", "domains/{0}/dns".format(domain))["domains"][0]["entries"] | |
for record in records: | |
client.call("delete", "dns/{0}".format(record["id"])) | |
print "Deleted {name} {type} {content}".format(**record) | |
domain_id = client.call("get", "domains/{0}".format(domain))["domain"]["id"] | |
if filename == "-": filename = "/dev/stdin" | |
with open(filename, "r") as f: | |
for line in f: | |
parts = line.strip().split(" ", 2) | |
record = {"name": parts[0], "type": parts[1], "content": parts[2]} | |
client.call("post", "domains/{0}/dns".format(domain), record) | |
print "Created {name} {type} {content}".format(**record) | |
def export_dns(username, password, domain, filename): | |
try: | |
client = HoverAPI(username, password) | |
except HoverException as e: | |
raise HoverException("Authentication failed") | |
records = client.call("get", "domains/{0}/dns".format(domain))["domains"][0]["entries"] | |
if filename == "-": filename = "/dev/stdout" | |
with open(filename, "w") as f: | |
for record in records: | |
f.write("{name} {type} {content}\n".format(**record)) | |
def main(): | |
usage = "usage: %prog (-c CONF|-u USERNAME -p PASSWORD) (import|export) DOMAIN DNS_FILE" | |
description = "Import or export DNS records for a single domain in a hover account." | |
parser = optparse.OptionParser(usage=usage, description=description) | |
parser.add_option("-c", "--conf", default=None, help="The conf file that contains your username and password") | |
parser.add_option("-u", "--username", default=None, help="Your hover.com username") | |
parser.add_option("-p", "--password", default=None, help="Your hover.com password") | |
parser.add_option("-f", "--flush", default=False, action="store_true", help="Flush all DNS records associated with the domain before importing") | |
(options, args) = parser.parse_args() | |
if len(args) < 3: | |
parser.error("You must specify an operation, a domain, and a file") | |
operation, domain, filename = args | |
if operation not in ("import", "export"): | |
parser.error("Invalid operation: {0} - Valid operations are import and export".format(operation)) | |
def get_conf(filename): | |
config = ConfigParser.ConfigParser() | |
config.read(filename) | |
items = dict(config.items("hover")) | |
return items["username"], items["password"] | |
if options.conf is None: | |
if not all((options.username, options.password)): | |
parser.error("You must specifiy either a conf file, or a username and password") | |
else: | |
username, password = options.username, options.password | |
else: | |
username, password = get_conf(options.conf) | |
if operation == "import": | |
import_dns(username, password, domain, filename, options.flush) | |
elif operation == "export": | |
export_dns(username, password, domain, filename) | |
if __name__ == "__main__": | |
try: | |
main() | |
except HoverException as e: | |
print "Failed while importing DNS: {0}".format(e) | |
sys.exit(1) | |
sys.exit(0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
dynhover.py 1.1 | |
Usage: | |
dynhover.py (-c <conf> | -u <user> -p <password>) <domain> | |
dynhover.py (-h | --help) | |
dynhover.py --version | |
Options: | |
-h --help Show this screen. | |
--version Show version. | |
-c --conf=<conf> Path to conf. | |
-u --username=<user> Your hover username. | |
-p --password=<pass> Your hover password. | |
""" | |
import ConfigParser | |
import docopt | |
import requests | |
import sys | |
class HoverException(Exception): | |
pass | |
class HoverAPI(object): | |
def __init__(self, username, password): | |
params = {"username": username, "password": password} | |
r = requests.post("https://www.hover.com/api/login", params=params) | |
if not r.ok or "hoverauth" not in r.cookies: | |
raise HoverException(r) | |
self.cookies = {"hoverauth": r.cookies["hoverauth"]} | |
def call(self, method, resource, data=None): | |
url = "https://www.hover.com/api/{0}".format(resource) | |
r = requests.request(method, url, data=data, cookies=self.cookies) | |
if not r.ok: | |
raise HoverException(r) | |
if r.content: | |
body = r.json() | |
if "succeeded" not in body or body["succeeded"] is not True: | |
raise HoverException(body) | |
return body | |
def get_public_ip(): | |
return requests.get("http://api.exip.org/?call=ip").content | |
def update_dns(username, password, fqdn): | |
try: | |
client = HoverAPI(username, password) | |
except HoverException as e: | |
raise HoverException("Authentication failed") | |
dns = client.call("get", "dns") | |
dns_id = None | |
for domain in dns["domains"]: | |
if fqdn == domain["domain_name"]: | |
fqdn = "@.{domain_name}".format(**domain) | |
for entry in domain["entries"]: | |
if entry["type"] != "A": continue | |
if "{0}.{1}".format(entry["name"], domain["domain_name"]) == fqdn: | |
dns_id = entry["id"] | |
break | |
if dns_id is None: | |
raise HoverException("No DNS record found for {0}".format(fqdn)) | |
my_ip = get_public_ip() | |
response = client.call("put", "dns/{0}".format(dns_id), {"content": my_ip}) | |
if "succeeded" not in response or response["succeeded"] is not True: | |
raise HoverException(response) | |
def main(args): | |
if args["--username"]: | |
username, password = args["--username"], args["--password"] | |
else: | |
config = ConfigParser.ConfigParser() | |
config.read(args["--conf"]) | |
items = dict(config.items("hover")) | |
username, password = items["username"], items["password"] | |
domain = args["<domain>"] | |
try: | |
update_dns(username, password, domain) | |
except HoverException as e: | |
print "Unable to update DNS: {0}".format(e) | |
return 1 | |
return 0 | |
if __name__ == "__main__": | |
version = __doc__.strip().split("\n")[0] | |
args = docopt.docopt(__doc__, version=version) | |
status = main(args) | |
sys.exit(status) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
[[ $# -lt 3 ]] && echo "Usage: $0 USERNAME PASSWORD DNS_ID" | |
USERNAME=${1} | |
PASSWORD=${2} | |
DNS_ID=${3} | |
# find your DNS ID here: https://www.hover.com/api/domains/yourdomain.com/dns/ | |
# (replace "yourdomain.com" with your actual domain, and look for the record | |
# you want to change. The ID looks like: dns1234567) | |
IP=$(curl "http://api.exip.org/?call=ip" -s) | |
curl "https://www.hover.com/api/dns/${DNS_ID}" \ | |
-X PUT \ | |
-d "content=${IP}" \ | |
-s \ | |
-b <(curl "https://www.hover.com/api/login" \ | |
-X POST \ | |
-G \ | |
-d "username=${USERNAME}" \ | |
-d "password=${PASSWORD}" \ | |
-s \ | |
-o /dev/null \ | |
-c -) | |
echo | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment