1# 2# (c) 2019, Ansible by Red Hat, inc 3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4# 5import re 6 7from ansible.module_utils.six import iteritems 8from ansible.module_utils.network.common.utils import to_list 9from ansible.module_utils.network.ios.providers.providers import CliProvider 10 11 12class Neighbors(CliProvider): 13 14 def render(self, config=None, nbr_list=None): 15 commands = list() 16 safe_list = list() 17 if not nbr_list: 18 nbr_list = self.get_value('config.neighbors') 19 20 for item in nbr_list: 21 neighbor_commands = list() 22 context = 'neighbor %s' % item['neighbor'] 23 cmd = '%s remote-as %s' % (context, item['remote_as']) 24 25 if not config or cmd not in config: 26 neighbor_commands.append(cmd) 27 28 for key, value in iteritems(item): 29 if value is not None: 30 meth = getattr(self, '_render_%s' % key, None) 31 if meth: 32 resp = meth(item, config) 33 if resp: 34 neighbor_commands.extend(to_list(resp)) 35 36 commands.extend(neighbor_commands) 37 safe_list.append(context) 38 39 if self.params['operation'] == 'replace': 40 if config and safe_list: 41 commands.extend(self._negate_config(config, safe_list)) 42 43 return commands 44 45 def _negate_config(self, config, safe_list=None): 46 commands = list() 47 matches = re.findall(r'(neighbor \S+)', config, re.M) 48 for item in set(matches).difference(safe_list): 49 commands.append('no %s' % item) 50 return commands 51 52 def _render_local_as(self, item, config=None): 53 cmd = 'neighbor %s local-as %s' % (item['neighbor'], item['local_as']) 54 if not config or cmd not in config: 55 return cmd 56 57 def _render_port(self, item, config=None): 58 cmd = 'neighbor %s port %s' % (item['neighbor'], item['port']) 59 if not config or cmd not in config: 60 return cmd 61 62 def _render_description(self, item, config=None): 63 cmd = 'neighbor %s description %s' % (item['neighbor'], item['description']) 64 if not config or cmd not in config: 65 return cmd 66 67 def _render_enabled(self, item, config=None): 68 cmd = 'neighbor %s shutdown' % item['neighbor'] 69 if item['enabled'] is True: 70 if not config or cmd in config: 71 cmd = 'no %s' % cmd 72 return cmd 73 elif not config or cmd not in config: 74 return cmd 75 76 def _render_update_source(self, item, config=None): 77 cmd = 'neighbor %s update-source %s' % (item['neighbor'], item['update_source']) 78 if not config or cmd not in config: 79 return cmd 80 81 def _render_password(self, item, config=None): 82 cmd = 'neighbor %s password %s' % (item['neighbor'], item['password']) 83 if not config or cmd not in config: 84 return cmd 85 86 def _render_ebgp_multihop(self, item, config=None): 87 cmd = 'neighbor %s ebgp-multihop %s' % (item['neighbor'], item['ebgp_multihop']) 88 if not config or cmd not in config: 89 return cmd 90 91 def _render_peer_group(self, item, config=None): 92 cmd = 'neighbor %s peer-group %s' % (item['neighbor'], item['peer_group']) 93 if not config or cmd not in config: 94 return cmd 95 96 def _render_timers(self, item, config): 97 """generate bgp timer related configuration 98 """ 99 keepalive = item['timers']['keepalive'] 100 holdtime = item['timers']['holdtime'] 101 min_neighbor_holdtime = item['timers']['min_neighbor_holdtime'] 102 neighbor = item['neighbor'] 103 104 if keepalive and holdtime: 105 cmd = 'neighbor %s timers %s %s' % (neighbor, keepalive, holdtime) 106 if min_neighbor_holdtime: 107 cmd += ' %s' % min_neighbor_holdtime 108 if not config or cmd not in config: 109 return cmd 110 111 112class AFNeighbors(CliProvider): 113 114 def render(self, config=None, nbr_list=None): 115 commands = list() 116 if not nbr_list: 117 return 118 119 for item in nbr_list: 120 neighbor_commands = list() 121 for key, value in iteritems(item): 122 if value is not None: 123 meth = getattr(self, '_render_%s' % key, None) 124 if meth: 125 resp = meth(item, config) 126 if resp: 127 neighbor_commands.extend(to_list(resp)) 128 129 commands.extend(neighbor_commands) 130 131 return commands 132 133 def _render_advertisement_interval(self, item, config=None): 134 cmd = 'neighbor %s advertisement-interval %s' % (item['neighbor'], item['advertisement_interval']) 135 if not config or cmd not in config: 136 return cmd 137 138 def _render_route_reflector_client(self, item, config=None): 139 cmd = 'neighbor %s route-reflector-client' % item['neighbor'] 140 if item['route_reflector_client'] is False: 141 if not config or cmd in config: 142 cmd = 'no %s' % cmd 143 return cmd 144 elif not config or cmd not in config: 145 return cmd 146 147 def _render_route_server_client(self, item, config=None): 148 cmd = 'neighbor %s route-server-client' % item['neighbor'] 149 if item['route_server_client'] is False: 150 if not config or cmd in config: 151 cmd = 'no %s' % cmd 152 return cmd 153 elif not config or cmd not in config: 154 return cmd 155 156 def _render_remove_private_as(self, item, config=None): 157 cmd = 'neighbor %s remove-private-as' % item['neighbor'] 158 if item['remove_private_as'] is False: 159 if not config or cmd in config: 160 cmd = 'no %s' % cmd 161 return cmd 162 elif not config or cmd not in config: 163 return cmd 164 165 def _render_next_hop_self(self, item, config=None): 166 cmd = 'neighbor %s next-hop-self' % item['neighbor'] 167 if item['next_hop_self'] is False: 168 if not config or cmd in config: 169 cmd = 'no %s' % cmd 170 return cmd 171 elif not config or cmd not in config: 172 return cmd 173 174 def _render_activate(self, item, config=None): 175 cmd = 'neighbor %s activate' % item['neighbor'] 176 if item['activate'] is False: 177 if not config or cmd in config: 178 cmd = 'no %s' % cmd 179 return cmd 180 elif not config or cmd not in config: 181 return cmd 182 183 def _render_maximum_prefix(self, item, config=None): 184 cmd = 'neighbor %s maximum-prefix %s' % (item['neighbor'], item['maximum_prefix']) 185 if not config or cmd not in config: 186 return cmd 187