Execution module network support for AIX

This commit is contained in:
David Murphy 2017-03-23 17:26:42 -06:00
parent b7f9100e6d
commit 031c9457ba
3 changed files with 211 additions and 4 deletions

View File

@ -336,6 +336,53 @@ def _netstat_sunos():
return ret
def _netstat_aix():
'''
Return netstat information for SunOS flavors
'''
ret = []
## AIX 6.1 - 7.2, appears to ignore addr_family field contents
## for addr_family in ('inet', 'inet6'):
for addr_family in ('inet',):
# Lookup connections
cmd = 'netstat -n -a -f {0} | tail -n +3'.format(addr_family)
out = __salt__['cmd.run'](cmd, python_shell=True)
for line in out.splitlines():
comps = line.split()
if len(comps) < 5:
continue
proto_seen = None
tcp_flag = True
if 'tcp' == comps[0] or 'tcp4' == comps[0]:
proto_seen = 'tcp'
elif 'tcp6' == comps[0]:
proto_seen = 'tcp6'
elif 'udp' == comps[0] or 'udp4' == comps[0]:
proto_seen = 'udp'
tcp_flag = False
elif 'udp6' == comps[0]:
proto_seen = 'udp6'
tcp_flag = False
if tcp_flag:
if len(comps) >= 6:
ret.append({
'proto': proto_seen,
'recv-q': comps[1],
'send-q': comps[2],
'local-address': comps[3],
'remote-address': comps[4],
'state': comps[5]})
else:
if len(comps) >= 5:
ret.append({
'proto': proto_seen,
'local-address': comps[3],
'remote-address': comps[4]})
return ret
def _netstat_route_linux():
'''
Return netstat routing information for Linux distros
@ -506,6 +553,36 @@ def _netstat_route_sunos():
return ret
def _netstat_route_aix():
'''
Return netstat routing information for AIX
'''
ret = []
cmd = 'netstat -f inet -rn | tail -n +5'
out = __salt__['cmd.run'](cmd, python_shell=True)
for line in out.splitlines():
comps = line.split()
ret.append({
'addr_family': 'inet',
'destination': comps[0],
'gateway': comps[1],
'netmask': '',
'flags': comps[2],
'interface': comps[5] if len(comps) >= 6 else ''})
cmd = 'netstat -f inet6 -rn | tail -n +5'
out = __salt__['cmd.run'](cmd, python_shell=True)
for line in out.splitlines():
comps = line.split()
ret.append({
'addr_family': 'inet6',
'destination': comps[0],
'gateway': comps[1],
'netmask': '',
'flags': comps[2],
'interface': comps[5] if len(comps) >= 6 else ''})
return ret
def netstat():
'''
Return information on open ports and states
@ -520,6 +597,9 @@ def netstat():
.. versionchanged:: 2015.8.0
Added support for SunOS
.. versionchanged:: 2016.11.4
Added support for AIX
CLI Example:
.. code-block:: bash
@ -532,6 +612,8 @@ def netstat():
return _netstat_bsd()
elif __grains__['kernel'] == 'SunOS':
return _netstat_sunos()
elif __grains__['kernel'] == 'AIX':
return _netstat_aix()
raise CommandExecutionError('Not yet supported on this platform')
@ -566,6 +648,22 @@ def active_tcp():
'remote_port': '.'.join(connection['remote-address'].split('.')[-1:])
}
return ret
elif __grains__['kernel'] == 'AIX':
# lets use netstat to mimic linux as close as possible
ret = {}
for connection in _netstat_aix():
## TBD need to deliver AIX output in consumable fashion
if not connection['proto'].startswith('tcp'):
continue
if connection['state'] != 'ESTABLISHED':
continue
ret[len(ret)+1] = {
'local_addr': '.'.join(connection['local-address'].split('.')[:-1]),
'local_port': '.'.join(connection['local-address'].split('.')[-1:]),
'remote_addr': '.'.join(connection['remote-address'].split('.')[:-1]),
'remote_port': '.'.join(connection['remote-address'].split('.')[-1:])
}
return ret
else:
return {}
@ -577,6 +675,9 @@ def traceroute(host):
.. versionchanged:: 2015.8.0
Added support for SunOS
.. versionchanged:: 2016.11.4
Added support for AIX
CLI Example:
.. code-block:: bash
@ -593,7 +694,7 @@ def traceroute(host):
out = __salt__['cmd.run'](cmd)
# Parse version of traceroute
if salt.utils.is_sunos():
if salt.utils.is_sunos() or salt.utils.is_aix():
traceroute_version = [0, 0, 0]
else:
cmd2 = 'traceroute --version'
@ -626,8 +727,21 @@ def traceroute(host):
if line.startswith('traceroute'):
continue
if salt.utils.is_aix():
if line.startswith('trying to get source for'):
continue
if line.startswith('source should be'):
continue
if line.startswith('outgoing MTU'):
continue
if line.startswith('fragmentation required'):
continue
if 'Darwin' in str(traceroute_version[1]) or 'FreeBSD' in str(traceroute_version[1]) or \
__grains__['kernel'] == 'SunOS':
__grains__['kernel'] == 'SunOS' or __grains__['kernel'] == 'AIX':
try:
traceline = re.findall(r'\s*(\d*)\s+(.*)\s+\((.*)\)\s+(.*)$', line)[0]
except IndexError:
@ -729,8 +843,15 @@ def arp():
if comps[0] == 'Host' or comps[1] == '(incomplete)':
continue
ret[comps[1]] = comps[0]
elif __grains__['kernel'] == 'AIX':
if comps[0] == 'bucket':
continue
if comps[0] == 'There':
continue
ret[comps[3]] = comps[1].strip('(').strip(')')
else:
ret[comps[3]] = comps[1].strip('(').strip(')')
return ret
@ -1298,6 +1419,9 @@ def routes(family=None):
.. versionchanged:: 2015.8.0
Added support for SunOS (Solaris 10, Illumos, SmartOS)
.. versionchanged:: 2016.11.4
Added support for AIX
CLI Example:
.. code-block:: bash
@ -1317,6 +1441,8 @@ def routes(family=None):
routes_ = _netstat_route_netbsd()
elif __grains__['os'] in ['OpenBSD']:
routes_ = _netstat_route_openbsd()
elif __grains__['os'] in ['AIX']:
routes_ = _netstat_route_aix()
else:
raise CommandExecutionError('Not yet supported on this platform')
@ -1334,6 +1460,9 @@ def default_route(family=None):
.. versionchanged:: 2015.8.0
Added support for SunOS (Solaris 10, Illumos, SmartOS)
.. versionchanged:: 2016.11.4
Added support for AIX
CLI Example:
.. code-block:: bash
@ -1350,7 +1479,7 @@ def default_route(family=None):
default_route['inet'] = ['0.0.0.0', 'default']
default_route['inet6'] = ['::/0', 'default']
elif __grains__['os'] in ['FreeBSD', 'NetBSD', 'OpenBSD', 'MacOS', 'Darwin'] or \
__grains__['kernel'] == 'SunOS':
__grains__['kernel'] == 'SunOS' or __grains__['kernel'] == 'AIX':
default_route['inet'] = ['default']
default_route['inet6'] = ['default']
else:
@ -1381,6 +1510,9 @@ def get_route(ip):
Added support for SunOS (Solaris 10, Illumos, SmartOS)
Added support for OpenBSD
.. versionchanged:: 2016.11.4
Added support for AIX
CLI Example::
salt '*' network.get_route 10.10.10.10
@ -1466,6 +1598,39 @@ def get_route(ip):
return ret
if __grains__['kernel'] == 'AIX':
# root@la68pp002_pub:~# route -n get 172.29.149.95
# route to: 172.29.149.95
#destination: 172.29.149.95
# gateway: 127.0.0.1
# interface: lo0
#interf addr: 127.0.0.1
# flags: <UP,GATEWAY,HOST,DONE,STATIC>
#recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
# 0 0 0 0 0 0 0 -68642
cmd = 'route -n get {0}'.format(ip)
out = __salt__['cmd.run'](cmd, python_shell=False)
ret = {
'destination': ip,
'gateway': None,
'interface': None,
'source': None
}
for line in out.splitlines():
line = line.split(':')
if 'route to' in line[0]:
ret['destination'] = line[1].strip()
if 'gateway' in line[0]:
ret['gateway'] = line[1].strip()
if 'interface' in line[0]:
ret['interface'] = line[1].strip()
if 'interf addr' in line[0]:
ret['source'] = line[1].strip()
return ret
else:
raise CommandExecutionError('Not yet supported on this platform')

