aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/autobuilder/lib/daft.py
blob: 925efa7e3697567e4d4bc2b988b8cedbcdfa98ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import os
import ConfigParser as configparser

class DeployScanner(object):
    '''
    In charge of scanning deployed daft bbb devices
    '''

    __MAGIC_SERVER_ADDRESS = '192.168.30.1' # DAFT uses this address for this internal network
    __MAGIC_SSH_PORT = 2233 # it is hardcoded as per DAFT implementation manual

    def  __init__(self, *args, **kwargs):
        self.devsconf_fp = kwargs.get('devsconf_file', None)
        if not self.devsconf_fp:
            raise Exception('not fed devsconf file')
        self.ign_leases = kwargs.get('ign_leases', True)
        if not self.ign_leases:
            self.leases_file_path =  kwargs.get('leases_file', None)
            if not self.leases_file_path:
                raise Exception('not fed leases file')

    def getDevices(self):
        '''
        Creates relation of deployed devices
        Returns:
            List of dictionaries containing info about devices deployed.
        '''

        def _map_config(conf, leases=None):
            """
                Creates a list with dictionaries for DUT config
                information, if DHCP leases isn't none also validate
                if the DUT IP is active.
            """

            mapped_config = []

            for entry in conf:
                append = False
                if leases:
                    for active in leases:
                        if conf['bb_ip'] == active['ip']:
                            append = True
                            break
                else:
                    append = True

                if append:
                    mapped_config.append({
                        'dut_label': entry['device'],
                        'dut_family': entry['device_type'],
                        'dut_sshport': str(self.__MAGIC_SSH_PORT),
                        'ctrl_address': entry['bb_ip'],
                        'server_address': self.__MAGIC_SERVER_ADDRESS
                    })

            return mapped_config

        conf = self.__fetch_confs()
        if not conf:
            raise Exception('There are no configurations as per BBB devices')

        leases = None
        if not self.ign_leases:
            leases = self.__active_leases()
            if not leases:
                raise Exception('DHCP server has not registered any host yet')

        return _map_config(conf, leases)

    def __fetch_confs(self):
        '''
        Read and parse BBB configuration file and return result as dictionary
        '''
        config = configparser.SafeConfigParser()
        config.read(self.devsconf_fp)
        configurations = []
        for device in config.sections():
            device_config = dict(config.items(device))
            device_config["device"] = device
            device_config["device_type"] = device.rstrip('1234567890_')
            configurations.append(device_config)
        return configurations

    def __active_leases(self):
        """
        Read the active leases from dnsmasq leases file and return a list of
        active leases as dictionaries.
        Args:
            file_name (str): Path to leases file, e.g. /path/to/file/dnsmasq.leases
        Returns:
            List of dictionaries containing the active leases.
            The dictionaries have the following format:
            {
                "mac": "device_mac_address",
                "ip": "device_ip_address",
                "hostname": "device_host_name",
                "client_id": "client_id_or_*_if_unset"
            }
        """
        with open(self.leases_file_path) as lease_file:
            leases = lease_file.readlines()

        leases_list = []

        # dnsmasq.leases contains rows with the following format:
        # <lease_expiry_time_as_epoch_format> <mac> <ip> <hostname> <domain>
        # See:
        #http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q1/000143.html
        for lease in leases:
            lease = lease.split()
            leases_list.append({
                "mac": lease[1],
                "ip": lease[2],
                "hostname": lease[3],
                "client_id": lease[4],
            })
        return leases_list