Initial commit
authorZachary Seguin <ztseguin@csclub.uwaterloo.ca>
Tue, 8 Dec 2015 05:16:07 +0000 (00:16 -0500)
committerZachary Seguin <ztseguin@csclub.uwaterloo.ca>
Tue, 8 Dec 2015 05:23:27 +0000 (00:23 -0500)
.gitignore [new file with mode: 0644]
README [new file with mode: 0644]
ansible.cfg [new file with mode: 0644]
hosts [new file with mode: 0644]
install-etckeeper.yml [new file with mode: 0644]
plugins/callback/log_plays/log_plays.py [new file with mode: 0644]
test-playbook.yml [new file with mode: 0644]
upgrade-office.yml [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..63a7abd
--- /dev/null
@@ -0,0 +1,3 @@
+logs/
+*.log
+*.pyc
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..db07f85
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+           ____ ____   ____      _              _ _     _
+          / ___/ ___| / ___|    / \   _ __  ___(_) |__ | | ___
+         | |   \___ \| |       / _ \ | '_ \/ __| | '_ \| |/ _ \
+         | |___ ___) | |___   / ___ \| | | \__ \ | |_) | |  __/
+          \____|____/ \____| /_/   \_\_| |_|___/_|_.__/|_|\___|
+
+Ansible playbooks of the University of Waterloo Computer Science Club.
+
+** Usage **
+
+To run playbooks which require authentication as 'root':
+
+   1. kadmin -p sysadmin/admin
+   2. execute the ansible playbook
diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644 (file)
index 0000000..afca5ff
--- /dev/null
@@ -0,0 +1,19 @@
+[defaults]
+# Settings
+ask_sudo_pass  = False
+remote_tmp     = /tmp/${USER}/ansible
+nocows         = 1
+
+# Inventory
+inventory      = hosts
+
+# Logging
+log_path       = ansible.log
+
+# Plugins
+
+callback_plugins = plugins/callback/log_plays/
+
+[ssh_connection]
+ssh_args       = -o ServerAliveInterval=30 -o ControlMaster=no
+
diff --git a/hosts b/hosts
new file mode 100644 (file)
index 0000000..9dc79f0
--- /dev/null
+++ b/hosts
@@ -0,0 +1,14 @@
+[general-use]
+caffeine.csclub.uwaterloo.ca
+corn-syrup.csclub.uwaterloo.ca
+high-fructose-corn-syrup.csclub.uwaterloo.ca
+sucrose.csclub.uwaterloo.ca
+taurine.csclub.uwaterloo.ca
+
+[office]
+bit-shifter.csclub.uwaterloo.ca
+gwem.csclub.uwaterloo.ca
+maltodextrin.csclub.uwaterloo.ca
+natural-flavours.csclub.uwaterloo.ca
+nullsleep.csclub.uwaterloo.ca
+strombola.csclub.uwaterloo.ca
diff --git a/install-etckeeper.yml b/install-etckeeper.yml
new file mode 100644 (file)
index 0000000..58bb6ec
--- /dev/null
@@ -0,0 +1,30 @@
+---
+   - hosts: all
+     remote_user: root
+     tasks:
+        - name: update apt cache
+          apt: update_cache=yes
+        - name: install git
+          apt: name=git state=present
+        - name: install etckeeper
+          apt:  name=etckeeper state=present
+          register: etckeeper
+        - name:  update etckeeper VCS
+          lineinfile: dest=/etc/etckeeper/etckeeper.conf
+                      state=present
+                      backrefs=yes
+                      regexp={{ item.regex }}
+                      line={{ item.line }}
+          with_items:
+             - { regex: '^(VCS=.*)$', line: '#\\1' }
+             - { regex: '^#(VCS=\"git\")$', line: '\\1' }
+          when: etckeeper.changed == true
+        - name: re-initialize etckeeper with git
+          command: "{{ item }}"
+          with_items:
+             - 'etckeeper uninit -f'
+             - 'etckeeper init'
+             - 'git commit -m "Initial commit"'
+          args:
+             chdir: /etc
+          when: etckeeper.changed == true
diff --git a/plugins/callback/log_plays/log_plays.py b/plugins/callback/log_plays/log_plays.py
new file mode 100644 (file)
index 0000000..dea0cf8
--- /dev/null
@@ -0,0 +1,97 @@
+# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
+
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+import time
+import json
+
+from ansible.utils.unicode import to_bytes
+
+# NOTE: in Ansible 1.2 or later general logging is available without
+# this plugin, just set ANSIBLE_LOG_PATH as an environment variable
+# or log_path in the DEFAULTS section of your ansible configuration
+# file.  This callback is an example of per hosts logging for those
+# that want it.
+
+
+class CallbackModule(object):
+    """
+    logs playbook results, per host, in /var/log/ansible/hosts
+    """
+    CALLBACK_VERSION = 2.0
+    CALLBACK_TYPE = 'notification'
+    CALLBACK_NAME = 'log_plays'
+    CALLBACK_NEEDS_WHITELIST = True
+
+    TIME_FORMAT="%b %d %Y %H:%M:%S"
+    MSG_FORMAT="%(now)s - %(category)s - %(data)s\n\n"
+
+    def __init__(self):
+
+        super(CallbackModule, self).__init__()
+
+        if not os.path.exists("./logs"):
+            os.makedirs("./logs")
+
+    def log(self, host, category, data):
+        if type(data) == dict:
+            if '_ansible_verbose_override' in data:
+                # avoid logging extraneous data
+                data = 'omitted'
+            else:
+                data = data.copy()
+                invocation = data.pop('invocation', None)
+
+                if invocation['module_name'] == 'setup':
+                    data = json.dumps(data)
+                else:
+                    data = json.dumps(data, indent=3, sort_keys=True, separators=(',', ': '))
+
+                if invocation is not None:
+                    data = json.dumps(invocation, indent=3, sort_keys=True, separators=(',', ': ')) + " => %s " % data
+
+        path = os.path.join("./logs/", host)
+        now = time.strftime(self.TIME_FORMAT, time.localtime())
+
+        msg = to_bytes(self.MSG_FORMAT % dict(now=now, category=category, data=data))
+        with open(path, "ab") as fd:
+            fd.write(msg)
+
+    def runner_on_failed(self, host, res, ignore_errors=False):
+        self.log(host, 'FAILED', res)
+
+    def runner_on_ok(self, host, res):
+        self.log(host, 'OK', res)
+
+    def runner_on_skipped(self, host, item=None):
+        self.log(host, 'SKIPPED', '...')
+
+    def runner_on_unreachable(self, host, res):
+        self.log(host, 'UNREACHABLE', res)
+
+    def runner_on_async_failed(self, host, res, jid):
+        self.log(host, 'ASYNC_FAILED', res)
+
+    def playbook_on_import_for_host(self, host, imported_file):
+        self.log(host, 'IMPORTED', imported_file)
+
+    def playbook_on_not_import_for_host(self, host, missing_file):
+        self.log(host, 'NOTIMPORTED', missing_file)
diff --git a/test-playbook.yml b/test-playbook.yml
new file mode 100644 (file)
index 0000000..1e36deb
--- /dev/null
@@ -0,0 +1,6 @@
+---
+   - hosts: office
+     remote_user: root
+     tasks:
+        - name: whoami
+          command: whoami
diff --git a/upgrade-office.yml b/upgrade-office.yml
new file mode 100644 (file)
index 0000000..2cfddb0
--- /dev/null
@@ -0,0 +1,6 @@
+---
+   - hosts: office
+     remote_user: root
+     tasks:
+        - name: upgrade software packages (safe)
+          apt: update_cache=yes upgrade=safe