summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/README33
-rwxr-xr-xscripts/failover.exebin0 -> 56045128 bytes
-rw-r--r--scripts/failover.lisp121
3 files changed, 154 insertions, 0 deletions
diff --git a/scripts/README b/scripts/README
new file mode 100644
index 0000000..b6f4878
--- /dev/null
+++ b/scripts/README
@@ -0,0 +1,33 @@
+The scripts in this directory are meant to be run as standalone
+executables. They must be made into executable SBCL image files.
+
+From a terminal, enter this directory and type:
+
+ sbcl --load <lisp-file>
+
+where lisp file is a file with a .lisp extension. For example:
+
+ sbcl --load failover.lisp
+
+This will load the lisp file and leave you at the REPL. The prompt
+will look like:
+
+ *
+
+At the REPL, type the following lisp form:
+
+ (in-package :dns-admin)
+
+and hit Enter. Then type:
+
+ (sb-ext:save-lisp-and-die "<exe-file>" :toplevel #'run :executable t)
+
+where <exe-file> is the name you want for the new executable core
+file. For example:
+
+ (sb-ext:save-lisp-and-die "failover.exe" :toplevel #'run :executable t)
+
+and hit Enter.
+
+When `save-lisp-and-die' finishes, SBCL will exit and you will be back
+at a terminal prompt.
diff --git a/scripts/failover.exe b/scripts/failover.exe
new file mode 100755
index 0000000..971de4c
--- /dev/null
+++ b/scripts/failover.exe
Binary files differ
diff --git a/scripts/failover.lisp b/scripts/failover.lisp
new file mode 100644
index 0000000..e461af5
--- /dev/null
+++ b/scripts/failover.lisp
@@ -0,0 +1,121 @@
+(in-package :cl)
+(require :asdf)
+(asdf:operate 'asdf:load-op 'drakma)
+
+(defpackage :dns-admin (:use :cl :asdf))
+(in-package :dns-admin)
+
+(defparameter *conf-file* "/etc/dns-admin/options.lisp")
+;;(defparameter *endpoint* "https://dns-admin.vcpfe.vzwops.com")
+(defparameter *endpoint* "http://localhost:3000")
+(defparameter *records* '(
+ (:name "www.meter.vzwops.com"
+ :ref "record:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS52endvcHMubWV0ZXIud3d3:www.meter.vzwops.com/default")
+ (:name "core.meter.vzwops.com"
+ :ref "record:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS52endvcHMubWV0ZXIuY29yZQ:core.meter.vzwops.com/default")
+ (:name "edn.meter.vzwops.com"
+ :ref "record:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS52endvcHMubWV0ZXIuZWRu:edn.meter.vzwops.com/default")
+ (:name "capacity.meter.vzwops.com"
+ :ref "record:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS52endvcHMubWV0ZXIuY2FwYWNpdHk:capacity.meter.vzwops.com/default")
+ (:name "capacity-edn.meter.vzwops.com"
+ :ref "record:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS52endvcHMubWV0ZXIuY2FwYWNpdHktZWRu:capacity-edn.meter.vzwops.com/default")
+ ))
+
+(defmacro with-cookie-jar (&body body)
+ `(let ((cookie-jar (make-instance 'drakma:cookie-jar)))
+ ,@body))
+
+(defun drakma-request (url
+ cookie-jar
+ &key
+ (protocol :HTTP/1.1)
+ (method :get)
+ (content-type "application/x-www-form-urlencoded")
+ (user-agent :firefox)
+ (content nil)
+ (parameters nil)
+ (redirect t)
+ (auto-referer t)
+ (additional-headers nil)
+ (connection-timeout 120)
+ (verify nil)
+ (proxy nil)
+ (proxy-basic-authorization nil)
+ (basic-authorization nil))
+ (drakma:http-request url
+ :cookie-jar cookie-jar
+ :protocol protocol
+ :method method
+ :content-type content-type
+ :parameters parameters
+ :content content
+ :user-agent user-agent
+ :redirect redirect
+ :auto-referer auto-referer
+ :connection-timeout connection-timeout
+ :additional-headers additional-headers
+ :verify verify
+ :proxy proxy
+ :proxy-basic-authorization proxy-basic-authorization
+ :basic-authorization basic-authorization
+ :close t))
+
+(defun read-conf-file ()
+ "Reads the data stored in the config file at location
+`*conf-file*'."
+ (when (probe-file *conf-file*)
+ (with-open-file (input *conf-file* :direction :input)
+ (read input))))
+
+(defun read-creds ()
+ (let ((conf (read-conf-file))
+ username
+ password)
+ (setf username (getf conf :username))
+ (setf password (getf conf :password))
+ (values username password)))
+
+(defun do-failover (target)
+ (let ((retcode 0)
+ (retmsg "OK"))
+ (handler-case
+ (multiple-value-bind (username password)
+ (read-creds)
+ (with-cookie-jar
+ (loop for record in *records* do
+ (format t "Setting ~a to ~a~%" (getf record :name) target)
+ (multiple-value-bind (body status-code headers uri stream must-close reason)
+ (drakma-request (format nil "~a/dns/api/modify/post" *endpoint*)
+ cookie-jar
+ :method :post
+ :basic-authorization `(,username ,password)
+ :parameters `(("recordtype" . "cname")
+ ("ref" . ,(getf record :ref))
+ ("name" . ,(getf record :name))
+ ("canonical" . ,(format nil "openbook-lb-vip-master-~a.meter.vzwops.com" target))))
+ (declare (ignore headers uri stream must-close reason))
+ (cond ((>= status-code 300)
+ (setf retcode 1)
+ (setf retmsg (format nil "Error response from dns-admin.~%Endpoint = [~a]~%Response = [~a]" (format nil "~a/dns/modify/submit" *endpoint*) body)))
+ (t
+ (format t "~a~%" body)))))))
+ (error (e)
+ (progn
+ (setf retcode 1)
+ (setf retmsg (format nil "An error occurred. Error: ~a" e)))))
+ (values retcode retmsg)))
+
+(defun run (&optional target-override)
+ (let ((target (or target-override (car (last sb-ext:*posix-argv*))))
+ (retcode 0)
+ (retmsg "OK"))
+ (cond ((not (find target '("rocklin" "twinsburg") :test 'string=))
+ (setf retcode 1)
+ (setf retmsg "Invalid target specified. Must be 'rocklin' or 'twinsburg'."))
+ (t
+ (multiple-value-bind (code msg)
+ (do-failover target)
+ (setf retcode code)
+ (setf retmsg msg))))
+ (format t "~a" retmsg)
+ (sb-ext:exit :code retcode)))