1#!/usr/bin/env python
2
3# (c) 2016, Julian Barnett <jbarnett@tableau.com>
4#
5# This file is part of Ansible.
6#
7# Ansible is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# Ansible is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
19
20'''
21MDT external inventory script
22=================================
23author: J Barnett 06/23/2016 01:15
24maintainer: J Barnett (github @jbarnett1981)
25'''
26
27import argparse
28import json
29import pymssql
30from ansible.module_utils.six.moves import configparser
31
32
33class MDTInventory(object):
34
35    def __init__(self):
36        ''' Main execution path '''
37        self.conn = None
38
39        # Initialize empty inventory
40        self.inventory = self._empty_inventory()
41
42        # Read CLI arguments
43        self.read_settings()
44        self.parse_cli_args()
45
46        # Get Hosts
47        if self.args.list:
48            self.get_hosts()
49
50        # Get specific host vars
51        if self.args.host:
52            self.get_hosts(self.args.host)
53
54    def _connect(self, query):
55        '''
56        Connect to MDT and dump contents of dbo.ComputerIdentity database
57        '''
58        if not self.conn:
59            self.conn = pymssql.connect(server=self.mdt_server + "\\" + self.mdt_instance, user=self.mdt_user, password=self.mdt_password,
60                                        database=self.mdt_database)
61            cursor = self.conn.cursor()
62            cursor.execute(query)
63            self.mdt_dump = cursor.fetchall()
64            self.conn.close()
65
66    def get_hosts(self, hostname=False):
67        '''
68        Gets host from MDT Database
69        '''
70        if hostname:
71            query = ("SELECT t1.ID, t1.Description, t1.MacAddress, t2.Role "
72                     "FROM ComputerIdentity as t1 join Settings_Roles as t2 on t1.ID = t2.ID where t1.Description = '%s'" % hostname)
73        else:
74            query = 'SELECT t1.ID, t1.Description, t1.MacAddress, t2.Role FROM ComputerIdentity as t1 join Settings_Roles as t2 on t1.ID = t2.ID'
75        self._connect(query)
76
77        # Configure to group name configured in Ansible Tower for this inventory
78        groupname = self.mdt_groupname
79
80        # Initialize empty host list
81        hostlist = []
82
83        # Parse through db dump and populate inventory
84        for hosts in self.mdt_dump:
85            self.inventory['_meta']['hostvars'][hosts[1]] = {'id': hosts[0], 'name': hosts[1], 'mac': hosts[2], 'role': hosts[3]}
86            hostlist.append(hosts[1])
87        self.inventory[groupname] = hostlist
88
89        # Print it all out
90        print(json.dumps(self.inventory, indent=2))
91
92    def _empty_inventory(self):
93        '''
94        Create empty inventory dictionary
95        '''
96        return {"_meta": {"hostvars": {}}}
97
98    def read_settings(self):
99        '''
100        Reads the settings from the mdt.ini file
101        '''
102        config = configparser.SafeConfigParser()
103        config.read('mdt.ini')
104
105        # MDT Server and instance and database
106        self.mdt_server = config.get('mdt', 'server')
107        self.mdt_instance = config.get('mdt', 'instance')
108        self.mdt_database = config.get('mdt', 'database')
109
110        # MDT Login credentials
111        if config.has_option('mdt', 'user'):
112            self.mdt_user = config.get('mdt', 'user')
113        if config.has_option('mdt', 'password'):
114            self.mdt_password = config.get('mdt', 'password')
115
116        # Group name in Tower
117        if config.has_option('tower', 'groupname'):
118            self.mdt_groupname = config.get('tower', 'groupname')
119
120    def parse_cli_args(self):
121        '''
122        Command line argument processing
123        '''
124        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on MDT')
125        parser.add_argument('--list', action='store_true', default=False, help='List instances')
126        parser.add_argument('--host', action='store', help='Get all the variables about a specific instance')
127        self.args = parser.parse_args()
128
129
130if __name__ == "__main__":
131    # Run the script
132    MDTInventory()
133