1# This file is part of Ansible 2# 3# Ansible is free software: you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation, either version 3 of the License, or 6# (at your option) any later version. 7# 8# Ansible is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 15 16from __future__ import (absolute_import, division, print_function) 17__metaclass__ = type 18 19import re 20 21from ansible.module_utils.facts.network.base import NetworkCollector 22from ansible.module_utils.facts.network.generic_bsd import GenericBsdIfconfigNetwork 23 24 25class SunOSNetwork(GenericBsdIfconfigNetwork): 26 """ 27 This is the SunOS Network Class. 28 It uses the GenericBsdIfconfigNetwork. 29 30 Solaris can have different FLAGS and MTU for IPv4 and IPv6 on the same interface 31 so these facts have been moved inside the 'ipv4' and 'ipv6' lists. 32 """ 33 platform = 'SunOS' 34 35 # Solaris 'ifconfig -a' will print interfaces twice, once for IPv4 and again for IPv6. 36 # MTU and FLAGS also may differ between IPv4 and IPv6 on the same interface. 37 # 'parse_interface_line()' checks for previously seen interfaces before defining 38 # 'current_if' so that IPv6 facts don't clobber IPv4 facts (or vice versa). 39 def get_interfaces_info(self, ifconfig_path): 40 interfaces = {} 41 current_if = {} 42 ips = dict( 43 all_ipv4_addresses=[], 44 all_ipv6_addresses=[], 45 ) 46 rc, out, err = self.module.run_command([ifconfig_path, '-a']) 47 48 for line in out.splitlines(): 49 50 if line: 51 words = line.split() 52 53 if re.match(r'^\S', line) and len(words) > 3: 54 current_if = self.parse_interface_line(words, current_if, interfaces) 55 interfaces[current_if['device']] = current_if 56 elif words[0].startswith('options='): 57 self.parse_options_line(words, current_if, ips) 58 elif words[0] == 'nd6': 59 self.parse_nd6_line(words, current_if, ips) 60 elif words[0] == 'ether': 61 self.parse_ether_line(words, current_if, ips) 62 elif words[0] == 'media:': 63 self.parse_media_line(words, current_if, ips) 64 elif words[0] == 'status:': 65 self.parse_status_line(words, current_if, ips) 66 elif words[0] == 'lladdr': 67 self.parse_lladdr_line(words, current_if, ips) 68 elif words[0] == 'inet': 69 self.parse_inet_line(words, current_if, ips) 70 elif words[0] == 'inet6': 71 self.parse_inet6_line(words, current_if, ips) 72 else: 73 self.parse_unknown_line(words, current_if, ips) 74 75 # 'parse_interface_line' and 'parse_inet*_line' leave two dicts in the 76 # ipv4/ipv6 lists which is ugly and hard to read. 77 # This quick hack merges the dictionaries. Purely cosmetic. 78 for iface in interfaces: 79 for v in 'ipv4', 'ipv6': 80 combined_facts = {} 81 for facts in interfaces[iface][v]: 82 combined_facts.update(facts) 83 if len(combined_facts.keys()) > 0: 84 interfaces[iface][v] = [combined_facts] 85 86 return interfaces, ips 87 88 def parse_interface_line(self, words, current_if, interfaces): 89 device = words[0][0:-1] 90 if device not in interfaces: 91 current_if = {'device': device, 'ipv4': [], 'ipv6': [], 'type': 'unknown'} 92 else: 93 current_if = interfaces[device] 94 flags = self.get_options(words[1]) 95 v = 'ipv4' 96 if 'IPv6' in flags: 97 v = 'ipv6' 98 if 'LOOPBACK' in flags: 99 current_if['type'] = 'loopback' 100 current_if[v].append({'flags': flags, 'mtu': words[3]}) 101 current_if['macaddress'] = 'unknown' # will be overwritten later 102 return current_if 103 104 # Solaris displays single digit octets in MAC addresses e.g. 0:1:2:d:e:f 105 # Add leading zero to each octet where needed. 106 def parse_ether_line(self, words, current_if, ips): 107 macaddress = '' 108 for octet in words[1].split(':'): 109 octet = ('0' + octet)[-2:None] 110 macaddress += (octet + ':') 111 current_if['macaddress'] = macaddress[0:-1] 112 113 114class SunOSNetworkCollector(NetworkCollector): 115 _fact_class = SunOSNetwork 116 _platform = 'SunOS' 117