View File

@ -1782,6 +1782,14 @@ def is_openbsd():
return sys.platform.startswith('openbsd')
@real_memoize
def is_aix():
'''
Simple function to return if host is AIX or not
'''
return sys.platform.startswith('aix')
def is_fcntl_available(check_sunos=False):
'''
Simple function to check if the `fcntl` module is available or not.

View File

@ -660,10 +660,39 @@ def _get_iface_info(iface):
return None, error_msg
def _hw_addr_aix(iface):
'''
Return the hardware address (a.k.a. MAC address) for a given interface on AIX
MAC address not available in through interfaces
'''
cmd = subprocess.Popen(
'entstat -d {0} | grep \'Hardware Address\''.format(iface),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT).communicate()[0]
if cmd:
comps = cmd.split(' ')
if len(comps) == 3:
mac_addr = comps[2].strip('\'').strip()
return mac_addr
error_msg = ('Interface "{0}" either not available or does not contain a hardware address'.format(iface))
log.error(error_msg)
return error_msg
def hw_addr(iface):
'''
Return the hardware address (a.k.a. MAC address) for a given interface
.. versionchanged:: 2016.11.4
Added support for AIX
'''
if salt.utils.is_aix():
return _hw_addr_aix
iface_info, error = _get_iface_info(iface)
if error is False:
@ -714,8 +743,10 @@ def _subnets(proto='inet', interfaces_=None):
if proto == 'inet':
subnet = 'netmask'
dflt_cidr = 32
elif proto == 'inet6':
subnet = 'prefixlen'
dflt_cidr = 128
else:
log.error('Invalid proto {0} calling subnets()'.format(proto))
return
@ -725,7 +756,10 @@ def _subnets(proto='inet', interfaces_=None):
addrs.extend([addr for addr in ip_info.get('secondary', []) if addr.get('type') == proto])
for intf in addrs:
intf = ipaddress.ip_interface('{0}/{1}'.format(intf['address'], intf[subnet]))
if subnet in intf:
intf = ipaddress.ip_interface('{0}/{1}'.format(intf['address'], intf[subnet]))
else:
intf = ipaddress.ip_interface('{0}/{1}'.format(intf['address'], dflt_cidr))
if not intf.is_loopback:
ret.add(intf.network)
return [str(net) for net in sorted(ret)]