1823b8294SYaroslav Brustinov#!/router/bin/python
2823b8294SYaroslav Brustinov
3823b8294SYaroslav Brustinovfrom interfaces_e import IFType
4823b8294SYaroslav Brustinovfrom platform_cmd_link import *
5823b8294SYaroslav Brustinovimport CustomLogger
6823b8294SYaroslav Brustinovimport misc_methods
7823b8294SYaroslav Brustinovimport re
8823b8294SYaroslav Brustinovimport time
9823b8294SYaroslav Brustinovimport CProgressDisp
10823b8294SYaroslav Brustinovfrom CShowParser import CShowParser
11823b8294SYaroslav Brustinov
12823b8294SYaroslav Brustinovclass CPlatform(object):
13823b8294SYaroslav Brustinov    def __init__(self, silent_mode):
14823b8294SYaroslav Brustinov        self.if_mngr            = CIfManager()
15823b8294SYaroslav Brustinov        self.cmd_link           = CCommandLink(silent_mode)
16823b8294SYaroslav Brustinov        self.nat_config         = None
17823b8294SYaroslav Brustinov        self.stat_route_config  = None
18823b8294SYaroslav Brustinov        self.running_image      = None
19823b8294SYaroslav Brustinov        self.needed_image_path  = None
20823b8294SYaroslav Brustinov        self.tftp_cfg           = None
21823b8294SYaroslav Brustinov        self.config_history     = { 'basic_if_config' : False, 'tftp_server_config' : False }
22a6e3bf69SIdo Barnea        self.client_vlan        = "100"
23a6e3bf69SIdo Barnea        self.server_vlan        = "200"
24823b8294SYaroslav Brustinov
25a6e3bf69SIdo Barnea    def configure_basic_interfaces(self, mtu = 9050, vlan=False):
26823b8294SYaroslav Brustinov
27823b8294SYaroslav Brustinov        cache = CCommandCache()
28823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list():
29823b8294SYaroslav Brustinov            client_if_command_set   = []
30823b8294SYaroslav Brustinov            server_if_command_set   = []
31a6e3bf69SIdo Barnea            client_if_command_set_vlan   = []
32a6e3bf69SIdo Barnea            server_if_command_set_vlan   = []
33a6e3bf69SIdo Barnea
34a6e3bf69SIdo Barnea            client_if_name = dual_if.client_if.get_name()
35a6e3bf69SIdo Barnea            server_if_name = dual_if.server_if.get_name()
36a6e3bf69SIdo Barnea
37a6e3bf69SIdo Barnea            if vlan:
38a6e3bf69SIdo Barnea                client_if_name_vlan = client_if_name + "." + self.client_vlan
39a6e3bf69SIdo Barnea                server_if_name_vlan = server_if_name + "." + self.server_vlan
40a6e3bf69SIdo Barnea                client_if_command_set_vlan.append('encapsulation dot1Q {vlan}'. format(vlan = self.client_vlan));
41a6e3bf69SIdo Barnea                server_if_command_set_vlan.append('encapsulation dot1Q {vlan}'. format(vlan = self.server_vlan));
42823b8294SYaroslav Brustinov
43823b8294SYaroslav Brustinov            client_if_command_set.append ('mac-address {mac}'.format( mac = dual_if.client_if.get_src_mac_addr()) )
446e425446SYaroslav Brustinov            client_if_command_set.append ('mtu %s' % mtu)
45823b8294SYaroslav Brustinov
46a6e3bf69SIdo Barnea            client_ip_command = 'ip address {ip} 255.255.255.0'.format( ip = dual_if.client_if.get_ipv4_addr() )
47a6e3bf69SIdo Barnea            client_ipv6_command = 'ipv6 address {ip}/64'.format( ip = dual_if.client_if.get_ipv6_addr() )
48a6e3bf69SIdo Barnea            if vlan:
49a6e3bf69SIdo Barnea                client_if_command_set_vlan.append (client_ip_command)
50a6e3bf69SIdo Barnea                client_if_command_set_vlan.append (client_ipv6_command)
51a6e3bf69SIdo Barnea            else:
52a6e3bf69SIdo Barnea                client_if_command_set.append (client_ip_command)
53a6e3bf69SIdo Barnea                client_if_command_set.append (client_ipv6_command)
54a6e3bf69SIdo Barnea
55a6e3bf69SIdo Barnea            cache.add('IF', client_if_command_set, client_if_name)
56a6e3bf69SIdo Barnea            if vlan:
57a6e3bf69SIdo Barnea                cache.add('IF', client_if_command_set_vlan, client_if_name_vlan)
58823b8294SYaroslav Brustinov
59823b8294SYaroslav Brustinov            server_if_command_set.append ('mac-address {mac}'.format( mac = dual_if.server_if.get_src_mac_addr()) )
606e425446SYaroslav Brustinov            server_if_command_set.append ('mtu %s' % mtu)
61823b8294SYaroslav Brustinov
62a6e3bf69SIdo Barnea            server_ip_command = 'ip address {ip} 255.255.255.0'.format( ip = dual_if.server_if.get_ipv4_addr() )
63a6e3bf69SIdo Barnea            server_ipv6_command = 'ipv6 address {ip}/64'.format( ip = dual_if.server_if.get_ipv6_addr() )
64a6e3bf69SIdo Barnea            if vlan:
65a6e3bf69SIdo Barnea                server_if_command_set_vlan.append (server_ip_command)
66a6e3bf69SIdo Barnea                server_if_command_set_vlan.append (server_ipv6_command)
67a6e3bf69SIdo Barnea            else:
68a6e3bf69SIdo Barnea                server_if_command_set.append (server_ip_command)
69a6e3bf69SIdo Barnea                server_if_command_set.append (server_ipv6_command)
70a6e3bf69SIdo Barnea
71a6e3bf69SIdo Barnea            cache.add('IF', server_if_command_set, server_if_name)
72a6e3bf69SIdo Barnea            if vlan:
73a6e3bf69SIdo Barnea                cache.add('IF', server_if_command_set_vlan, server_if_name_vlan)
74823b8294SYaroslav Brustinov
75823b8294SYaroslav Brustinov        self.cmd_link.run_single_command(cache)
76823b8294SYaroslav Brustinov        self.config_history['basic_if_config'] = True
77823b8294SYaroslav Brustinov
78d0c51b80SYaroslav Brustinov    def configure_basic_filtered_interfaces(self, intf_list, mtu = 9050, vlan = False):
79823b8294SYaroslav Brustinov
80823b8294SYaroslav Brustinov        cache = CCommandCache()
81823b8294SYaroslav Brustinov        for intf in intf_list:
82823b8294SYaroslav Brustinov            if_command_set   = []
83d0c51b80SYaroslav Brustinov            if_command_set_vlan = []
84823b8294SYaroslav Brustinov
85823b8294SYaroslav Brustinov            if_command_set.append ('mac-address {mac}'.format( mac = intf.get_src_mac_addr()) )
866e425446SYaroslav Brustinov            if_command_set.append ('mtu %s' % mtu)
87d0c51b80SYaroslav Brustinov            ip_commands = ['ip address {ip} 255.255.255.0'.format( ip = intf.get_ipv4_addr() ),
88d0c51b80SYaroslav Brustinov                           'ipv6 address {ip}/64'.format( ip = intf.get_ipv6_addr() )]
89a6e3bf69SIdo Barnea            if vlan:
90d0c51b80SYaroslav Brustinov                if_command_set_vlan.extend(ip_commands)
91d0c51b80SYaroslav Brustinov            else:
92d0c51b80SYaroslav Brustinov                if_command_set.extend(ip_commands)
93823b8294SYaroslav Brustinov
94823b8294SYaroslav Brustinov            cache.add('IF', if_command_set, intf.get_name())
95d0c51b80SYaroslav Brustinov            if vlan:
96d0c51b80SYaroslav Brustinov                if_name = intf.get_name() + '.' + (self.client_vlan if intf.is_client() else self.server_vlan)
97d0c51b80SYaroslav Brustinov                cache.add('IF', if_command_set_vlan, if_name)
98823b8294SYaroslav Brustinov
99823b8294SYaroslav Brustinov        self.cmd_link.run_single_command(cache)
100823b8294SYaroslav Brustinov
101823b8294SYaroslav Brustinov
102823b8294SYaroslav Brustinov    def load_clean_config (self, config_filename = "clean_config.cfg", cfg_drive = "bootflash"):
103ec23dc1aSYaroslav Brustinov        for i in range(5):
104ec23dc1aSYaroslav Brustinov            self.clear_nat_translations()
105ec23dc1aSYaroslav Brustinov            cache = CCommandCache()
106ec23dc1aSYaroslav Brustinov            cache.add('EXEC', "configure replace {drive}:{file} force".format(drive = cfg_drive, file = config_filename))
107ec23dc1aSYaroslav Brustinov            res = self.cmd_link.run_single_command(cache)
108ec23dc1aSYaroslav Brustinov            if 'Rollback Done' not in res:
109ec23dc1aSYaroslav Brustinov                print('Failed to load clean config, trying again')
11051db963aSYaroslav Brustinov                time.sleep(2)
111ec23dc1aSYaroslav Brustinov                if i < 4:
112ec23dc1aSYaroslav Brustinov                    continue
113ec23dc1aSYaroslav Brustinov                raise Exception('Could not load clean config, response: %s' % res)
114d0c51b80SYaroslav Brustinov            break
115823b8294SYaroslav Brustinov
116a6e3bf69SIdo Barnea    def config_pbr (self, mode = 'config', vlan = False):
117823b8294SYaroslav Brustinov        idx = 1
118823b8294SYaroslav Brustinov        unconfig_str = '' if mode=='config' else 'no '
119823b8294SYaroslav Brustinov
120823b8294SYaroslav Brustinov        cache = CCommandCache()
121823b8294SYaroslav Brustinov        pre_commit_cache = CCommandCache()
122823b8294SYaroslav Brustinov        pre_commit_set = set([])
123823b8294SYaroslav Brustinov
124823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list():
125823b8294SYaroslav Brustinov            client_if_command_set   = []
126823b8294SYaroslav Brustinov            server_if_command_set   = []
127823b8294SYaroslav Brustinov            conf_t_command_set      = []
128823b8294SYaroslav Brustinov            client_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.server_if.get_ipv4_addr() )
129823b8294SYaroslav Brustinov            server_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.client_if.get_ipv4_addr() )
130823b8294SYaroslav Brustinov
131823b8294SYaroslav Brustinov            if dual_if.is_duplicated():
132823b8294SYaroslav Brustinov                # define the relevant VRF name
133823b8294SYaroslav Brustinov                pre_commit_set.add('{mode}ip vrf {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
134a6e3bf69SIdo Barnea
135823b8294SYaroslav Brustinov                # assign VRF to interfaces, config interfaces with relevant route-map
136823b8294SYaroslav Brustinov                client_if_command_set.append ('{mode}ip vrf forwarding {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
137a6e3bf69SIdo Barnea                client_if_command_set.append ('{mode}ip policy route-map {dup}_{p1}_to_{p2}'.format(
138823b8294SYaroslav Brustinov                    mode = unconfig_str,
139a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
140823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
141823b8294SYaroslav Brustinov                server_if_command_set.append ('{mode}ip vrf forwarding {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
142a6e3bf69SIdo Barnea                server_if_command_set.append ('{mode}ip policy route-map {dup}_{p2}_to_{p1}'.format(
143823b8294SYaroslav Brustinov                    mode = unconfig_str,
144a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
145823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
146823b8294SYaroslav Brustinov
147823b8294SYaroslav Brustinov                # config route-map routing
148823b8294SYaroslav Brustinov                conf_t_command_set.append('{mode}route-map {dup}_{p1}_to_{p2} permit 10'.format(
149823b8294SYaroslav Brustinov                    mode = unconfig_str,
150a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
151823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
152823b8294SYaroslav Brustinov                if mode == 'config':
153823b8294SYaroslav Brustinov                    conf_t_command_set.append('set ip next-hop {next_hop}'.format(
154823b8294SYaroslav Brustinov                         next_hop = client_net_next_hop) )
155823b8294SYaroslav Brustinov                conf_t_command_set.append('{mode}route-map {dup}_{p2}_to_{p1} permit 10'.format(
156823b8294SYaroslav Brustinov                    mode = unconfig_str,
157a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
158823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
159823b8294SYaroslav Brustinov                if mode == 'config':
160823b8294SYaroslav Brustinov                    conf_t_command_set.append('set ip next-hop {next_hop}'.format(
161823b8294SYaroslav Brustinov                         next_hop = server_net_next_hop) )
1629c6e6d4bSIdo Barnea                conf_t_command_set.append('exit')
163823b8294SYaroslav Brustinov
164823b8294SYaroslav Brustinov                # config global arp to interfaces net address and vrf
1659c6e6d4bSIdo Barnea                if dual_if.client_if.get_dest_mac():
1669c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp vrf {dup} {next_hop} {dest_mac} arpa'.format(
1679c6e6d4bSIdo Barnea                        mode = unconfig_str,
168a6e3bf69SIdo Barnea                        dup = dual_if.get_vrf_name(),
169a6e3bf69SIdo Barnea                        next_hop = server_net_next_hop,
1709c6e6d4bSIdo Barnea                        dest_mac = dual_if.client_if.get_dest_mac()))
1719c6e6d4bSIdo Barnea                if dual_if.server_if.get_dest_mac():
1729c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp vrf {dup} {next_hop} {dest_mac} arpa'.format(
173a6e3bf69SIdo Barnea                        mode = unconfig_str,
174a6e3bf69SIdo Barnea                        dup = dual_if.get_vrf_name(),
175a6e3bf69SIdo Barnea                        next_hop = client_net_next_hop,
1769c6e6d4bSIdo Barnea                        dest_mac = dual_if.server_if.get_dest_mac()))
177823b8294SYaroslav Brustinov            else:
178823b8294SYaroslav Brustinov                # config interfaces with relevant route-map
179a6e3bf69SIdo Barnea                client_if_command_set.append ('{mode}ip policy route-map {p1}_to_{p2}'.format(
180823b8294SYaroslav Brustinov                    mode = unconfig_str,
181823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
182a6e3bf69SIdo Barnea                server_if_command_set.append ('{mode}ip policy route-map {p2}_to_{p1}'.format(
183823b8294SYaroslav Brustinov                    mode = unconfig_str,
184823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
185823b8294SYaroslav Brustinov
186823b8294SYaroslav Brustinov                # config route-map routing
187823b8294SYaroslav Brustinov                conf_t_command_set.append('{mode}route-map {p1}_to_{p2} permit 10'.format(
188823b8294SYaroslav Brustinov                    mode = unconfig_str,
189823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
190823b8294SYaroslav Brustinov                if mode == 'config':
191823b8294SYaroslav Brustinov                    conf_t_command_set.append('set ip next-hop {next_hop}'.format(
192823b8294SYaroslav Brustinov                         next_hop = client_net_next_hop) )
193823b8294SYaroslav Brustinov                conf_t_command_set.append('{mode}route-map {p2}_to_{p1} permit 10'.format(
194823b8294SYaroslav Brustinov                    mode = unconfig_str,
195823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
196823b8294SYaroslav Brustinov                if mode == 'config':
197823b8294SYaroslav Brustinov                    conf_t_command_set.append('set ip next-hop {next_hop}'.format(
198823b8294SYaroslav Brustinov                         next_hop = server_net_next_hop) )
1999c6e6d4bSIdo Barnea                conf_t_command_set.append('exit')
200823b8294SYaroslav Brustinov
201823b8294SYaroslav Brustinov                # config global arp to interfaces net address
2029c6e6d4bSIdo Barnea                if dual_if.client_if.get_dest_mac():
2039c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
2049c6e6d4bSIdo Barnea                        mode = unconfig_str,
205a6e3bf69SIdo Barnea                        next_hop = server_net_next_hop,
2069c6e6d4bSIdo Barnea                        dest_mac = dual_if.client_if.get_dest_mac()))
2079c6e6d4bSIdo Barnea                if dual_if.server_if.get_dest_mac():
2089c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
2099c6e6d4bSIdo Barnea                        mode = unconfig_str,
210a6e3bf69SIdo Barnea                        next_hop = client_net_next_hop,
2119c6e6d4bSIdo Barnea                        dest_mac = dual_if.server_if.get_dest_mac()))
212823b8294SYaroslav Brustinov
213823b8294SYaroslav Brustinov            # assign generated config list to cache
214a6e3bf69SIdo Barnea            client_if_name = dual_if.client_if.get_name()
215a6e3bf69SIdo Barnea            server_if_name = dual_if.server_if.get_name()
216a6e3bf69SIdo Barnea            if vlan:
217a6e3bf69SIdo Barnea                client_if_name += "." + self.client_vlan
218a6e3bf69SIdo Barnea                server_if_name += "." + self.server_vlan
219a6e3bf69SIdo Barnea            cache.add('IF', server_if_command_set, server_if_name)
220a6e3bf69SIdo Barnea            cache.add('IF', client_if_command_set, client_if_name)
221823b8294SYaroslav Brustinov            cache.add('CONF', conf_t_command_set)
222823b8294SYaroslav Brustinov            idx += 2
223823b8294SYaroslav Brustinov
224823b8294SYaroslav Brustinov        # finish handling pre-config cache
225823b8294SYaroslav Brustinov        pre_commit_set = list(pre_commit_set)
226cc53c3d2SYaroslav Brustinov        if len(pre_commit_set):
227cc53c3d2SYaroslav Brustinov            pre_commit_set.append('exit')
228823b8294SYaroslav Brustinov        pre_commit_cache.add('CONF', pre_commit_set )
229823b8294SYaroslav Brustinov        # deploy the configs (order is important!)
230823b8294SYaroslav Brustinov        self.cmd_link.run_command( [pre_commit_cache, cache] )
231823b8294SYaroslav Brustinov        if self.config_history['basic_if_config']:
232a6e3bf69SIdo Barnea            # in this case, duplicated interfaces will lose its ip address.
233823b8294SYaroslav Brustinov            # re-config IPv4 addresses
234d0c51b80SYaroslav Brustinov            self.configure_basic_filtered_interfaces(self.if_mngr.get_duplicated_if(), vlan = vlan)
235823b8294SYaroslav Brustinov
236a6e3bf69SIdo Barnea    def config_no_pbr (self, vlan = False):
237a6e3bf69SIdo Barnea        self.config_pbr(mode = 'unconfig', vlan = vlan)
238823b8294SYaroslav Brustinov
239823b8294SYaroslav Brustinov    def config_static_routing (self, stat_route_obj, mode = 'config'):
240823b8294SYaroslav Brustinov
241823b8294SYaroslav Brustinov        if mode == 'config':
242823b8294SYaroslav Brustinov            self.stat_route_config = stat_route_obj   # save the latest static route config for future removal purposes
243823b8294SYaroslav Brustinov
244823b8294SYaroslav Brustinov        unconfig_str = '' if mode=='config' else 'no '
245823b8294SYaroslav Brustinov        cache              = CCommandCache()
246823b8294SYaroslav Brustinov        pre_commit_cache   = CCommandCache()
247823b8294SYaroslav Brustinov        pre_commit_set     = set([])
248823b8294SYaroslav Brustinov        current_dup_intf   = None
249823b8294SYaroslav Brustinov        # client_net       = None
250823b8294SYaroslav Brustinov        # server_net       = None
251823b8294SYaroslav Brustinov        client_net         = stat_route_obj.client_net_start
252823b8294SYaroslav Brustinov        server_net         = stat_route_obj.server_net_start
253823b8294SYaroslav Brustinov        conf_t_command_set = []
254823b8294SYaroslav Brustinov
255823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list():
256823b8294SYaroslav Brustinov
257823b8294SYaroslav Brustinov            # handle duplicated addressing generation
258823b8294SYaroslav Brustinov            if dual_if.is_duplicated():
259823b8294SYaroslav Brustinov                if dual_if.get_vrf_name() != current_dup_intf:
260823b8294SYaroslav Brustinov                    # if this is a dual interfaces, and it is different from the one we proccessed so far, reset static route addressing
261823b8294SYaroslav Brustinov                    current_dup_intf = dual_if.get_vrf_name()
262823b8294SYaroslav Brustinov                    client_net       = stat_route_obj.client_net_start
263823b8294SYaroslav Brustinov                    server_net       = stat_route_obj.server_net_start
264823b8294SYaroslav Brustinov            else:
265823b8294SYaroslav Brustinov                if current_dup_intf is not None:
266823b8294SYaroslav Brustinov                    current_dup_intf = None
267823b8294SYaroslav Brustinov                    client_net       = stat_route_obj.client_net_start
268823b8294SYaroslav Brustinov                    server_net       = stat_route_obj.server_net_start
269823b8294SYaroslav Brustinov
270823b8294SYaroslav Brustinov            client_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.server_if.get_ipv4_addr() )
271823b8294SYaroslav Brustinov            server_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.client_if.get_ipv4_addr() )
272823b8294SYaroslav Brustinov
273823b8294SYaroslav Brustinov            # handle static route configuration for the interfaces
274823b8294SYaroslav Brustinov            if dual_if.is_duplicated():
275823b8294SYaroslav Brustinov                client_if_command_set   = []
276823b8294SYaroslav Brustinov                server_if_command_set   = []
277823b8294SYaroslav Brustinov
278823b8294SYaroslav Brustinov                # define the relevant VRF name
279823b8294SYaroslav Brustinov                pre_commit_set.add('{mode}ip vrf {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
2805698b663SYaroslav Brustinov
281823b8294SYaroslav Brustinov                # assign VRF to interfaces, config interfaces with relevant route-map
282823b8294SYaroslav Brustinov                client_if_command_set.append ('{mode}ip vrf forwarding {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
283823b8294SYaroslav Brustinov                server_if_command_set.append ('{mode}ip vrf forwarding {dup}'.format( mode = unconfig_str, dup = dual_if.get_vrf_name()) )
284823b8294SYaroslav Brustinov
285823b8294SYaroslav Brustinov                conf_t_command_set.append( "{mode}ip route vrf {dup} {next_net} {dest_mask} {next_hop}".format(
286823b8294SYaroslav Brustinov                    mode = unconfig_str,
287a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
288823b8294SYaroslav Brustinov                    next_net = client_net,
289823b8294SYaroslav Brustinov                    dest_mask = stat_route_obj.client_mask,
290823b8294SYaroslav Brustinov                    next_hop = client_net_next_hop))
291823b8294SYaroslav Brustinov                conf_t_command_set.append( "{mode}ip route vrf {dup} {next_net} {dest_mask} {next_hop}".format(
292823b8294SYaroslav Brustinov                    mode = unconfig_str,
293a6e3bf69SIdo Barnea                    dup = dual_if.get_vrf_name(),
294823b8294SYaroslav Brustinov                    next_net = server_net,
295823b8294SYaroslav Brustinov                    dest_mask = stat_route_obj.server_mask,
296823b8294SYaroslav Brustinov                    next_hop = server_net_next_hop))
297823b8294SYaroslav Brustinov
298823b8294SYaroslav Brustinov                # config global arp to interfaces net address and vrf
2999c6e6d4bSIdo Barnea                if dual_if.client_if.get_dest_mac():
3009c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp vrf {dup} {next_hop} {dest_mac} arpa'.format(
3019c6e6d4bSIdo Barnea                        mode = unconfig_str,
302a6e3bf69SIdo Barnea                        dup = dual_if.get_vrf_name(),
303a6e3bf69SIdo Barnea                        next_hop = server_net_next_hop,
3049c6e6d4bSIdo Barnea                        dest_mac = dual_if.client_if.get_dest_mac()))
3059c6e6d4bSIdo Barnea                if dual_if.server_if.get_dest_mac():
3069c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp vrf {dup} {next_hop} {dest_mac} arpa'.format(
307a6e3bf69SIdo Barnea                        mode = unconfig_str,
308a6e3bf69SIdo Barnea                        dup = dual_if.get_vrf_name(),
309a6e3bf69SIdo Barnea                        next_hop = client_net_next_hop,
3109c6e6d4bSIdo Barnea                        dest_mac = dual_if.server_if.get_dest_mac()))
311823b8294SYaroslav Brustinov
312823b8294SYaroslav Brustinov                # assign generated interfaces config list to cache
313823b8294SYaroslav Brustinov                cache.add('IF', server_if_command_set, dual_if.server_if.get_name())
314823b8294SYaroslav Brustinov                cache.add('IF', client_if_command_set, dual_if.client_if.get_name())
315823b8294SYaroslav Brustinov
316823b8294SYaroslav Brustinov            else:
317823b8294SYaroslav Brustinov                conf_t_command_set.append( "{mode}ip route {next_net} {dest_mask} {next_hop}".format(
318823b8294SYaroslav Brustinov                    mode = unconfig_str,
319823b8294SYaroslav Brustinov                    next_net = client_net,
320823b8294SYaroslav Brustinov                    dest_mask = stat_route_obj.client_mask,
321823b8294SYaroslav Brustinov                    next_hop = server_net_next_hop))
322823b8294SYaroslav Brustinov                conf_t_command_set.append( "{mode}ip route {next_net} {dest_mask} {next_hop}".format(
323823b8294SYaroslav Brustinov                    mode = unconfig_str,
324823b8294SYaroslav Brustinov                    next_net = server_net,
325823b8294SYaroslav Brustinov                    dest_mask = stat_route_obj.server_mask,
326823b8294SYaroslav Brustinov                    next_hop = client_net_next_hop))
327823b8294SYaroslav Brustinov
328823b8294SYaroslav Brustinov                # config global arp to interfaces net address
3299c6e6d4bSIdo Barnea                if dual_if.client_if.get_dest_mac():
3309c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
3319c6e6d4bSIdo Barnea                        mode = unconfig_str,
332a6e3bf69SIdo Barnea                        next_hop = server_net_next_hop,
3339c6e6d4bSIdo Barnea                        dest_mac = dual_if.client_if.get_dest_mac()))
3349c6e6d4bSIdo Barnea                if dual_if.server_if.get_dest_mac():
3359c6e6d4bSIdo Barnea                    conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
3369c6e6d4bSIdo Barnea                        mode = unconfig_str,
337a6e3bf69SIdo Barnea                        next_hop = client_net_next_hop,
3389c6e6d4bSIdo Barnea                        dest_mac = dual_if.server_if.get_dest_mac()))
339823b8294SYaroslav Brustinov
340823b8294SYaroslav Brustinov            # bump up to the next client network address
341823b8294SYaroslav Brustinov            client_net = misc_methods.get_single_net_client_addr(client_net, stat_route_obj.net_increment)
342823b8294SYaroslav Brustinov            server_net = misc_methods.get_single_net_client_addr(server_net, stat_route_obj.net_increment)
343823b8294SYaroslav Brustinov
344823b8294SYaroslav Brustinov
345823b8294SYaroslav Brustinov        # finish handling pre-config cache
346823b8294SYaroslav Brustinov        pre_commit_set = list(pre_commit_set)
347cc53c3d2SYaroslav Brustinov        if len(pre_commit_set):
348cc53c3d2SYaroslav Brustinov            pre_commit_set.append('exit')
349823b8294SYaroslav Brustinov        pre_commit_cache.add('CONF', pre_commit_set )
350823b8294SYaroslav Brustinov        # assign generated config list to cache
351823b8294SYaroslav Brustinov        cache.add('CONF', conf_t_command_set)
352823b8294SYaroslav Brustinov        # deploy the configs (order is important!)
353823b8294SYaroslav Brustinov        self.cmd_link.run_command( [pre_commit_cache, cache] )
354823b8294SYaroslav Brustinov        if self.config_history['basic_if_config']:
355a6e3bf69SIdo Barnea            # in this case, duplicated interfaces will lose its ip address.
356823b8294SYaroslav Brustinov            # re-config IPv4 addresses
35798aa7529SYaroslav Brustinov            self.configure_basic_filtered_interfaces(self.if_mngr.get_duplicated_if())
358823b8294SYaroslav Brustinov
359823b8294SYaroslav Brustinov
360823b8294SYaroslav Brustinov    def config_no_static_routing (self, stat_route_obj = None):
361823b8294SYaroslav Brustinov
362823b8294SYaroslav Brustinov        if stat_route_obj is None and self.stat_route_config is not None:
363823b8294SYaroslav Brustinov            self.config_static_routing(self.stat_route_config, mode = 'unconfig')
364823b8294SYaroslav Brustinov            self.stat_route_config = None  # reverse current static route config back to None (no nat config is known to run).
365823b8294SYaroslav Brustinov        elif stat_route_obj is not None:
366823b8294SYaroslav Brustinov            self.config_static_routing(stat_route_obj, mode = 'unconfig')
367823b8294SYaroslav Brustinov        else:
368823b8294SYaroslav Brustinov            raise UserWarning('No static route configuration is available for removal.')
369823b8294SYaroslav Brustinov
370823b8294SYaroslav Brustinov    def config_nbar_pd (self, mode = 'config'):
371823b8294SYaroslav Brustinov        unconfig_str = '' if mode=='config' else 'no '
372823b8294SYaroslav Brustinov        cache = CCommandCache()
373823b8294SYaroslav Brustinov
374823b8294SYaroslav Brustinov        for intf in self.if_mngr.get_if_list(if_type = IFType.Client):
375823b8294SYaroslav Brustinov            cache.add('IF', "{mode}ip nbar protocol-discovery".format( mode = unconfig_str ), intf.get_name())
376823b8294SYaroslav Brustinov
377823b8294SYaroslav Brustinov        self.cmd_link.run_single_command( cache )
378823b8294SYaroslav Brustinov
379823b8294SYaroslav Brustinov    def config_no_nbar_pd (self):
380823b8294SYaroslav Brustinov        self.config_nbar_pd (mode = 'unconfig')
381823b8294SYaroslav Brustinov
382823b8294SYaroslav Brustinov
383823b8294SYaroslav Brustinov    def config_nat_verify (self, mode = 'config'):
384823b8294SYaroslav Brustinov
385823b8294SYaroslav Brustinov        # toggle all duplicate interfaces
386823b8294SYaroslav Brustinov        # dup_ifs = self.if_mngr.get_duplicated_if()
387823b8294SYaroslav Brustinov        if mode=='config':
388823b8294SYaroslav Brustinov            self.toggle_duplicated_intf(action = 'down')
389823b8294SYaroslav Brustinov            # self.__toggle_interfaces(dup_ifs, action = 'down' )
390823b8294SYaroslav Brustinov        else:
391823b8294SYaroslav Brustinov            # if we're in 'unconfig', toggle duplicated interfaces back up
392823b8294SYaroslav Brustinov            self.toggle_duplicated_intf(action = 'up')
393823b8294SYaroslav Brustinov            # self.__toggle_interfaces(dup_ifs)
394823b8294SYaroslav Brustinov
395823b8294SYaroslav Brustinov    def config_no_nat_verify (self):
396823b8294SYaroslav Brustinov        self.config_nat_verify(mode = 'unconfig')
397823b8294SYaroslav Brustinov
398823b8294SYaroslav Brustinov    def config_nat (self, nat_obj, mode = 'config'):
399823b8294SYaroslav Brustinov
400823b8294SYaroslav Brustinov        if mode == 'config':
401823b8294SYaroslav Brustinov            self.nat_config = nat_obj   # save the latest nat config for future removal purposes
402823b8294SYaroslav Brustinov
403823b8294SYaroslav Brustinov        cache               = CCommandCache()
404823b8294SYaroslav Brustinov        conf_t_command_set  = []
405823b8294SYaroslav Brustinov        client_net          = nat_obj.clients_net_start
406823b8294SYaroslav Brustinov        pool_net            = nat_obj.nat_pool_start
407823b8294SYaroslav Brustinov        unconfig_str        = '' if mode=='config' else 'no '
408823b8294SYaroslav Brustinov
409823b8294SYaroslav Brustinov        # toggle all duplicate interfaces
410823b8294SYaroslav Brustinov        # dup_ifs = self.if_mngr.get_duplicated_if()
411823b8294SYaroslav Brustinov        if mode=='config':
412823b8294SYaroslav Brustinov            self.toggle_duplicated_intf(action = 'down')
413823b8294SYaroslav Brustinov            # self.__toggle_interfaces(dup_ifs, action = 'down' )
414823b8294SYaroslav Brustinov        else:
415823b8294SYaroslav Brustinov            # if we're in 'unconfig', toggle duplicated interfaces back up
416823b8294SYaroslav Brustinov            self.toggle_duplicated_intf(action = 'up')
417823b8294SYaroslav Brustinov            # self.__toggle_interfaces(dup_ifs)
418823b8294SYaroslav Brustinov
419823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list(is_duplicated = False):
420823b8294SYaroslav Brustinov            cache.add('IF', "{mode}ip nat inside".format( mode = unconfig_str ), dual_if.client_if.get_name())
421823b8294SYaroslav Brustinov            cache.add('IF', "{mode}ip nat outside".format( mode = unconfig_str ), dual_if.server_if.get_name())
422823b8294SYaroslav Brustinov            pool_id = dual_if.get_id() + 1
423823b8294SYaroslav Brustinov
424823b8294SYaroslav Brustinov            conf_t_command_set.append("{mode}ip nat pool pool{pool_num} {start_addr} {end_addr} netmask {mask}".format(
425823b8294SYaroslav Brustinov                mode = unconfig_str,
426823b8294SYaroslav Brustinov                pool_num = pool_id,
427823b8294SYaroslav Brustinov                start_addr = pool_net,
428823b8294SYaroslav Brustinov                end_addr = CNatConfig.calc_pool_end(pool_net, nat_obj.nat_netmask),
429823b8294SYaroslav Brustinov                mask = nat_obj.nat_netmask))
430823b8294SYaroslav Brustinov
431823b8294SYaroslav Brustinov            conf_t_command_set.append("{mode}ip nat inside source list {num} pool pool{pool_num} overload".format(
432823b8294SYaroslav Brustinov                mode = unconfig_str,
433823b8294SYaroslav Brustinov                num = pool_id,
434823b8294SYaroslav Brustinov                pool_num = pool_id ))
435823b8294SYaroslav Brustinov            conf_t_command_set.append("{mode}access-list {num} permit {net_addr} {net_wildcard}".format(
436823b8294SYaroslav Brustinov                mode = unconfig_str,
437823b8294SYaroslav Brustinov                num = pool_id,
438823b8294SYaroslav Brustinov                net_addr = client_net,
439823b8294SYaroslav Brustinov                net_wildcard = nat_obj.client_acl_wildcard))
440823b8294SYaroslav Brustinov
441823b8294SYaroslav Brustinov            # bump up to the next client address
442823b8294SYaroslav Brustinov            client_net = misc_methods.get_single_net_client_addr(client_net, nat_obj.net_increment)
443823b8294SYaroslav Brustinov            pool_net   = misc_methods.get_single_net_client_addr(pool_net, nat_obj.net_increment)
444823b8294SYaroslav Brustinov
445823b8294SYaroslav Brustinov
446823b8294SYaroslav Brustinov        # assign generated config list to cache
447823b8294SYaroslav Brustinov        cache.add('CONF', conf_t_command_set)
448823b8294SYaroslav Brustinov
449823b8294SYaroslav Brustinov        # deploy the configs (order is important!)
4509c1dfed4SYaroslav Brustinov        return self.cmd_link.run_single_command( cache )
451823b8294SYaroslav Brustinov
452823b8294SYaroslav Brustinov
453823b8294SYaroslav Brustinov    def config_no_nat (self, nat_obj = None):
454823b8294SYaroslav Brustinov        # first, clear all nat translations
455823b8294SYaroslav Brustinov        self.clear_nat_translations()
456823b8294SYaroslav Brustinov
457823b8294SYaroslav Brustinov        # then, decompose the known config
458823b8294SYaroslav Brustinov        if nat_obj is None and self.nat_config is not None:
459823b8294SYaroslav Brustinov            self.config_nat(self.nat_config, mode = 'unconfig')
460823b8294SYaroslav Brustinov            self.nat_config = None  # reverse current NAT config back to None (no nat config is known to run).
461823b8294SYaroslav Brustinov        elif nat_obj is not None:
462823b8294SYaroslav Brustinov            self.config_nat(nat_obj, mode = 'unconfig')
463823b8294SYaroslav Brustinov        else:
464823b8294SYaroslav Brustinov            raise UserWarning('No NAT configuration is available for removal.')
465823b8294SYaroslav Brustinov
466823b8294SYaroslav Brustinov
467823b8294SYaroslav Brustinov    def config_zbf (self, mode = 'config'):
468823b8294SYaroslav Brustinov        cache               = CCommandCache()
469823b8294SYaroslav Brustinov        pre_commit_cache    = CCommandCache()
470a6e3bf69SIdo Barnea        conf_t_command_set  = []
471823b8294SYaroslav Brustinov
472823b8294SYaroslav Brustinov        # toggle all duplicate interfaces down
473823b8294SYaroslav Brustinov        self.toggle_duplicated_intf(action = 'down')
474823b8294SYaroslav Brustinov        # dup_ifs = self.if_mngr.get_duplicated_if()
475823b8294SYaroslav Brustinov        # self.__toggle_interfaces(dup_ifs, action = 'down' )
476823b8294SYaroslav Brustinov
477823b8294SYaroslav Brustinov        # define security zones and security service policy to be applied on the interfaces
478823b8294SYaroslav Brustinov        conf_t_command_set.append('class-map type inspect match-any c1')
479823b8294SYaroslav Brustinov        conf_t_command_set.append('match protocol tcp')
480823b8294SYaroslav Brustinov        conf_t_command_set.append('match protocol udp')
481823b8294SYaroslav Brustinov        conf_t_command_set.append('policy-map type inspect p1')
482823b8294SYaroslav Brustinov        conf_t_command_set.append('class type inspect c1')
483823b8294SYaroslav Brustinov        conf_t_command_set.append('inspect')
484823b8294SYaroslav Brustinov        conf_t_command_set.append('class class-default')
485823b8294SYaroslav Brustinov        conf_t_command_set.append('pass')
486823b8294SYaroslav Brustinov
487823b8294SYaroslav Brustinov        conf_t_command_set.append('zone security z_in')
488823b8294SYaroslav Brustinov        conf_t_command_set.append('zone security z_out')
489823b8294SYaroslav Brustinov
490823b8294SYaroslav Brustinov        conf_t_command_set.append('zone-pair security in2out source z_in destination z_out')
491823b8294SYaroslav Brustinov        conf_t_command_set.append('service-policy type inspect p1')
492823b8294SYaroslav Brustinov        conf_t_command_set.append('zone-pair security out2in source z_out destination z_in')
493823b8294SYaroslav Brustinov        conf_t_command_set.append('service-policy type inspect p1')
494823b8294SYaroslav Brustinov        conf_t_command_set.append('exit')
495823b8294SYaroslav Brustinov
496823b8294SYaroslav Brustinov        pre_commit_cache.add('CONF', conf_t_command_set)
497823b8294SYaroslav Brustinov
498823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list(is_duplicated = False):
499823b8294SYaroslav Brustinov            cache.add('IF', "zone-member security z_in", dual_if.client_if.get_name() )
500823b8294SYaroslav Brustinov            cache.add('IF', "zone-member security z_out", dual_if.server_if.get_name() )
501823b8294SYaroslav Brustinov
502823b8294SYaroslav Brustinov        self.cmd_link.run_command( [pre_commit_cache, cache] )
503823b8294SYaroslav Brustinov
504823b8294SYaroslav Brustinov    def config_no_zbf (self):
505823b8294SYaroslav Brustinov        cache               = CCommandCache()
506a6e3bf69SIdo Barnea        conf_t_command_set  = []
507823b8294SYaroslav Brustinov
508823b8294SYaroslav Brustinov        # define security zones and security service policy to be applied on the interfaces
509823b8294SYaroslav Brustinov        conf_t_command_set.append('no zone-pair security in2out source z_in destination z_out')
510823b8294SYaroslav Brustinov        conf_t_command_set.append('no zone-pair security out2in source z_out destination z_in')
511823b8294SYaroslav Brustinov
512823b8294SYaroslav Brustinov        conf_t_command_set.append('no policy-map type inspect p1')
513823b8294SYaroslav Brustinov        conf_t_command_set.append('no class-map type inspect match-any c1')
514823b8294SYaroslav Brustinov
515823b8294SYaroslav Brustinov        conf_t_command_set.append('no zone security z_in')
516823b8294SYaroslav Brustinov        conf_t_command_set.append('no zone security z_out')
517823b8294SYaroslav Brustinov
518823b8294SYaroslav Brustinov        cache.add('CONF', conf_t_command_set)
519823b8294SYaroslav Brustinov
520823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list(is_duplicated = False):
521823b8294SYaroslav Brustinov            cache.add('IF', "no zone-member security z_in", dual_if.client_if.get_name() )
522823b8294SYaroslav Brustinov            cache.add('IF', "no zone-member security z_out", dual_if.server_if.get_name() )
523823b8294SYaroslav Brustinov
524823b8294SYaroslav Brustinov        self.cmd_link.run_command( [cache] )
525823b8294SYaroslav Brustinov        # toggle all duplicate interfaces back up
526823b8294SYaroslav Brustinov        self.toggle_duplicated_intf(action = 'up')
527823b8294SYaroslav Brustinov        # dup_ifs = self.if_mngr.get_duplicated_if()
528823b8294SYaroslav Brustinov        # self.__toggle_interfaces(dup_ifs)
529823b8294SYaroslav Brustinov
530823b8294SYaroslav Brustinov
531a6e3bf69SIdo Barnea    def config_ipv6_pbr (self, mode = 'config', vlan=False):
532823b8294SYaroslav Brustinov        idx = 1
533823b8294SYaroslav Brustinov        unconfig_str = '' if mode=='config' else 'no '
534823b8294SYaroslav Brustinov        cache               = CCommandCache()
535823b8294SYaroslav Brustinov        conf_t_command_set  = []
536823b8294SYaroslav Brustinov
537823b8294SYaroslav Brustinov        conf_t_command_set.append('{mode}ipv6 unicast-routing'.format(mode = unconfig_str) )
538823b8294SYaroslav Brustinov
539823b8294SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list():
540823b8294SYaroslav Brustinov            client_if_command_set   = []
541823b8294SYaroslav Brustinov            server_if_command_set   = []
542a6e3bf69SIdo Barnea
543823b8294SYaroslav Brustinov            client_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.server_if.get_ipv6_addr(), {'7':1}, ip_type = 'ipv6' )
544823b8294SYaroslav Brustinov            server_net_next_hop = misc_methods.get_single_net_client_addr(dual_if.client_if.get_ipv6_addr(), {'7':1}, ip_type = 'ipv6' )
545e1969be5SIdo Barnea            client_net_next_hop_v4 = misc_methods.get_single_net_client_addr(dual_if.server_if.get_ipv4_addr() )
546e1969be5SIdo Barnea            server_net_next_hop_v4 = misc_methods.get_single_net_client_addr(dual_if.client_if.get_ipv4_addr() )
547823b8294SYaroslav Brustinov
548823b8294SYaroslav Brustinov
549823b8294SYaroslav Brustinov            client_if_command_set.append ('{mode}ipv6 enable'.format(mode = unconfig_str))
550823b8294SYaroslav Brustinov            server_if_command_set.append ('{mode}ipv6 enable'.format(mode = unconfig_str))
551823b8294SYaroslav Brustinov
552823b8294SYaroslav Brustinov            if dual_if.is_duplicated():
553823b8294SYaroslav Brustinov                prefix = 'ipv6_' + dual_if.get_vrf_name()
554823b8294SYaroslav Brustinov            else:
555823b8294SYaroslav Brustinov                prefix = 'ipv6'
556a6e3bf69SIdo Barnea
557823b8294SYaroslav Brustinov            # config interfaces with relevant route-map
558a6e3bf69SIdo Barnea            client_if_command_set.append ('{mode}ipv6 policy route-map {pre}_{p1}_to_{p2}'.format(
559823b8294SYaroslav Brustinov                mode = unconfig_str,
560a6e3bf69SIdo Barnea                pre = prefix,
561823b8294SYaroslav Brustinov                p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
562a6e3bf69SIdo Barnea            server_if_command_set.append ('{mode}ipv6 policy route-map {pre}_{p2}_to_{p1}'.format(
563823b8294SYaroslav Brustinov                mode = unconfig_str,
564a6e3bf69SIdo Barnea                pre = prefix,
565823b8294SYaroslav Brustinov                p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
566823b8294SYaroslav Brustinov
567823b8294SYaroslav Brustinov            # config global arp to interfaces net address and vrf
56868c71be2SIdo Barnea            if dual_if.client_if.get_ipv6_dest_mac():
5699c6e6d4bSIdo Barnea                conf_t_command_set.append('{mode}ipv6 neighbor {next_hop} {intf} {dest_mac}'.format(
570823b8294SYaroslav Brustinov                    mode = unconfig_str,
571a6e3bf69SIdo Barnea                    next_hop = server_net_next_hop,
572823b8294SYaroslav Brustinov                    intf = dual_if.client_if.get_name(),
57368c71be2SIdo Barnea                    dest_mac = dual_if.client_if.get_ipv6_dest_mac()))
574e1969be5SIdo Barnea                # For latency packets (which are IPv4), we need to configure also static ARP
575e1969be5SIdo Barnea                conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
576e1969be5SIdo Barnea                    mode = unconfig_str,
577e1969be5SIdo Barnea                    next_hop = server_net_next_hop_v4,
578e1969be5SIdo Barnea                    dest_mac = dual_if.client_if.get_ipv6_dest_mac()))
579e1969be5SIdo Barnea
58068c71be2SIdo Barnea            if dual_if.server_if.get_ipv6_dest_mac():
5819c6e6d4bSIdo Barnea                conf_t_command_set.append('{mode}ipv6 neighbor {next_hop} {intf} {dest_mac}'.format(
582823b8294SYaroslav Brustinov                    mode = unconfig_str,
583e1969be5SIdo Barnea                    next_hop = client_net_next_hop,
584823b8294SYaroslav Brustinov                    intf = dual_if.server_if.get_name(),
58568c71be2SIdo Barnea                    dest_mac = dual_if.server_if.get_ipv6_dest_mac()))
586e1969be5SIdo Barnea                # For latency packets (which are IPv4), we need to configure also static ARP
587e1969be5SIdo Barnea                conf_t_command_set.append('{mode}arp {next_hop} {dest_mac} arpa'.format(
588e1969be5SIdo Barnea                        mode = unconfig_str,
589e1969be5SIdo Barnea                        next_hop = client_net_next_hop_v4,
590e1969be5SIdo Barnea                        dest_mac = dual_if.server_if.get_ipv6_dest_mac()))
591823b8294SYaroslav Brustinov
592823b8294SYaroslav Brustinov            conf_t_command_set.append('{mode}route-map {pre}_{p1}_to_{p2} permit 10'.format(
593823b8294SYaroslav Brustinov                    mode = unconfig_str,
594823b8294SYaroslav Brustinov                    pre = prefix,
595823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
596823b8294SYaroslav Brustinov            if (mode == 'config'):
597823b8294SYaroslav Brustinov                conf_t_command_set.append('set ipv6 next-hop {next_hop}'.format(next_hop = client_net_next_hop ) )
598823b8294SYaroslav Brustinov            conf_t_command_set.append('{mode}route-map {pre}_{p2}_to_{p1} permit 10'.format(
599823b8294SYaroslav Brustinov                    mode = unconfig_str,
600823b8294SYaroslav Brustinov                    pre = prefix,
601823b8294SYaroslav Brustinov                    p1 = 'p'+str(idx), p2 = 'p'+str(idx+1) ) )
602823b8294SYaroslav Brustinov            if (mode == 'config'):
603823b8294SYaroslav Brustinov                conf_t_command_set.append('set ipv6 next-hop {next_hop}'.format(next_hop = server_net_next_hop ) )
604823b8294SYaroslav Brustinov                conf_t_command_set.append('exit')
605823b8294SYaroslav Brustinov
606823b8294SYaroslav Brustinov            # assign generated config list to cache
607a6e3bf69SIdo Barnea            client_if_name = dual_if.client_if.get_name()
608a6e3bf69SIdo Barnea            server_if_name = dual_if.server_if.get_name()
609a6e3bf69SIdo Barnea            if vlan:
610a6e3bf69SIdo Barnea                client_if_name += "." + self.client_vlan
611a6e3bf69SIdo Barnea                server_if_name += "." + self.server_vlan
612a6e3bf69SIdo Barnea
613a6e3bf69SIdo Barnea            cache.add('IF', server_if_command_set, server_if_name)
614a6e3bf69SIdo Barnea            cache.add('IF', client_if_command_set, client_if_name)
615a6e3bf69SIdo Barnea
616823b8294SYaroslav Brustinov            idx += 2
617823b8294SYaroslav Brustinov
618823b8294SYaroslav Brustinov        cache.add('CONF', conf_t_command_set)
619a6e3bf69SIdo Barnea
620823b8294SYaroslav Brustinov        # deploy the configs (order is important!)
621823b8294SYaroslav Brustinov        self.cmd_link.run_command( [cache] )
622823b8294SYaroslav Brustinov
623a6e3bf69SIdo Barnea    def config_no_ipv6_pbr (self, vlan = False):
624a6e3bf69SIdo Barnea        self.config_ipv6_pbr(mode = 'unconfig', vlan = vlan)
625823b8294SYaroslav Brustinov
626823b8294SYaroslav Brustinov    # show methods
627823b8294SYaroslav Brustinov    def get_cpu_util (self):
628823b8294SYaroslav Brustinov        response    = self.cmd_link.run_single_command('show platform hardware qfp active datapath utilization | inc Load')
629823b8294SYaroslav Brustinov        return CShowParser.parse_cpu_util_stats(response)
630823b8294SYaroslav Brustinov
631823b8294SYaroslav Brustinov    def get_cft_stats (self):
632823b8294SYaroslav Brustinov        response    = self.cmd_link.run_single_command('test platform hardware qfp active infrastructure cft datapath function cft-cpp-show-all-instances')
633823b8294SYaroslav Brustinov        return CShowParser.parse_cft_stats(response)
634823b8294SYaroslav Brustinov
635823b8294SYaroslav Brustinov    def get_nbar_stats (self):
636823b8294SYaroslav Brustinov        per_intf_stats = {}
637823b8294SYaroslav Brustinov        for intf in self.if_mngr.get_if_list(if_type = IFType.Client):
638823b8294SYaroslav Brustinov            response = self.cmd_link.run_single_command("show ip nbar protocol-discovery interface {interface} stats packet-count protocol".format( interface = intf.get_name() ), flush_first = True)
639823b8294SYaroslav Brustinov            per_intf_stats[intf.get_name()] = CShowParser.parse_nbar_stats(response)
640823b8294SYaroslav Brustinov        return per_intf_stats
641823b8294SYaroslav Brustinov
642823b8294SYaroslav Brustinov    def get_nbar_profiling_stats (self):
643823b8294SYaroslav Brustinov        response = self.cmd_link.run_single_command("show platform hardware qfp active feature nbar profiling")
644823b8294SYaroslav Brustinov        return CShowParser.parse_nbar_profiling_stats(response)
645823b8294SYaroslav Brustinov
646823b8294SYaroslav Brustinov    def get_drop_stats (self):
647823b8294SYaroslav Brustinov
648823b8294SYaroslav Brustinov        response    = self.cmd_link.run_single_command('show platform hardware qfp active interface all statistics', flush_first = True)
649823b8294SYaroslav Brustinov        # print response
650823b8294SYaroslav Brustinov        # response    = self.cmd_link.run_single_command('show platform hardware qfp active interface all statistics')
651823b8294SYaroslav Brustinov        # print response
652501fb3b4SYaroslav Brustinov        if_list_by_name = [x.get_name() for x in self.if_mngr.get_if_list()]
653823b8294SYaroslav Brustinov        return CShowParser.parse_drop_stats(response, if_list_by_name )
654823b8294SYaroslav Brustinov
655823b8294SYaroslav Brustinov    def get_nat_stats (self):
656823b8294SYaroslav Brustinov        response    = self.cmd_link.run_single_command('show ip nat statistics')
657823b8294SYaroslav Brustinov        return CShowParser.parse_nat_stats(response)
658823b8294SYaroslav Brustinov
6599c1dfed4SYaroslav Brustinov    def get_nat_trans (self):
6609c1dfed4SYaroslav Brustinov        return self.cmd_link.run_single_command('show ip nat translation')
6619c1dfed4SYaroslav Brustinov
662823b8294SYaroslav Brustinov    def get_cvla_memory_usage(self):
663823b8294SYaroslav Brustinov        response    = self.cmd_link.run_single_command('show platform hardware qfp active infrastructure cvla client handles')
664823b8294SYaroslav Brustinov        # (res, res2) = CShowParser.parse_cvla_memory_usage(response)
665823b8294SYaroslav Brustinov        return CShowParser.parse_cvla_memory_usage(response)
666823b8294SYaroslav Brustinov
667823b8294SYaroslav Brustinov
668823b8294SYaroslav Brustinov    # clear methods
669823b8294SYaroslav Brustinov    def clear_nat_translations(self):
670823b8294SYaroslav Brustinov        pre_commit_cache = CCommandCache()
6719c1dfed4SYaroslav Brustinov        # prevent new NAT entries
6729c1dfed4SYaroslav Brustinov        # http://www.cisco.com/c/en/us/support/docs/ip/network-address-translation-nat/13779-clear-nat-comments.html
6739c1dfed4SYaroslav Brustinov        for dual_if in self.if_mngr.get_dual_if_list(is_duplicated = False):
6749c1dfed4SYaroslav Brustinov            pre_commit_cache.add('IF', "no ip nat inside", dual_if.client_if.get_name())
6759c1dfed4SYaroslav Brustinov            pre_commit_cache.add('IF', "no ip nat outside", dual_if.server_if.get_name())
676ec23dc1aSYaroslav Brustinov        self.cmd_link.run_single_command(pre_commit_cache)
677ec23dc1aSYaroslav Brustinov        time.sleep(0.5)
678ec23dc1aSYaroslav Brustinov        pre_commit_cache = CCommandCache()
6799c1dfed4SYaroslav Brustinov        # clear the translation
680823b8294SYaroslav Brustinov        pre_commit_cache.add('EXEC', 'clear ip nat translation *')
6819c1dfed4SYaroslav Brustinov        self.cmd_link.run_single_command(pre_commit_cache)
682ec23dc1aSYaroslav Brustinov        time.sleep(0.5)
683823b8294SYaroslav Brustinov
684823b8294SYaroslav Brustinov    def clear_cft_counters (self):
685823b8294SYaroslav Brustinov        """ clear_cft_counters(self) -> None
686823b8294SYaroslav Brustinov
687823b8294SYaroslav Brustinov        Clears the CFT counters on the platform
688823b8294SYaroslav Brustinov        """
689823b8294SYaroslav Brustinov        self.cmd_link.run_single_command('test platform hardware qfp active infrastructure cft datapath function cft-cpp-clear-instance-stats')
690823b8294SYaroslav Brustinov
691823b8294SYaroslav Brustinov    def clear_counters(self):
692823b8294SYaroslav Brustinov        """ clear_counters(self) -> None
693823b8294SYaroslav Brustinov
694823b8294SYaroslav Brustinov        Clears the platform counters
695823b8294SYaroslav Brustinov        """
696823b8294SYaroslav Brustinov
697823b8294SYaroslav Brustinov        pre_commit_cache = CCommandCache()
6986c46ecabSYaroslav Brustinov        pre_commit_cache.add('EXEC', ['clear counters', '\r'] )
6996c46ecabSYaroslav Brustinov        self.cmd_link.run_single_command( pre_commit_cache , read_until = ['#', '\[confirm\]'])
700823b8294SYaroslav Brustinov
701823b8294SYaroslav Brustinov    def clear_nbar_stats(self):
702823b8294SYaroslav Brustinov        """ clear_nbar_stats(self) -> None
703823b8294SYaroslav Brustinov
704823b8294SYaroslav Brustinov        Clears the NBAR-PD classification stats
705823b8294SYaroslav Brustinov        """
706823b8294SYaroslav Brustinov        pre_commit_cache = CCommandCache()
707823b8294SYaroslav Brustinov        pre_commit_cache.add('EXEC', ['clear ip nbar protocol-discovery','\r'] )
708823b8294SYaroslav Brustinov        self.cmd_link.run_single_command( pre_commit_cache )
709823b8294SYaroslav Brustinov
710823b8294SYaroslav Brustinov    def clear_packet_drop_stats(self):
711823b8294SYaroslav Brustinov        """ clear_packet_drop_stats(self) -> None
712823b8294SYaroslav Brustinov
713823b8294SYaroslav Brustinov        Clears packet-drop stats
714823b8294SYaroslav Brustinov        """
715823b8294SYaroslav Brustinov#       command = "show platform hardware qfp active statistics drop clear"
716823b8294SYaroslav Brustinov        self.cmd_link.run_single_command('show platform hardware qfp active interface all statistics clear_drop')
717823b8294SYaroslav Brustinov
718823b8294SYaroslav Brustinov    ###########################################
719823b8294SYaroslav Brustinov    # file transfer and image loading methods #
720823b8294SYaroslav Brustinov    ###########################################
721823b8294SYaroslav Brustinov    def get_running_image_details (self):
722823b8294SYaroslav Brustinov        """ get_running_image_details() -> dict
723823b8294SYaroslav Brustinov
724823b8294SYaroslav Brustinov        Check for the currently running image file on the platform.
725823b8294SYaroslav Brustinov        Returns a dictionary, where 'drive' key is the drive in which the image is installed,
726823b8294SYaroslav Brustinov        and 'image' key is the actual image file used.
727823b8294SYaroslav Brustinov        """
728823b8294SYaroslav Brustinov        response = self.cmd_link.run_single_command('show version | include System image')
729823b8294SYaroslav Brustinov        parsed_info = CShowParser.parse_show_image_version(response)
730823b8294SYaroslav Brustinov        self.running_image = parsed_info
731823b8294SYaroslav Brustinov        return parsed_info
732a6e3bf69SIdo Barnea
733823b8294SYaroslav Brustinov
734823b8294SYaroslav Brustinov    def check_image_existence (self, img_name):
735823b8294SYaroslav Brustinov        """ check_image_existence(self, img_name) -> boolean
736823b8294SYaroslav Brustinov
737823b8294SYaroslav Brustinov        Parameters
738823b8294SYaroslav Brustinov        ----------
739823b8294SYaroslav Brustinov        img_name : str
740823b8294SYaroslav Brustinov            a string represents the image name.
741823b8294SYaroslav Brustinov
742823b8294SYaroslav Brustinov        Check if the image file defined in the platform_config already loaded into the platform.
743823b8294SYaroslav Brustinov        """
744823b8294SYaroslav Brustinov        search_drives = ['bootflash', 'harddisk', self.running_image['drive']]
745823b8294SYaroslav Brustinov        for search_drive in search_drives:
746823b8294SYaroslav Brustinov            command = "dir {drive}: | include {image}".format(drive = search_drive, image = img_name)
747823b8294SYaroslav Brustinov            response = self.cmd_link.run_single_command(command, timeout = 10)
748823b8294SYaroslav Brustinov            if CShowParser.parse_image_existence(response, img_name):
74959f00264SYaroslav Brustinov                self.needed_image_path = '%s:/%s' % (search_drive, img_name)
7501a935f29SYaroslav Brustinov                print('Found image in platform:', self.needed_image_path)
751823b8294SYaroslav Brustinov                return True
752823b8294SYaroslav Brustinov        return False
753823b8294SYaroslav Brustinov
754823b8294SYaroslav Brustinov    def config_tftp_server(self, device_cfg_obj, external_tftp_config = None, applyToPlatform = False):
755823b8294SYaroslav Brustinov        """ configure_tftp_server(self, external_tftp_config, applyToPlatform) -> str
756823b8294SYaroslav Brustinov
757823b8294SYaroslav Brustinov        Parameters
758823b8294SYaroslav Brustinov        ----------
759823b8294SYaroslav Brustinov        external_tftp_config : dict (Not is use)
760823b8294SYaroslav Brustinov            A path to external tftp config file other than using the one defined in the instance.
761823b8294SYaroslav Brustinov        applyToPlatform : boolean
762823b8294SYaroslav Brustinov            set to True in order to apply the config into the platform
763823b8294SYaroslav Brustinov
764823b8294SYaroslav Brustinov        Configures the tftp server on an interface of the platform.
765823b8294SYaroslav Brustinov        """
766823b8294SYaroslav Brustinov#       tmp_tftp_config = external_tftp_config if external_tftp_config is not None else self.tftp_server_config
767823b8294SYaroslav Brustinov        self.tftp_cfg   = device_cfg_obj.get_tftp_info()
768823b8294SYaroslav Brustinov        cache           = CCommandCache()
769a6e3bf69SIdo Barnea
770823b8294SYaroslav Brustinov        command = "ip tftp source-interface {intf}".format( intf = device_cfg_obj.get_mgmt_interface() )
771823b8294SYaroslav Brustinov        cache.add('CONF', command )
772823b8294SYaroslav Brustinov        self.cmd_link.run_single_command(cache)
773823b8294SYaroslav Brustinov        self.config_history['tftp_server_config'] = True
774823b8294SYaroslav Brustinov
775823b8294SYaroslav Brustinov    def load_platform_image(self, img_filename, external_tftp_config = None):
776823b8294SYaroslav Brustinov        """ load_platform_image(self, img_filename, external_tftp_config) -> None
777823b8294SYaroslav Brustinov
778823b8294SYaroslav Brustinov        Parameters
779823b8294SYaroslav Brustinov        ----------
780823b8294SYaroslav Brustinov        external_tftp_config : dict
781823b8294SYaroslav Brustinov            A path to external tftp config file other than using the one defined in the instance.
782823b8294SYaroslav Brustinov        img_filename : str
783823b8294SYaroslav Brustinov            image name to be saved into the platforms drive.
784823b8294SYaroslav Brustinov
785823b8294SYaroslav Brustinov        This method loads the configured image into the platform's harddisk (unless it is already loaded),
786823b8294SYaroslav Brustinov        and sets that image to be the boot_image of the platform.
787823b8294SYaroslav Brustinov        """
788823b8294SYaroslav Brustinov        if not self.check_image_existence(img_filename): # check if this image isn't already saved in platform
789823b8294SYaroslav Brustinov            #tmp_tftp_config = external_tftp_config if external_tftp_config is not None else self.tftp_cfg
790a6e3bf69SIdo Barnea
791823b8294SYaroslav Brustinov            if self.config_history['tftp_server_config']:  # make sure a TFTP configuration has been loaded
792823b8294SYaroslav Brustinov                cache = CCommandCache()
793823b8294SYaroslav Brustinov                if self.running_image is None:
794823b8294SYaroslav Brustinov                    self.get_running_image_details()
795a6e3bf69SIdo Barnea
796f91190c7SYaroslav Brustinov                command = "copy tftp://{tftp_ip}/{img_path}/{image} bootflash:".format(
797823b8294SYaroslav Brustinov                    tftp_ip  = self.tftp_cfg['ip_address'],
798823b8294SYaroslav Brustinov                    img_path = self.tftp_cfg['images_path'],
799823b8294SYaroslav Brustinov                    image    = img_filename)
800823b8294SYaroslav Brustinov                cache.add('EXEC', [command, '\r', '\r'])
801823b8294SYaroslav Brustinov
802823b8294SYaroslav Brustinov                progress_thread = CProgressDisp.ProgressThread(notifyMessage = "Copying image via tftp, this may take a while...\n")
803823b8294SYaroslav Brustinov                progress_thread.start()
804823b8294SYaroslav Brustinov
8056c46ecabSYaroslav Brustinov                response = self.cmd_link.run_single_command(cache, timeout = 900, read_until = ['\?', '#'])
8061a935f29SYaroslav Brustinov                print("RESPONSE:")
8071a935f29SYaroslav Brustinov                print(response)
808823b8294SYaroslav Brustinov                progress_thread.join()
809823b8294SYaroslav Brustinov                copy_ok = CShowParser.parse_file_copy(response)
810823b8294SYaroslav Brustinov
811823b8294SYaroslav Brustinov                if not copy_ok:
812823b8294SYaroslav Brustinov                    raise UserWarning('Image file loading failed. Please make sure the accessed image exists and has read privileges')
813823b8294SYaroslav Brustinov            else:
814823b8294SYaroslav Brustinov                raise UserWarning('TFTP configuration is not available. Please make sure a valid TFTP configuration has been provided')
815823b8294SYaroslav Brustinov
816823b8294SYaroslav Brustinov    def set_boot_image(self, boot_image):
817823b8294SYaroslav Brustinov        """ set_boot_image(self, boot_image) -> None
818823b8294SYaroslav Brustinov
819823b8294SYaroslav Brustinov        Parameters
820823b8294SYaroslav Brustinov        ----------
821823b8294SYaroslav Brustinov        boot_image : str
822823b8294SYaroslav Brustinov            An image file to be set as boot_image
823823b8294SYaroslav Brustinov
824823b8294SYaroslav Brustinov        Configures boot_image as the boot image of the platform into the running-config + config-register
825823b8294SYaroslav Brustinov        """
826823b8294SYaroslav Brustinov        cache = CCommandCache()
827823b8294SYaroslav Brustinov        if self.needed_image_path is None:
828823b8294SYaroslav Brustinov            if not self.check_image_existence(boot_image):
829823b8294SYaroslav Brustinov                raise Exception("Trying to set boot image that's not found in router, please copy it first.")
830823b8294SYaroslav Brustinov
831823b8294SYaroslav Brustinov        boot_img_cmd = "boot system flash %s" % self.needed_image_path
832823b8294SYaroslav Brustinov        config_register_cmd = "config-register 0x2021"
83359f00264SYaroslav Brustinov        cache.add('CONF', ["no boot system", boot_img_cmd, config_register_cmd, '\r'])
83459f00264SYaroslav Brustinov        response = self.cmd_link.run_single_command( cache )
83559f00264SYaroslav Brustinov        print("RESPONSE:")
83659f00264SYaroslav Brustinov        print(response)
837823b8294SYaroslav Brustinov        self.save_config_to_startup_config()
838823b8294SYaroslav Brustinov
839823b8294SYaroslav Brustinov    def is_image_matches(self, needed_image):
840823b8294SYaroslav Brustinov        """ set_boot_image(self, needed_image) -> boolean
841823b8294SYaroslav Brustinov
842823b8294SYaroslav Brustinov        Parameters
843823b8294SYaroslav Brustinov        ----------
844823b8294SYaroslav Brustinov        needed_image : str
845823b8294SYaroslav Brustinov            An image file to compare router running image
846823b8294SYaroslav Brustinov
847823b8294SYaroslav Brustinov        Compares image name to router running image, returns match result.
848a6e3bf69SIdo Barnea
849823b8294SYaroslav Brustinov        """
850823b8294SYaroslav Brustinov        if self.running_image is None:
851823b8294SYaroslav Brustinov            self.get_running_image_details()
852823b8294SYaroslav Brustinov        needed_image = needed_image.lower()
853823b8294SYaroslav Brustinov        current_image = self.running_image['image'].lower()
854823b8294SYaroslav Brustinov        if needed_image.find(current_image) != -1:
855823b8294SYaroslav Brustinov            return True
856823b8294SYaroslav Brustinov        if current_image.find(needed_image) != -1:
857823b8294SYaroslav Brustinov            return True
858823b8294SYaroslav Brustinov        return False
859823b8294SYaroslav Brustinov
860823b8294SYaroslav Brustinov    # misc class related methods
861823b8294SYaroslav Brustinov
862823b8294SYaroslav Brustinov    def load_platform_data_from_file (self, device_cfg_obj):
863823b8294SYaroslav Brustinov        self.if_mngr.load_config(device_cfg_obj)
864823b8294SYaroslav Brustinov
865823b8294SYaroslav Brustinov    def launch_connection (self, device_cfg_obj):
866823b8294SYaroslav Brustinov        self.running_image = None # clear the image name "cache"
867823b8294SYaroslav Brustinov        self.cmd_link.launch_platform_connectivity(device_cfg_obj)
868823b8294SYaroslav Brustinov
869823b8294SYaroslav Brustinov    def reload_connection (self, device_cfg_obj):
870823b8294SYaroslav Brustinov        self.cmd_link.close_platform_connection()
871823b8294SYaroslav Brustinov        self.launch_connection(device_cfg_obj)
872823b8294SYaroslav Brustinov
873823b8294SYaroslav Brustinov    def save_config_to_startup_config (self):
874823b8294SYaroslav Brustinov        """ save_config_to_startup_config(self) -> None
875823b8294SYaroslav Brustinov
876823b8294SYaroslav Brustinov        Copies running-config into startup-config.
877823b8294SYaroslav Brustinov        """
87859f00264SYaroslav Brustinov        cache = CCommandCache()
87959f00264SYaroslav Brustinov        cache.add('EXEC', ['wr', '\r'] )
88059f00264SYaroslav Brustinov        self.cmd_link.run_single_command(cache)
881823b8294SYaroslav Brustinov
882823b8294SYaroslav Brustinov    def reload_platform(self, device_cfg_obj):
883823b8294SYaroslav Brustinov        """ reload_platform(self) -> None
884823b8294SYaroslav Brustinov
885823b8294SYaroslav Brustinov        Reloads the platform.
886823b8294SYaroslav Brustinov        """
887823b8294SYaroslav Brustinov        from subprocess import call
888823b8294SYaroslav Brustinov        import os
889823b8294SYaroslav Brustinov        i = 0
890823b8294SYaroslav Brustinov        sleep_time = 30 # seconds
891823b8294SYaroslav Brustinov
892a6e3bf69SIdo Barnea        try:
893823b8294SYaroslav Brustinov            cache = CCommandCache()
894823b8294SYaroslav Brustinov
895823b8294SYaroslav Brustinov            cache.add('EXEC', ['reload','n\r','\r'] )
896823b8294SYaroslav Brustinov            self.cmd_link.run_single_command( cache )
897823b8294SYaroslav Brustinov
898823b8294SYaroslav Brustinov            progress_thread = CProgressDisp.ProgressThread(notifyMessage = "Reloading the platform, this may take a while...\n")
899823b8294SYaroslav Brustinov            progress_thread.start()
900823b8294SYaroslav Brustinov            time.sleep(60) # need delay for device to shut down before polling it
901823b8294SYaroslav Brustinov            # poll the platform until ping response is received.
902823b8294SYaroslav Brustinov            while True:
903823b8294SYaroslav Brustinov                time.sleep(sleep_time)
904823b8294SYaroslav Brustinov                try:
905823b8294SYaroslav Brustinov                    x = call(["ping", "-c 1", device_cfg_obj.get_ip_address()], stdout = open(os.devnull, 'wb'))
906823b8294SYaroslav Brustinov                except:
907823b8294SYaroslav Brustinov                    x = 1
908823b8294SYaroslav Brustinov                if x == 0:
909823b8294SYaroslav Brustinov                    break
910823b8294SYaroslav Brustinov                elif i > 20:
911823b8294SYaroslav Brustinov                    raise TimeoutError('Platform failed to reload after reboot for over {minutes} minutes!'.format(minutes = round(1 + i * sleep_time / 60)))
912823b8294SYaroslav Brustinov                else:
913823b8294SYaroslav Brustinov                    i += 1
914a6e3bf69SIdo Barnea
915823b8294SYaroslav Brustinov            time.sleep(30)
916823b8294SYaroslav Brustinov            self.reload_connection(device_cfg_obj)
917823b8294SYaroslav Brustinov            progress_thread.join()
91859f00264SYaroslav Brustinov        except Exception as e:
919501fb3b4SYaroslav Brustinov            print(e)
920823b8294SYaroslav Brustinov
921823b8294SYaroslav Brustinov    def get_if_manager(self):
922823b8294SYaroslav Brustinov        return self.if_mngr
923823b8294SYaroslav Brustinov
924823b8294SYaroslav Brustinov    def dump_obj_config (self, object_name):
925823b8294SYaroslav Brustinov        if object_name=='nat' and self.nat_config is not None:
926823b8294SYaroslav Brustinov            self.nat_config.dump_config()
927823b8294SYaroslav Brustinov        elif object_name=='static_route' and self.stat_route_config is not None:
928823b8294SYaroslav Brustinov            self.stat_route_config.dump_config()
929823b8294SYaroslav Brustinov        else:
930823b8294SYaroslav Brustinov            raise UserWarning('No known configuration exists.')
931823b8294SYaroslav Brustinov
932823b8294SYaroslav Brustinov    def toggle_duplicated_intf(self, action = 'down'):
933823b8294SYaroslav Brustinov
934823b8294SYaroslav Brustinov        dup_ifs = self.if_mngr.get_duplicated_if()
935823b8294SYaroslav Brustinov        self.__toggle_interfaces( dup_ifs, action = action )
936823b8294SYaroslav Brustinov
937823b8294SYaroslav Brustinov
938823b8294SYaroslav Brustinov    def __toggle_interfaces (self, intf_list, action = 'up'):
939823b8294SYaroslav Brustinov        cache = CCommandCache()
940823b8294SYaroslav Brustinov        mode_str = 'no ' if action == 'up' else ''
941823b8294SYaroslav Brustinov
942823b8294SYaroslav Brustinov        for intf_obj in intf_list:
943823b8294SYaroslav Brustinov            cache.add('IF', '{mode}shutdown'.format(mode = mode_str), intf_obj.get_name())
944823b8294SYaroslav Brustinov
945823b8294SYaroslav Brustinov        self.cmd_link.run_single_command( cache )
946823b8294SYaroslav Brustinov
947823b8294SYaroslav Brustinov
948823b8294SYaroslav Brustinovclass CStaticRouteConfig(object):
949823b8294SYaroslav Brustinov
950823b8294SYaroslav Brustinov    def __init__(self, static_route_dict):
951823b8294SYaroslav Brustinov        self.clients_start  = static_route_dict['clients_start']
952823b8294SYaroslav Brustinov        self.servers_start  = static_route_dict['servers_start']
953823b8294SYaroslav Brustinov        self.net_increment  = misc_methods.gen_increment_dict(static_route_dict['dual_port_mask'])
954823b8294SYaroslav Brustinov        self.client_mask    = static_route_dict['client_destination_mask']
955823b8294SYaroslav Brustinov        self.server_mask    = static_route_dict['server_destination_mask']
956823b8294SYaroslav Brustinov        self.client_net_start = self.extract_net_addr(self.clients_start, self.client_mask)
957823b8294SYaroslav Brustinov        self.server_net_start = self.extract_net_addr(self.servers_start, self.server_mask)
958823b8294SYaroslav Brustinov        self.static_route_dict = static_route_dict
959823b8294SYaroslav Brustinov
960823b8294SYaroslav Brustinov    def extract_net_addr (self, ip_addr, ip_mask):
961823b8294SYaroslav Brustinov        addr_lst = ip_addr.split('.')
962823b8294SYaroslav Brustinov        mask_lst = ip_mask.split('.')
963501fb3b4SYaroslav Brustinov        mask_lst = [str(int(x) & int(y)) for x, y in zip(addr_lst, mask_lst)]
964501fb3b4SYaroslav Brustinov        return '.'.join(mask_lst)
965823b8294SYaroslav Brustinov
966823b8294SYaroslav Brustinov    def dump_config (self):
967823b8294SYaroslav Brustinov        import yaml
9681a935f29SYaroslav Brustinov        print(yaml.dump( self.static_route_dict , default_flow_style=False))
969823b8294SYaroslav Brustinov
970823b8294SYaroslav Brustinov
971823b8294SYaroslav Brustinovclass CNatConfig(object):
972823b8294SYaroslav Brustinov    def __init__(self, nat_dict):
973823b8294SYaroslav Brustinov        self.clients_net_start  = nat_dict['clients_net_start']
974823b8294SYaroslav Brustinov        self.client_acl_wildcard= nat_dict['client_acl_wildcard_mask']
975823b8294SYaroslav Brustinov        self.net_increment      = misc_methods.gen_increment_dict(nat_dict['dual_port_mask'])
976823b8294SYaroslav Brustinov        self.nat_pool_start     = nat_dict['pool_start']
977823b8294SYaroslav Brustinov        self.nat_netmask        = nat_dict['pool_netmask']
978823b8294SYaroslav Brustinov        self.nat_dict           = nat_dict
979823b8294SYaroslav Brustinov
980823b8294SYaroslav Brustinov    @staticmethod
981823b8294SYaroslav Brustinov    def calc_pool_end (nat_pool_start, netmask):
982501fb3b4SYaroslav Brustinov        pool_start_lst  = [int(x) for x in nat_pool_start.split('.')]
983823b8294SYaroslav Brustinov        pool_end_lst    = list( pool_start_lst )   # create new list object, don't point to the original one
984501fb3b4SYaroslav Brustinov        mask_lst        = [int(x) for x in netmask.split('.')]
985823b8294SYaroslav Brustinov        curr_octet      = 3 # start with the LSB octet
986823b8294SYaroslav Brustinov        inc_val         = 1
987823b8294SYaroslav Brustinov
988823b8294SYaroslav Brustinov        while True:
989823b8294SYaroslav Brustinov            tmp_masked = inc_val & mask_lst[curr_octet]
990823b8294SYaroslav Brustinov            if tmp_masked == 0:
991823b8294SYaroslav Brustinov                if (inc_val << 1) > 255:
992823b8294SYaroslav Brustinov                    inc_val = 1
993823b8294SYaroslav Brustinov                    pool_end_lst[curr_octet] = 255
994823b8294SYaroslav Brustinov                    curr_octet -= 1
995823b8294SYaroslav Brustinov                else:
996823b8294SYaroslav Brustinov                    inc_val <<= 1
997823b8294SYaroslav Brustinov            else:
998823b8294SYaroslav Brustinov                pool_end_lst[curr_octet] += (inc_val - 1)
999823b8294SYaroslav Brustinov                break
1000501fb3b4SYaroslav Brustinov        return '.'.join([str(x) for x in pool_end_lst])
1001823b8294SYaroslav Brustinov
1002823b8294SYaroslav Brustinov    def dump_config (self):
1003823b8294SYaroslav Brustinov        import yaml
10041a935f29SYaroslav Brustinov        print(yaml.dump( self.nat_dict , default_flow_style=False))
1005823b8294SYaroslav Brustinov
1006823b8294SYaroslav Brustinov
1007823b8294SYaroslav Brustinovif __name__ == "__main__":
1008823b8294SYaroslav Brustinov    pass
1009