1823b8294SYaroslav Brustinov#!/router/bin/python-2.7.4
2823b8294SYaroslav Brustinov
3823b8294SYaroslav Brustinovimport re
4823b8294SYaroslav Brustinovimport misc_methods
5823b8294SYaroslav Brustinov
6823b8294SYaroslav Brustinovclass PlatformResponseMissmatch(Exception):
7823b8294SYaroslav Brustinov    def __init__(self, message):
8823b8294SYaroslav Brustinov        # Call the base class constructor with the parameters it needs
9823b8294SYaroslav Brustinov        super(PlatformResponseMissmatch, self).__init__(message + ' is not available for given platform state and data.\nPlease make sure the relevant features are turned on in the platform.')
10823b8294SYaroslav Brustinov
11823b8294SYaroslav Brustinovclass PlatformResponseAmbiguity(Exception):
12823b8294SYaroslav Brustinov    def __init__(self, message):
13823b8294SYaroslav Brustinov        # Call the base class constructor with the parameters it needs
14823b8294SYaroslav Brustinov        super(PlatformResponseAmbiguity, self).__init__(message + ' found more than one file matching the provided filename.\nPlease provide more distinct filename.')
15823b8294SYaroslav Brustinov
16823b8294SYaroslav Brustinov
17823b8294SYaroslav Brustinovclass CShowParser(object):
18823b8294SYaroslav Brustinov
19823b8294SYaroslav Brustinov    @staticmethod
20823b8294SYaroslav Brustinov    def parse_drop_stats (query_response, interfaces_list):
21823b8294SYaroslav Brustinov        res          = {'total_drops' : 0}
22823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
23823b8294SYaroslav Brustinov        mtch_found   = 0
24823b8294SYaroslav Brustinov
25823b8294SYaroslav Brustinov        for line in response_lst:
26823b8294SYaroslav Brustinov            mtch = re.match("^\s*(\w+/\d/\d)\s+(\d+)\s+(\d+)", line)
27823b8294SYaroslav Brustinov            if mtch:
28823b8294SYaroslav Brustinov                mtch_found += 1
29823b8294SYaroslav Brustinov                if (mtch.group(1) in interfaces_list):
30823b8294SYaroslav Brustinov                    res[mtch.group(1)] = (int(mtch.group(2)) + int(mtch.group(3)))
31823b8294SYaroslav Brustinov                    res['total_drops'] += (int(mtch.group(2)) + int(mtch.group(3)))
32823b8294SYaroslav Brustinov#       if mtch_found == 0: # no matches found at all
33823b8294SYaroslav Brustinov#           raise PlatformResponseMissmatch('Drop stats')
34823b8294SYaroslav Brustinov#       else:
35823b8294SYaroslav Brustinov#           return res
36823b8294SYaroslav Brustinov        return res
37823b8294SYaroslav Brustinov
38823b8294SYaroslav Brustinov    @staticmethod
39823b8294SYaroslav Brustinov    def parse_nbar_stats (query_response):
40823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
41823b8294SYaroslav Brustinov        stats        = {}
42823b8294SYaroslav Brustinov        final_stats  = {}
43823b8294SYaroslav Brustinov        mtch_found   = 0
44823b8294SYaroslav Brustinov
45823b8294SYaroslav Brustinov        for line in response_lst:
46823b8294SYaroslav Brustinov            mtch = re.match("\s*([\w-]+)\s*(\d+)\s*(\d+)\s+", line)
47823b8294SYaroslav Brustinov            if mtch:
48823b8294SYaroslav Brustinov                mtch_found += 1
49823b8294SYaroslav Brustinov                key     = mtch.group(1)
50823b8294SYaroslav Brustinov                pkt_in  = int(mtch.group(2))
51823b8294SYaroslav Brustinov                pkt_out = int(mtch.group(3))
52823b8294SYaroslav Brustinov
53823b8294SYaroslav Brustinov                avg_pkt_cnt = ( pkt_in + pkt_out )/2
54823b8294SYaroslav Brustinov                if avg_pkt_cnt == 0.0:
55823b8294SYaroslav Brustinov                    # escaping zero division case
56823b8294SYaroslav Brustinov                    continue
57501fb3b4SYaroslav Brustinov                if key in stats:
58823b8294SYaroslav Brustinov                    stats[key] += avg_pkt_cnt
59823b8294SYaroslav Brustinov                else:
60823b8294SYaroslav Brustinov                    stats[key] = avg_pkt_cnt
61823b8294SYaroslav Brustinov
62823b8294SYaroslav Brustinov        # Normalize the results to percents
63823b8294SYaroslav Brustinov        for protocol in stats:
64823b8294SYaroslav Brustinov            protocol_norm_stat = int(stats[protocol]*10000/stats['Total'])/100.0 # round the result to x.xx format
65823b8294SYaroslav Brustinov            if (protocol_norm_stat != 0.0):
66823b8294SYaroslav Brustinov                final_stats[protocol] = protocol_norm_stat
67823b8294SYaroslav Brustinov
68823b8294SYaroslav Brustinov        if mtch_found == 0: # no matches found at all
69823b8294SYaroslav Brustinov            raise PlatformResponseMissmatch('NBAR classification stats')
70823b8294SYaroslav Brustinov        else:
71823b8294SYaroslav Brustinov            return { 'percentage' : final_stats, 'packets' : stats }
72823b8294SYaroslav Brustinov
73823b8294SYaroslav Brustinov    @staticmethod
74823b8294SYaroslav Brustinov    def parse_nat_stats (query_response):
75823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
76823b8294SYaroslav Brustinov        res          = {}
77823b8294SYaroslav Brustinov        mtch_found   = 0
78823b8294SYaroslav Brustinov
79823b8294SYaroslav Brustinov        for line in response_lst:
80823b8294SYaroslav Brustinov            mtch = re.match("Total (active translations):\s+(\d+).*(\d+)\s+static,\s+(\d+)\s+dynamic", line)
81823b8294SYaroslav Brustinov            if mtch:
82823b8294SYaroslav Brustinov                mtch_found += 1
83823b8294SYaroslav Brustinov                res['total_active_trans']   = int(mtch.group(2))
84823b8294SYaroslav Brustinov                res['static_active_trans']  = int(mtch.group(3))
85823b8294SYaroslav Brustinov                res['dynamic_active_trans'] = int(mtch.group(4))
86823b8294SYaroslav Brustinov                continue
87823b8294SYaroslav Brustinov
88823b8294SYaroslav Brustinov            mtch = re.match("(Hits):\s+(\d+)\s+(Misses):\s+(\d+)", line)
89823b8294SYaroslav Brustinov            if mtch:
90823b8294SYaroslav Brustinov                mtch_found += 1
91823b8294SYaroslav Brustinov                res['num_of_hits']   = int(mtch.group(2))
92823b8294SYaroslav Brustinov                res['num_of_misses'] = int(mtch.group(4))
93823b8294SYaroslav Brustinov
94823b8294SYaroslav Brustinov        if mtch_found == 0: # no matches found at all
95823b8294SYaroslav Brustinov            raise PlatformResponseMissmatch('NAT translations stats')
96823b8294SYaroslav Brustinov        else:
97823b8294SYaroslav Brustinov            return res
98823b8294SYaroslav Brustinov
99823b8294SYaroslav Brustinov    @staticmethod
100823b8294SYaroslav Brustinov    def parse_cpu_util_stats (query_response):
101823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
102823b8294SYaroslav Brustinov        res = { 'cpu0' : 0,
103823b8294SYaroslav Brustinov                'cpu1' : 0 }
104823b8294SYaroslav Brustinov        mtch_found = 0
105823b8294SYaroslav Brustinov        for line in response_lst:
106823b8294SYaroslav Brustinov            mtch = re.match("\W*Processing: Load\D*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\D*", line)
107823b8294SYaroslav Brustinov            if mtch:
108823b8294SYaroslav Brustinov                mtch_found += 1
109823b8294SYaroslav Brustinov                res['cpu0'] += float(mtch.group(1))
110823b8294SYaroslav Brustinov                res['cpu1'] += float(mtch.group(2))
111823b8294SYaroslav Brustinov
112823b8294SYaroslav Brustinov        if mtch_found == 0: # no matches found at all
113823b8294SYaroslav Brustinov            raise PlatformResponseMissmatch('CPU utilization processing')
114823b8294SYaroslav Brustinov        else:
115823b8294SYaroslav Brustinov            res['cpu0'] = res['cpu0']/mtch_found
116823b8294SYaroslav Brustinov            res['cpu1'] = res['cpu1']/mtch_found
117823b8294SYaroslav Brustinov            return res
118823b8294SYaroslav Brustinov
119823b8294SYaroslav Brustinov    @staticmethod
120823b8294SYaroslav Brustinov    def parse_cft_stats (query_response):
121823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
122823b8294SYaroslav Brustinov        res = {}
123823b8294SYaroslav Brustinov        mtch_found = 0
124823b8294SYaroslav Brustinov        for line in response_lst:
125823b8294SYaroslav Brustinov            mtch = re.match("\W*(\w+)\W*([:]|[=])\W*(\d+)", line)
126823b8294SYaroslav Brustinov            if mtch:
127823b8294SYaroslav Brustinov                mtch_found += 1
128823b8294SYaroslav Brustinov                res[ str( mix_string(m.group(1)) )] = float(m.group(3))
129823b8294SYaroslav Brustinov        if mtch_found == 0: # no matches found at all
130823b8294SYaroslav Brustinov            raise PlatformResponseMissmatch('CFT counters stats')
131823b8294SYaroslav Brustinov        else:
132823b8294SYaroslav Brustinov            return res
133823b8294SYaroslav Brustinov
134823b8294SYaroslav Brustinov
135823b8294SYaroslav Brustinov    @staticmethod
136823b8294SYaroslav Brustinov    def parse_cvla_memory_usage(query_response):
137823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
138823b8294SYaroslav Brustinov        res      = {}
139823b8294SYaroslav Brustinov        res2     = {}
140823b8294SYaroslav Brustinov        cnt      = 0
141823b8294SYaroslav Brustinov        state    = 0
142823b8294SYaroslav Brustinov        name     = ''
143823b8294SYaroslav Brustinov        number   = 0.0
144823b8294SYaroslav Brustinov
145823b8294SYaroslav Brustinov        for line in response_lst:
146823b8294SYaroslav Brustinov            if state == 0:
147823b8294SYaroslav Brustinov                mtch = re.match("\W*Entity name:\W*(\w[^\r\n]+)", line)
148823b8294SYaroslav Brustinov                if mtch:
149823b8294SYaroslav Brustinov                    name = misc_methods.mix_string(mtch.group(1))
150823b8294SYaroslav Brustinov                    state = 1
151823b8294SYaroslav Brustinov                    cnt += 1
152823b8294SYaroslav Brustinov            elif state == 1:
153823b8294SYaroslav Brustinov                mtch = re.match("\W*Handle:\W*(\d+)", line)
154823b8294SYaroslav Brustinov                if mtch:
155823b8294SYaroslav Brustinov                    state = state + 1
156823b8294SYaroslav Brustinov                else:
157823b8294SYaroslav Brustinov                    state = 0;
158823b8294SYaroslav Brustinov            elif state == 2:
159823b8294SYaroslav Brustinov                mtch = re.match("\W*Number of allocations:\W*(\d+)", line)
160823b8294SYaroslav Brustinov                if mtch:
161823b8294SYaroslav Brustinov                    state = state + 1
162823b8294SYaroslav Brustinov                    number=float(mtch.group(1))
163823b8294SYaroslav Brustinov                else:
164823b8294SYaroslav Brustinov                    state = 0;
165823b8294SYaroslav Brustinov            elif state == 3:
166823b8294SYaroslav Brustinov                mtch = re.match("\W*Memory allocated:\W*(\d+)", line)
167823b8294SYaroslav Brustinov                if mtch:
168823b8294SYaroslav Brustinov                    state = 0
169823b8294SYaroslav Brustinov                    res[name]   = float(mtch.group(1))
170823b8294SYaroslav Brustinov                    res2[name]  = number
171823b8294SYaroslav Brustinov                else:
172823b8294SYaroslav Brustinov                    state = 0
173823b8294SYaroslav Brustinov        if cnt == 0:
174823b8294SYaroslav Brustinov            raise PlatformResponseMissmatch('CVLA memory usage stats')
175823b8294SYaroslav Brustinov
176823b8294SYaroslav Brustinov        return (res,res2)
177823b8294SYaroslav Brustinov
178823b8294SYaroslav Brustinov
179823b8294SYaroslav Brustinov    @staticmethod
180823b8294SYaroslav Brustinov    def parse_show_image_version(query_response):
181823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
182823b8294SYaroslav Brustinov        res      = {}
183823b8294SYaroslav Brustinov
184823b8294SYaroslav Brustinov        for line in response_lst:
185823b8294SYaroslav Brustinov            mtch = re.match("System image file is \"(\w+):(.*/)?(.+)\"", line)
186823b8294SYaroslav Brustinov            if mtch:
187823b8294SYaroslav Brustinov                res['drive'] = mtch.group(1)
188823b8294SYaroslav Brustinov                res['image'] = mtch.group(3)
189823b8294SYaroslav Brustinov                return res
190823b8294SYaroslav Brustinov
191823b8294SYaroslav Brustinov        raise PlatformResponseMissmatch('Running image info')
192823b8294SYaroslav Brustinov
193823b8294SYaroslav Brustinov
194823b8294SYaroslav Brustinov    @staticmethod
195823b8294SYaroslav Brustinov    def parse_image_existence(query_response, img_name):
196823b8294SYaroslav Brustinov        response_lst = query_response.split('\r\n')
197823b8294SYaroslav Brustinov        cnt      = 0
198823b8294SYaroslav Brustinov
199823b8294SYaroslav Brustinov        for line in response_lst:
200823b8294SYaroslav Brustinov            regex = re.compile(".* (?!include) %s" % img_name )
201823b8294SYaroslav Brustinov            mtch = regex.match(line)
202823b8294SYaroslav Brustinov            if mtch:
203823b8294SYaroslav Brustinov                cnt += 1
204823b8294SYaroslav Brustinov        if cnt == 1:
205823b8294SYaroslav Brustinov            return True
206823b8294SYaroslav Brustinov        elif cnt > 1:
207823b8294SYaroslav Brustinov            raise PlatformResponseAmbiguity('Image existence')
208823b8294SYaroslav Brustinov        else:
209823b8294SYaroslav Brustinov            return False
210823b8294SYaroslav Brustinov
211823b8294SYaroslav Brustinov    @staticmethod
212823b8294SYaroslav Brustinov    def parse_file_copy (query_response):
213823b8294SYaroslav Brustinov        rev_response_lst = reversed(query_response.split('\r\n'))
214823b8294SYaroslav Brustinov        lines_parsed     = 0
215823b8294SYaroslav Brustinov
216823b8294SYaroslav Brustinov        for line in rev_response_lst:
217823b8294SYaroslav Brustinov            mtch = re.match("\[OK - (\d+) bytes\]", line)
218823b8294SYaroslav Brustinov            if mtch:
219823b8294SYaroslav Brustinov                return True
220823b8294SYaroslav Brustinov            lines_parsed += 1
221823b8294SYaroslav Brustinov
222823b8294SYaroslav Brustinov            if lines_parsed > 5:
223823b8294SYaroslav Brustinov                return False
224823b8294SYaroslav Brustinov        return False
225823b8294SYaroslav Brustinov
226823b8294SYaroslav Brustinov
227823b8294SYaroslav Brustinovif __name__ == "__main__":
228823b8294SYaroslav Brustinov    pass
229