1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-04-20 10:48:59 +00:00

Initial commit

This commit is contained in:
Ansible Core Team 2020-03-09 09:11:07 +00:00
commit aebc1b03fd
4861 changed files with 812621 additions and 0 deletions

View file

@ -0,0 +1,170 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: dladm_etherstub
short_description: Manage etherstubs on Solaris/illumos systems.
description:
- Create or delete etherstubs on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
name:
description:
- Etherstub name.
required: true
temporary:
description:
- Specifies that the etherstub is temporary. Temporary etherstubs
do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Create or delete Solaris/illumos etherstub.
required: false
default: "present"
choices: [ "present", "absent" ]
'''
EXAMPLES = '''
# Create 'stub0' etherstub
- dladm_etherstub:
name: stub0
state: present
# Remove 'stub0 etherstub
- dladm_etherstub:
name: stub0
state: absent
'''
RETURN = '''
name:
description: etherstub name
returned: always
type: str
sample: "switch0"
state:
description: state of the target
returned: always
type: str
sample: "present"
temporary:
description: etherstub's persistence
returned: always
type: bool
sample: "True"
'''
from ansible.module_utils.basic import AnsibleModule
class Etherstub(object):
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.temporary = module.params['temporary']
self.state = module.params['state']
def etherstub_exists(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('show-etherstub')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def create_etherstub(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('create-etherstub')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def delete_etherstub(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('delete-etherstub')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
temporary=dict(default=False, type='bool'),
state=dict(default='present', choices=['absent', 'present']),
),
supports_check_mode=True
)
etherstub = Etherstub(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = etherstub.name
result['state'] = etherstub.state
result['temporary'] = etherstub.temporary
if etherstub.state == 'absent':
if etherstub.etherstub_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = etherstub.delete_etherstub()
if rc != 0:
module.fail_json(name=etherstub.name, msg=err, rc=rc)
elif etherstub.state == 'present':
if not etherstub.etherstub_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = etherstub.create_etherstub()
if rc is not None and rc != 0:
module.fail_json(name=etherstub.name, msg=err, rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,277 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: dladm_iptun
short_description: Manage IP tunnel interfaces on Solaris/illumos systems.
description:
- Manage IP tunnel interfaces on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
name:
description:
- IP tunnel interface name.
required: true
temporary:
description:
- Specifies that the IP tunnel interface is temporary. Temporary IP tunnel
interfaces do not persist across reboots.
required: false
default: false
type: bool
type:
description:
- Specifies the type of tunnel to be created.
required: false
default: "ipv4"
choices: [ "ipv4", "ipv6", "6to4" ]
aliases: ['tunnel_type']
local_address:
description:
- Literal IP address or hostname corresponding to the tunnel source.
required: false
aliases: [ "local" ]
remote_address:
description:
- Literal IP address or hostname corresponding to the tunnel destination.
required: false
aliases: [ "remote" ]
state:
description:
- Create or delete Solaris/illumos VNIC.
required: false
default: "present"
choices: [ "present", "absent" ]
'''
EXAMPLES = '''
- name: Create IPv4 tunnel interface 'iptun0'
dladm_iptun: name=iptun0 local_address=192.0.2.23 remote_address=203.0.113.10 state=present
- name: Change IPv4 tunnel remote address
dladm_iptun: name=iptun0 type=ipv4 local_address=192.0.2.23 remote_address=203.0.113.11
- name: Create IPv6 tunnel interface 'tun0'
dladm_iptun: name=tun0 type=ipv6 local_address=192.0.2.23 remote_address=203.0.113.42
- name: Remove 'iptun0' tunnel interface
dladm_iptun: name=iptun0 state=absent
'''
RETURN = '''
name:
description: tunnel interface name
returned: always
type: str
sample: iptun0
state:
description: state of the target
returned: always
type: str
sample: present
temporary:
description: specifies if operation will persist across reboots
returned: always
type: bool
sample: True
local_address:
description: local IP address
returned: always
type: str
sample: 1.1.1.1/32
remote_address:
description: remote IP address
returned: always
type: str
sample: 2.2.2.2/32
type:
description: tunnel type
returned: always
type: str
sample: ipv4
'''
from ansible.module_utils.basic import AnsibleModule
SUPPORTED_TYPES = ['ipv4', 'ipv6', '6to4']
class IPTun(object):
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.type = module.params['type']
self.local_address = module.params['local_address']
self.remote_address = module.params['remote_address']
self.temporary = module.params['temporary']
self.state = module.params['state']
self.dladm_bin = self.module.get_bin_path('dladm', True)
def iptun_exists(self):
cmd = [self.dladm_bin]
cmd.append('show-iptun')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def create_iptun(self):
cmd = [self.dladm_bin]
cmd.append('create-iptun')
if self.temporary:
cmd.append('-t')
cmd.append('-T')
cmd.append(self.type)
cmd.append('-a')
cmd.append('local=' + self.local_address + ',remote=' + self.remote_address)
cmd.append(self.name)
return self.module.run_command(cmd)
def delete_iptun(self):
cmd = [self.dladm_bin]
cmd.append('delete-iptun')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def update_iptun(self):
cmd = [self.dladm_bin]
cmd.append('modify-iptun')
if self.temporary:
cmd.append('-t')
cmd.append('-a')
cmd.append('local=' + self.local_address + ',remote=' + self.remote_address)
cmd.append(self.name)
return self.module.run_command(cmd)
def _query_iptun_props(self):
cmd = [self.dladm_bin]
cmd.append('show-iptun')
cmd.append('-p')
cmd.append('-c')
cmd.append('link,type,flags,local,remote')
cmd.append(self.name)
return self.module.run_command(cmd)
def iptun_needs_updating(self):
(rc, out, err) = self._query_iptun_props()
NEEDS_UPDATING = False
if rc == 0:
configured_local, configured_remote = out.split(':')[3:]
if self.local_address != configured_local or self.remote_address != configured_remote:
NEEDS_UPDATING = True
return NEEDS_UPDATING
else:
self.module.fail_json(msg='Failed to query tunnel interface %s properties' % self.name,
err=err,
rc=rc)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, type='str'),
type=dict(default='ipv4', type='str', aliases=['tunnel_type'],
choices=SUPPORTED_TYPES),
local_address=dict(type='str', aliases=['local']),
remote_address=dict(type='str', aliases=['remote']),
temporary=dict(default=False, type='bool'),
state=dict(default='present', choices=['absent', 'present']),
),
required_if=[
['state', 'present', ['local_address', 'remote_address']],
],
supports_check_mode=True
)
iptun = IPTun(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = iptun.name
result['type'] = iptun.type
result['local_address'] = iptun.local_address
result['remote_address'] = iptun.remote_address
result['state'] = iptun.state
result['temporary'] = iptun.temporary
if iptun.state == 'absent':
if iptun.iptun_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = iptun.delete_iptun()
if rc != 0:
module.fail_json(name=iptun.name, msg=err, rc=rc)
elif iptun.state == 'present':
if not iptun.iptun_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = iptun.create_iptun()
if rc is not None and rc != 0:
module.fail_json(name=iptun.name, msg=err, rc=rc)
else:
if iptun.iptun_needs_updating():
(rc, out, err) = iptun.update_iptun()
if rc != 0:
module.fail_json(msg='Error while updating tunnel interface: "%s"' % err,
name=iptun.name,
stderr=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,289 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: dladm_linkprop
short_description: Manage link properties on Solaris/illumos systems.
description:
- Set / reset link properties on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
link:
description:
- Link interface name.
required: true
aliases: [ "nic", "interface" ]
property:
description:
- Specifies the name of the property we want to manage.
required: true
aliases: [ "name" ]
value:
description:
- Specifies the value we want to set for the link property.
required: false
temporary:
description:
- Specifies that lin property configuration is temporary. Temporary
link property configuration does not persist across reboots.
required: false
type: bool
default: false
state:
description:
- Set or reset the property value.
required: false
default: "present"
choices: [ "present", "absent", "reset" ]
'''
EXAMPLES = '''
- name: Set 'maxbw' to 100M on e1000g1
dladm_linkprop: name=e1000g1 property=maxbw value=100M state=present
- name: Set 'mtu' to 9000 on e1000g1
dladm_linkprop: name=e1000g1 property=mtu value=9000
- name: Reset 'mtu' property on e1000g1
dladm_linkprop: name=e1000g1 property=mtu state=reset
'''
RETURN = '''
property:
description: property name
returned: always
type: str
sample: mtu
state:
description: state of the target
returned: always
type: str
sample: present
temporary:
description: specifies if operation will persist across reboots
returned: always
type: bool
sample: True
link:
description: link name
returned: always
type: str
sample: e100g0
value:
description: property value
returned: always
type: str
sample: 9000
'''
from ansible.module_utils.basic import AnsibleModule
class LinkProp(object):
def __init__(self, module):
self.module = module
self.link = module.params['link']
self.property = module.params['property']
self.value = module.params['value']
self.temporary = module.params['temporary']
self.state = module.params['state']
self.dladm_bin = self.module.get_bin_path('dladm', True)
def property_exists(self):
cmd = [self.dladm_bin]
cmd.append('show-linkprop')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.link)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
self.module.fail_json(msg='Unknown property "%s" on link %s' %
(self.property, self.link),
property=self.property,
link=self.link)
def property_is_modified(self):
cmd = [self.dladm_bin]
cmd.append('show-linkprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('value,default')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.link)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
(value, default) = out.split(':')
if rc == 0 and value == default:
return True
else:
return False
def property_is_readonly(self):
cmd = [self.dladm_bin]
cmd.append('show-linkprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('perm')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.link)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
if rc == 0 and out == 'r-':
return True
else:
return False
def property_is_set(self):
cmd = [self.dladm_bin]
cmd.append('show-linkprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('value')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.link)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
if rc == 0 and self.value == out:
return True
else:
return False
def set_property(self):
cmd = [self.dladm_bin]
cmd.append('set-linkprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property + '=' + self.value)
cmd.append(self.link)
return self.module.run_command(cmd)
def reset_property(self):
cmd = [self.dladm_bin]
cmd.append('reset-linkprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.link)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
link=dict(required=True, default=None, type='str', aliases=['nic', 'interface']),
property=dict(required=True, type='str', aliases=['name']),
value=dict(required=False, type='str'),
temporary=dict(default=False, type='bool'),
state=dict(
default='present', choices=['absent', 'present', 'reset']),
),
required_if=[
['state', 'present', ['value']],
],
supports_check_mode=True
)
linkprop = LinkProp(module)
rc = None
out = ''
err = ''
result = {}
result['property'] = linkprop.property
result['link'] = linkprop.link
result['state'] = linkprop.state
if linkprop.value:
result['value'] = linkprop.value
if linkprop.state == 'absent' or linkprop.state == 'reset':
if linkprop.property_exists():
if not linkprop.property_is_modified():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = linkprop.reset_property()
if rc != 0:
module.fail_json(property=linkprop.property,
link=linkprop.link,
msg=err,
rc=rc)
elif linkprop.state == 'present':
if linkprop.property_exists():
if not linkprop.property_is_readonly():
if not linkprop.property_is_set():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = linkprop.set_property()
if rc != 0:
module.fail_json(property=linkprop.property,
link=linkprop.link,
msg=err,
rc=rc)
else:
module.fail_json(msg='Property "%s" is read-only!' % (linkprop.property),
property=linkprop.property,
link=linkprop.link)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,213 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: dladm_vlan
short_description: Manage VLAN interfaces on Solaris/illumos systems.
description:
- Create or delete VLAN interfaces on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
name:
description:
- VLAN interface name.
required: true
link:
description:
- VLAN underlying link name.
required: true
temporary:
description:
- Specifies that the VLAN interface is temporary. Temporary VLANs
do not persist across reboots.
required: false
default: false
type: bool
vlan_id:
description:
- VLAN ID value for VLAN interface.
required: false
default: false
aliases: [ "vid" ]
state:
description:
- Create or delete Solaris/illumos VNIC.
required: false
default: "present"
choices: [ "present", "absent" ]
'''
EXAMPLES = '''
- name: Create 'vlan42' VLAN over 'bnx0' link
dladm_vlan: name=vlan42 link=bnx0 vlan_id=42 state=present
- name: Remove 'vlan1337' VLAN interface
dladm_vlan: name=vlan1337 state=absent
'''
RETURN = '''
name:
description: VLAN name
returned: always
type: str
sample: vlan42
state:
description: state of the target
returned: always
type: str
sample: present
temporary:
description: specifies if operation will persist across reboots
returned: always
type: bool
sample: True
link:
description: VLAN's underlying link name
returned: always
type: str
sample: e100g0
vlan_id:
description: VLAN ID
returned: always
type: str
sample: 42
'''
from ansible.module_utils.basic import AnsibleModule
class VLAN(object):
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.link = module.params['link']
self.vlan_id = module.params['vlan_id']
self.temporary = module.params['temporary']
self.state = module.params['state']
def vlan_exists(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('show-vlan')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def create_vlan(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('create-vlan')
if self.temporary:
cmd.append('-t')
cmd.append('-l')
cmd.append(self.link)
cmd.append('-v')
cmd.append(self.vlan_id)
cmd.append(self.name)
return self.module.run_command(cmd)
def delete_vlan(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('delete-vlan')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def is_valid_vlan_id(self):
return 0 <= int(self.vlan_id) <= 4095
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, type='str'),
link=dict(default=None, type='str'),
vlan_id=dict(default=0, aliases=['vid']),
temporary=dict(default=False, type='bool'),
state=dict(default='present', choices=['absent', 'present']),
),
required_if=[
['state', 'present', ['vlan_id', 'link', 'name']],
],
supports_check_mode=True
)
vlan = VLAN(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = vlan.name
result['link'] = vlan.link
result['state'] = vlan.state
result['temporary'] = vlan.temporary
if int(vlan.vlan_id) != 0:
if not vlan.is_valid_vlan_id():
module.fail_json(msg='Invalid VLAN id value',
name=vlan.name,
state=vlan.state,
link=vlan.link,
vlan_id=vlan.vlan_id)
result['vlan_id'] = vlan.vlan_id
if vlan.state == 'absent':
if vlan.vlan_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = vlan.delete_vlan()
if rc != 0:
module.fail_json(name=vlan.name, msg=err, rc=rc)
elif vlan.state == 'present':
if not vlan.vlan_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = vlan.create_vlan()
if rc is not None and rc != 0:
module.fail_json(name=vlan.name, msg=err, rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,265 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Adam Števko <adam.stevko@gmail.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: dladm_vnic
short_description: Manage VNICs on Solaris/illumos systems.
description:
- Create or delete VNICs on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
name:
description:
- VNIC name.
required: true
link:
description:
- VNIC underlying link name.
required: true
temporary:
description:
- Specifies that the VNIC is temporary. Temporary VNICs
do not persist across reboots.
required: false
default: false
type: bool
mac:
description:
- Sets the VNIC's MAC address. Must be valid unicast MAC address.
required: false
default: false
aliases: [ "macaddr" ]
vlan:
description:
- Enable VLAN tagging for this VNIC. The VLAN tag will have id
I(vlan).
required: false
default: false
aliases: [ "vlan_id" ]
state:
description:
- Create or delete Solaris/illumos VNIC.
required: false
default: "present"
choices: [ "present", "absent" ]
'''
EXAMPLES = '''
# Create 'vnic0' VNIC over 'bnx0' link
- dladm_vnic:
name: vnic0
link: bnx0
state: present
# Create VNIC with specified MAC and VLAN tag over 'aggr0'
- dladm_vnic:
name: vnic1
link: aggr0
mac: '00:00:5E:00:53:23'
vlan: 4
# Remove 'vnic0' VNIC
- dladm_vnic:
name: vnic0
link: bnx0
state: absent
'''
RETURN = '''
name:
description: VNIC name
returned: always
type: str
sample: "vnic0"
link:
description: VNIC underlying link name
returned: always
type: str
sample: "igb0"
state:
description: state of the target
returned: always
type: str
sample: "present"
temporary:
description: VNIC's persistence
returned: always
type: bool
sample: "True"
mac:
description: MAC address to use for VNIC
returned: if mac is specified
type: str
sample: "00:00:5E:00:53:42"
vlan:
description: VLAN to use for VNIC
returned: success
type: int
sample: 42
'''
import re
from ansible.module_utils.basic import AnsibleModule
class VNIC(object):
UNICAST_MAC_REGEX = r'^[a-f0-9][2-9a-f0]:([a-f0-9]{2}:){4}[a-f0-9]{2}$'
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.link = module.params['link']
self.mac = module.params['mac']
self.vlan = module.params['vlan']
self.temporary = module.params['temporary']
self.state = module.params['state']
def vnic_exists(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('show-vnic')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def create_vnic(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('create-vnic')
if self.temporary:
cmd.append('-t')
if self.mac:
cmd.append('-m')
cmd.append(self.mac)
if self.vlan:
cmd.append('-v')
cmd.append(self.vlan)
cmd.append('-l')
cmd.append(self.link)
cmd.append(self.name)
return self.module.run_command(cmd)
def delete_vnic(self):
cmd = [self.module.get_bin_path('dladm', True)]
cmd.append('delete-vnic')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def is_valid_unicast_mac(self):
mac_re = re.match(self.UNICAST_MAC_REGEX, self.mac)
return mac_re is None
def is_valid_vlan_id(self):
return 0 <= self.vlan <= 4095
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
link=dict(required=True),
mac=dict(default=None, aliases=['macaddr']),
vlan=dict(default=None, aliases=['vlan_id']),
temporary=dict(default=False, type='bool'),
state=dict(default='present', choices=['absent', 'present']),
),
supports_check_mode=True
)
vnic = VNIC(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = vnic.name
result['link'] = vnic.link
result['state'] = vnic.state
result['temporary'] = vnic.temporary
if vnic.mac is not None:
if vnic.is_valid_unicast_mac():
module.fail_json(msg='Invalid unicast MAC address',
mac=vnic.mac,
name=vnic.name,
state=vnic.state,
link=vnic.link,
vlan=vnic.vlan)
result['mac'] = vnic.mac
if vnic.vlan is not None:
if vnic.is_valid_vlan_id():
module.fail_json(msg='Invalid VLAN tag',
mac=vnic.mac,
name=vnic.name,
state=vnic.state,
link=vnic.link,
vlan=vnic.vlan)
result['vlan'] = vnic.vlan
if vnic.state == 'absent':
if vnic.vnic_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = vnic.delete_vnic()
if rc != 0:
module.fail_json(name=vnic.name, msg=err, rc=rc)
elif vnic.state == 'present':
if not vnic.vnic_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = vnic.create_vnic()
if rc is not None and rc != 0:
module.fail_json(name=vnic.name, msg=err, rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,513 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: flowadm
short_description: Manage bandwidth resource control and priority for protocols, services and zones on Solaris/illumos systems
description:
- Create/modify/remove networking bandwidth and associated resources for a type of traffic on a particular link.
author: Adam Števko (@xen0l)
options:
name:
description: >
- A flow is defined as a set of attributes based on Layer 3 and Layer 4
headers, which can be used to identify a protocol, service, or a zone.
required: true
aliases: [ 'flow' ]
link:
description:
- Specifiies a link to configure flow on.
required: false
local_ip:
description:
- Identifies a network flow by the local IP address.
required: false
remote_ip:
description:
- Identifies a network flow by the remote IP address.
required: false
transport:
description: >
- Specifies a Layer 4 protocol to be used. It is typically used in combination with I(local_port) to
identify the service that needs special attention.
required: false
local_port:
description:
- Identifies a service specified by the local port.
required: false
dsfield:
description: >
- Identifies the 8-bit differentiated services field (as defined in
RFC 2474). The optional dsfield_mask is used to state the bits of interest in
the differentiated services field when comparing with the dsfield
value. Both values must be in hexadecimal.
required: false
maxbw:
description: >
- Sets the full duplex bandwidth for the flow. The bandwidth is
specified as an integer with one of the scale suffixes(K, M, or G
for Kbps, Mbps, and Gbps). If no units are specified, the input
value will be read as Mbps.
required: false
priority:
description:
- Sets the relative priority for the flow.
required: false
default: 'medium'
choices: [ 'low', 'medium', 'high' ]
temporary:
description:
- Specifies that the configured flow is temporary. Temporary
flows do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Create/delete/enable/disable an IP address on the network interface.
required: false
default: present
choices: [ 'absent', 'present', 'resetted' ]
'''
EXAMPLES = '''
# Limit SSH traffic to 100M via vnic0 interface
- flowadm:
link: vnic0
flow: ssh_out
transport: tcp
local_port: 22
maxbw: 100M
state: present
# Reset flow properties
- flowadm:
name: dns
state: resetted
# Configure policy for EF PHB (DSCP value of 101110 from RFC 2598) with a bandwidth of 500 Mbps and a high priority.
- flowadm:
link: bge0
dsfield: '0x2e:0xfc'
maxbw: 500M
priority: high
flow: efphb-flow
state: present
'''
RETURN = '''
name:
description: flow name
returned: always
type: str
sample: "http_drop"
link:
description: flow's link
returned: if link is defined
type: str
sample: "vnic0"
state:
description: state of the target
returned: always
type: str
sample: "present"
temporary:
description: flow's persistence
returned: always
type: bool
sample: "True"
priority:
description: flow's priority
returned: if priority is defined
type: str
sample: "low"
transport:
description: flow's transport
returned: if transport is defined
type: str
sample: "tcp"
maxbw:
description: flow's maximum bandwidth
returned: if maxbw is defined
type: str
sample: "100M"
local_Ip:
description: flow's local IP address
returned: if local_ip is defined
type: str
sample: "10.0.0.42"
local_port:
description: flow's local port
returned: if local_port is defined
type: int
sample: 1337
remote_Ip:
description: flow's remote IP address
returned: if remote_ip is defined
type: str
sample: "10.0.0.42"
dsfield:
description: flow's differentiated services value
returned: if dsfield is defined
type: str
sample: "0x2e:0xfc"
'''
import socket
from ansible.module_utils.basic import AnsibleModule
SUPPORTED_TRANSPORTS = ['tcp', 'udp', 'sctp', 'icmp', 'icmpv6']
SUPPORTED_PRIORITIES = ['low', 'medium', 'high']
SUPPORTED_ATTRIBUTES = ['local_ip', 'remote_ip', 'transport', 'local_port', 'dsfield']
SUPPORTPED_PROPERTIES = ['maxbw', 'priority']
class Flow(object):
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.link = module.params['link']
self.local_ip = module.params['local_ip']
self.remote_ip = module.params['remote_ip']
self.transport = module.params['transport']
self.local_port = module.params['local_port']
self.dsfield = module.params['dsfield']
self.maxbw = module.params['maxbw']
self.priority = module.params['priority']
self.temporary = module.params['temporary']
self.state = module.params['state']
self._needs_updating = {
'maxbw': False,
'priority': False,
}
@classmethod
def is_valid_port(cls, port):
return 1 <= int(port) <= 65535
@classmethod
def is_valid_address(cls, ip):
if ip.count('/') == 1:
ip_address, netmask = ip.split('/')
else:
ip_address = ip
if len(ip_address.split('.')) == 4:
try:
socket.inet_pton(socket.AF_INET, ip_address)
except socket.error:
return False
if not 0 <= netmask <= 32:
return False
else:
try:
socket.inet_pton(socket.AF_INET6, ip_address)
except socket.error:
return False
if not 0 <= netmask <= 128:
return False
return True
@classmethod
def is_hex(cls, number):
try:
int(number, 16)
except ValueError:
return False
return True
@classmethod
def is_valid_dsfield(cls, dsfield):
dsmask = None
if dsfield.count(':') == 1:
dsval = dsfield.split(':')[0]
else:
dsval, dsmask = dsfield.split(':')
if dsmask and not 0x01 <= int(dsmask, 16) <= 0xff and not 0x01 <= int(dsval, 16) <= 0xff:
return False
elif not 0x01 <= int(dsval, 16) <= 0xff:
return False
return True
def flow_exists(self):
cmd = [self.module.get_bin_path('flowadm')]
cmd.append('show-flow')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def delete_flow(self):
cmd = [self.module.get_bin_path('flowadm')]
cmd.append('remove-flow')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def create_flow(self):
cmd = [self.module.get_bin_path('flowadm')]
cmd.append('add-flow')
cmd.append('-l')
cmd.append(self.link)
if self.local_ip:
cmd.append('-a')
cmd.append('local_ip=' + self.local_ip)
if self.remote_ip:
cmd.append('-a')
cmd.append('remote_ip=' + self.remote_ip)
if self.transport:
cmd.append('-a')
cmd.append('transport=' + self.transport)
if self.local_port:
cmd.append('-a')
cmd.append('local_port=' + self.local_port)
if self.dsfield:
cmd.append('-a')
cmd.append('dsfield=' + self.dsfield)
if self.maxbw:
cmd.append('-p')
cmd.append('maxbw=' + self.maxbw)
if self.priority:
cmd.append('-p')
cmd.append('priority=' + self.priority)
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def _query_flow_props(self):
cmd = [self.module.get_bin_path('flowadm')]
cmd.append('show-flowprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('property,possible')
cmd.append(self.name)
return self.module.run_command(cmd)
def flow_needs_udpating(self):
(rc, out, err) = self._query_flow_props()
NEEDS_UPDATING = False
if rc == 0:
properties = (line.split(':') for line in out.rstrip().split('\n'))
for prop, value in properties:
if prop == 'maxbw' and self.maxbw != value:
self._needs_updating.update({prop: True})
NEEDS_UPDATING = True
elif prop == 'priority' and self.priority != value:
self._needs_updating.update({prop: True})
NEEDS_UPDATING = True
return NEEDS_UPDATING
else:
self.module.fail_json(msg='Error while checking flow properties: %s' % err,
stderr=err,
rc=rc)
def update_flow(self):
cmd = [self.module.get_bin_path('flowadm')]
cmd.append('set-flowprop')
if self.maxbw and self._needs_updating['maxbw']:
cmd.append('-p')
cmd.append('maxbw=' + self.maxbw)
if self.priority and self._needs_updating['priority']:
cmd.append('-p')
cmd.append('priority=' + self.priority)
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, aliases=['flow']),
link=dict(required=False),
local_ip=dict(required=False),
remote_ip=dict(required=False),
transport=dict(required=False, choices=SUPPORTED_TRANSPORTS),
local_port=dict(required=False),
dsfield=dict(required=False),
maxbw=dict(required=False),
priority=dict(required=False,
default='medium',
choices=SUPPORTED_PRIORITIES),
temporary=dict(default=False, type='bool'),
state=dict(required=False,
default='present',
choices=['absent', 'present', 'resetted']),
),
mutually_exclusive=[
('local_ip', 'remote_ip'),
('local_ip', 'transport'),
('local_ip', 'local_port'),
('local_ip', 'dsfield'),
('remote_ip', 'transport'),
('remote_ip', 'local_port'),
('remote_ip', 'dsfield'),
('transport', 'dsfield'),
('local_port', 'dsfield'),
],
supports_check_mode=True
)
flow = Flow(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = flow.name
result['state'] = flow.state
result['temporary'] = flow.temporary
if flow.link:
result['link'] = flow.link
if flow.maxbw:
result['maxbw'] = flow.maxbw
if flow.priority:
result['priority'] = flow.priority
if flow.local_ip:
if flow.is_valid_address(flow.local_ip):
result['local_ip'] = flow.local_ip
if flow.remote_ip:
if flow.is_valid_address(flow.remote_ip):
result['remote_ip'] = flow.remote_ip
if flow.transport:
result['transport'] = flow.transport
if flow.local_port:
if flow.is_valid_port(flow.local_port):
result['local_port'] = flow.local_port
else:
module.fail_json(msg='Invalid port: %s' % flow.local_port,
rc=1)
if flow.dsfield:
if flow.is_valid_dsfield(flow.dsfield):
result['dsfield'] = flow.dsfield
else:
module.fail_json(msg='Invalid dsfield: %s' % flow.dsfield,
rc=1)
if flow.state == 'absent':
if flow.flow_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = flow.delete_flow()
if rc != 0:
module.fail_json(msg='Error while deleting flow: "%s"' % err,
name=flow.name,
stderr=err,
rc=rc)
elif flow.state == 'present':
if not flow.flow_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = flow.create_flow()
if rc != 0:
module.fail_json(msg='Error while creating flow: "%s"' % err,
name=flow.name,
stderr=err,
rc=rc)
else:
if flow.flow_needs_udpating():
(rc, out, err) = flow.update_flow()
if rc != 0:
module.fail_json(msg='Error while updating flow: "%s"' % err,
name=flow.name,
stderr=err,
rc=rc)
elif flow.state == 'resetted':
if flow.flow_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = flow.reset_flow()
if rc != 0:
module.fail_json(msg='Error while resetting flow: "%s"' % err,
name=flow.name,
stderr=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,403 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ipadm_addr
short_description: Manage IP addresses on an interface on Solaris/illumos systems
description:
- Create/delete static/dynamic IP addresses on network interfaces on Solaris/illumos systems.
- Up/down static/dynamic IP addresses on network interfaces on Solaris/illumos systems.
- Manage IPv6 link-local addresses on network interfaces on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
address:
description:
- Specifiies an IP address to configure in CIDR notation.
required: false
aliases: [ "addr" ]
addrtype:
description:
- Specifiies a type of IP address to configure.
required: false
default: static
choices: [ 'static', 'dhcp', 'addrconf' ]
addrobj:
description:
- Specifies an unique IP address on the system.
required: true
temporary:
description:
- Specifies that the configured IP address is temporary. Temporary
IP addresses do not persist across reboots.
required: false
default: false
type: bool
wait:
description:
- Specifies the time in seconds we wait for obtaining address via DHCP.
required: false
default: 60
state:
description:
- Create/delete/enable/disable an IP address on the network interface.
required: false
default: present
choices: [ 'absent', 'present', 'up', 'down', 'enabled', 'disabled', 'refreshed' ]
'''
EXAMPLES = '''
- name: Configure IP address 10.0.0.1 on e1000g0
ipadm_addr: addr=10.0.0.1/32 addrobj=e1000g0/v4 state=present
- name: Delete addrobj
ipadm_addr: addrobj=e1000g0/v4 state=absent
- name: Configure link-local IPv6 address
ipadm_addr: addtype=addrconf addrobj=vnic0/v6
- name: Configure address via DHCP and wait 180 seconds for address obtaining
ipadm_addr: addrobj=vnic0/dhcp addrtype=dhcp wait=180
'''
RETURN = '''
addrobj:
description: address object name
returned: always
type: str
sample: bge0/v4
state:
description: state of the target
returned: always
type: str
sample: present
temporary:
description: specifies if operation will persist across reboots
returned: always
type: bool
sample: True
addrtype:
description: address type
returned: always
type: str
sample: static
address:
description: IP address
returned: only if addrtype is 'static'
type: str
sample: 1.3.3.7/32
wait:
description: time we wait for DHCP
returned: only if addrtype is 'dhcp'
type: str
sample: 10
'''
import socket
from ansible.module_utils.basic import AnsibleModule
SUPPORTED_TYPES = ['static', 'addrconf', 'dhcp']
class Addr(object):
def __init__(self, module):
self.module = module
self.address = module.params['address']
self.addrtype = module.params['addrtype']
self.addrobj = module.params['addrobj']
self.temporary = module.params['temporary']
self.state = module.params['state']
self.wait = module.params['wait']
def is_cidr_notation(self):
return self.address.count('/') == 1
def is_valid_address(self):
ip_address = self.address.split('/')[0]
try:
if len(ip_address.split('.')) == 4:
socket.inet_pton(socket.AF_INET, ip_address)
else:
socket.inet_pton(socket.AF_INET6, ip_address)
except socket.error:
return False
return True
def is_dhcp(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-addr')
cmd.append('-p')
cmd.append('-o')
cmd.append('type')
cmd.append(self.addrobj)
(rc, out, err) = self.module.run_command(cmd)
if rc == 0:
if out.rstrip() != 'dhcp':
return False
return True
else:
self.module.fail_json(msg='Wrong addrtype %s for addrobj "%s": %s' % (out, self.addrobj, err),
rc=rc,
stderr=err)
def addrobj_exists(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-addr')
cmd.append(self.addrobj)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def delete_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('delete-addr')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def create_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('create-addr')
cmd.append('-T')
cmd.append(self.addrtype)
if self.temporary:
cmd.append('-t')
if self.addrtype == 'static':
cmd.append('-a')
cmd.append(self.address)
if self.addrtype == 'dhcp' and self.wait:
cmd.append('-w')
cmd.append(self.wait)
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def up_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('up-addr')
if self.temporary:
cmd.append('-t')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def down_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('down-addr')
if self.temporary:
cmd.append('-t')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def enable_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('enable-addr')
cmd.append('-t')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def disable_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('disable-addr')
cmd.append('-t')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def refresh_addr(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('refresh-addr')
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
address=dict(aliases=['addr']),
addrtype=dict(default='static', choices=SUPPORTED_TYPES),
addrobj=dict(required=True),
temporary=dict(default=False, type='bool'),
state=dict(
default='present', choices=['absent', 'present', 'up', 'down', 'enabled', 'disabled', 'refreshed']),
wait=dict(default=60, type='int'),
),
mutually_exclusive=[
('address', 'wait'),
],
supports_check_mode=True
)
addr = Addr(module)
rc = None
out = ''
err = ''
result = {}
result['addrobj'] = addr.addrobj
result['state'] = addr.state
result['temporary'] = addr.temporary
result['addrtype'] = addr.addrtype
if addr.addrtype == 'static' and addr.address:
if addr.is_cidr_notation() and addr.is_valid_address():
result['address'] = addr.address
else:
module.fail_json(msg='Invalid IP address: %s' % addr.address)
if addr.addrtype == 'dhcp' and addr.wait:
result['wait'] = addr.wait
if addr.state == 'absent':
if addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.delete_addr()
if rc != 0:
module.fail_json(msg='Error while deleting addrobj: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
elif addr.state == 'present':
if not addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.create_addr()
if rc != 0:
module.fail_json(msg='Error while configuring IP address: "%s"' % err,
addrobj=addr.addrobj,
addr=addr.address,
stderr=err,
rc=rc)
elif addr.state == 'up':
if addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.up_addr()
if rc != 0:
module.fail_json(msg='Error while bringing IP address up: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
elif addr.state == 'down':
if addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.down_addr()
if rc != 0:
module.fail_json(msg='Error while bringing IP address down: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
elif addr.state == 'refreshed':
if addr.addrobj_exists():
if addr.is_dhcp():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.refresh_addr()
if rc != 0:
module.fail_json(msg='Error while refreshing IP address: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
else:
module.fail_json(msg='state "refreshed" cannot be used with "%s" addrtype' % addr.addrtype,
addrobj=addr.addrobj,
stderr=err,
rc=1)
elif addr.state == 'enabled':
if addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.enable_addr()
if rc != 0:
module.fail_json(msg='Error while enabling IP address: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
elif addr.state == 'disabled':
if addr.addrobj_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addr.disable_addr()
if rc != 0:
module.fail_json(msg='Error while disabling IP address: "%s"' % err,
addrobj=addr.addrobj,
stderr=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,259 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ipadm_addrprop
short_description: Manage IP address properties on Solaris/illumos systems.
description:
- Modify IP address properties on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
addrobj:
description:
- Specifies the address object we want to manage.
required: true
aliases: [nic, interface]
property:
description:
- Specifies the name of the address property we want to manage.
required: true
aliases: [name]
value:
description:
- Specifies the value we want to set for the address property.
required: false
temporary:
description:
- Specifies that the address property value is temporary.
Temporary values do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Set or reset the property value.
required: false
default: present
choices: [ "present", "absent", "reset" ]
'''
EXAMPLES = '''
- name: Mark address on addrobj as deprecated
ipadm_addrprop: property=deprecated value=on addrobj=e1000g0/v6
- name: Set network prefix length for addrobj
ipadm_addrprop: addrobj=bge0/v4 name=prefixlen value=26
'''
RETURN = '''
property:
description: property name
returned: always
type: str
sample: deprecated
addrobj:
description: address object name
returned: always
type: str
sample: bge0/v4
state:
description: state of the target
returned: always
type: str
sample: present
temporary:
description: specifies if operation will persist across reboots
returned: always
type: bool
sample: True
value:
description: property value
returned: when value is provided
type: str
sample: 26
'''
from ansible.module_utils.basic import AnsibleModule
class AddrProp(object):
def __init__(self, module):
self.module = module
self.addrobj = module.params['addrobj']
self.property = module.params['property']
self.value = module.params['value']
self.temporary = module.params['temporary']
self.state = module.params['state']
def property_exists(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-addrprop')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.addrobj)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
self.module.fail_json(msg='Unknown property "%s" on addrobj %s' %
(self.property, self.addrobj),
property=self.property,
addrobj=self.addrobj)
def property_is_modified(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-addrprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current,default')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.addrobj)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
(value, default) = out.split(':')
if rc == 0 and value == default:
return True
else:
return False
def property_is_set(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-addrprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.addrobj)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
if rc == 0 and self.value == out:
return True
else:
return False
def set_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('set-addrprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property + '=' + self.value)
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def reset_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('reset-addrprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.addrobj)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
addrobj=dict(required=True, default=None, aliases=['nic', 'interface']),
property=dict(required=True, aliases=['name']),
value=dict(required=False),
temporary=dict(default=False, type='bool'),
state=dict(
default='present', choices=['absent', 'present', 'reset']),
),
supports_check_mode=True
)
addrprop = AddrProp(module)
rc = None
out = ''
err = ''
result = {}
result['property'] = addrprop.property
result['addrobj'] = addrprop.addrobj
result['state'] = addrprop.state
result['temporary'] = addrprop.temporary
if addrprop.value:
result['value'] = addrprop.value
if addrprop.state == 'absent' or addrprop.state == 'reset':
if addrprop.property_exists():
if not addrprop.property_is_modified():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addrprop.reset_property()
if rc != 0:
module.fail_json(property=addrprop.property,
addrobj=addrprop.addrobj,
msg=err,
rc=rc)
elif addrprop.state == 'present':
if addrprop.value is None:
module.fail_json(msg='Value is mandatory with state "present"')
if addrprop.property_exists():
if not addrprop.property_is_set():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = addrprop.set_property()
if rc != 0:
module.fail_json(property=addrprop.property,
addrobj=addrprop.addrobj,
msg=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,221 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ipadm_if
short_description: Manage IP interfaces on Solaris/illumos systems.
description:
- Create, delete, enable or disable IP interfaces on Solaris/illumos
systems.
author: Adam Števko (@xen0l)
options:
name:
description:
- IP interface name.
required: true
temporary:
description:
- Specifies that the IP interface is temporary. Temporary IP
interfaces do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Create or delete Solaris/illumos IP interfaces.
required: false
default: "present"
choices: [ "present", "absent", "enabled", "disabled" ]
'''
EXAMPLES = '''
# Create vnic0 interface
- ipadm_if:
name: vnic0
state: enabled
# Disable vnic0 interface
- ipadm_if:
name: vnic0
state: disabled
'''
RETURN = '''
name:
description: IP interface name
returned: always
type: str
sample: "vnic0"
state:
description: state of the target
returned: always
type: str
sample: "present"
temporary:
description: persistence of a IP interface
returned: always
type: bool
sample: "True"
'''
from ansible.module_utils.basic import AnsibleModule
class IPInterface(object):
def __init__(self, module):
self.module = module
self.name = module.params['name']
self.temporary = module.params['temporary']
self.state = module.params['state']
def interface_exists(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('show-if')
cmd.append(self.name)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
return False
def interface_is_disabled(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('show-if')
cmd.append('-o')
cmd.append('state')
cmd.append(self.name)
(rc, out, err) = self.module.run_command(cmd)
if rc != 0:
self.module.fail_json(name=self.name, rc=rc, msg=err)
return 'disabled' in out
def create_interface(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('create-if')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def delete_interface(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('delete-if')
if self.temporary:
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def enable_interface(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('enable-if')
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def disable_interface(self):
cmd = [self.module.get_bin_path('ipadm', True)]
cmd.append('disable-if')
cmd.append('-t')
cmd.append(self.name)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
temporary=dict(default=False, type='bool'),
state=dict(default='present', choices=['absent',
'present',
'enabled',
'disabled']),
),
supports_check_mode=True
)
interface = IPInterface(module)
rc = None
out = ''
err = ''
result = {}
result['name'] = interface.name
result['state'] = interface.state
result['temporary'] = interface.temporary
if interface.state == 'absent':
if interface.interface_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = interface.delete_interface()
if rc != 0:
module.fail_json(name=interface.name, msg=err, rc=rc)
elif interface.state == 'present':
if not interface.interface_exists():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = interface.create_interface()
if rc is not None and rc != 0:
module.fail_json(name=interface.name, msg=err, rc=rc)
elif interface.state == 'enabled':
if interface.interface_is_disabled():
(rc, out, err) = interface.enable_interface()
if rc is not None and rc != 0:
module.fail_json(name=interface.name, msg=err, rc=rc)
elif interface.state == 'disabled':
if not interface.interface_is_disabled():
(rc, out, err) = interface.disable_interface()
if rc is not None and rc != 0:
module.fail_json(name=interface.name, msg=err, rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,287 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ipadm_ifprop
short_description: Manage IP interface properties on Solaris/illumos systems.
description:
- Modify IP interface properties on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
interface:
description:
- Specifies the IP interface we want to manage.
required: true
aliases: [nic]
protocol:
description:
- Specifies the protocol for which we want to manage properties.
required: true
property:
description:
- Specifies the name of the property we want to manage.
required: true
aliases: [name]
value:
description:
- Specifies the value we want to set for the property.
required: false
temporary:
description:
- Specifies that the property value is temporary. Temporary
property values do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Set or reset the property value.
required: false
default: present
choices: [ "present", "absent", "reset" ]
'''
EXAMPLES = '''
- name: Allow forwarding of IPv4 packets on network interface e1000g0
ipadm_ifprop: protocol=ipv4 property=forwarding value=on interface=e1000g0
- name: Temporarily reset IPv4 forwarding property on network interface e1000g0
ipadm_ifprop: protocol=ipv4 interface=e1000g0 temporary=true property=forwarding state=reset
- name: Configure IPv6 metric on network interface e1000g0
ipadm_ifprop: protocol=ipv6 nic=e1000g0 name=metric value=100
- name: Set IPv6 MTU on network interface bge0
ipadm_ifprop: interface=bge0 name=mtu value=1280 protocol=ipv6
'''
RETURN = '''
protocol:
description: property's protocol
returned: always
type: str
sample: ipv4
property:
description: property's name
returned: always
type: str
sample: mtu
interface:
description: interface name we want to set property on
returned: always
type: str
sample: e1000g0
state:
description: state of the target
returned: always
type: str
sample: present
value:
description: property's value
returned: when value is provided
type: str
sample: 1280
'''
from ansible.module_utils.basic import AnsibleModule
SUPPORTED_PROTOCOLS = ['ipv4', 'ipv6']
class IfProp(object):
def __init__(self, module):
self.module = module
self.interface = module.params['interface']
self.protocol = module.params['protocol']
self.property = module.params['property']
self.value = module.params['value']
self.temporary = module.params['temporary']
self.state = module.params['state']
def property_exists(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-ifprop')
cmd.append('-p')
cmd.append(self.property)
cmd.append('-m')
cmd.append(self.protocol)
cmd.append(self.interface)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
self.module.fail_json(msg='Unknown %s property "%s" on IP interface %s' %
(self.protocol, self.property, self.interface),
protocol=self.protocol,
property=self.property,
interface=self.interface)
def property_is_modified(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-ifprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current,default')
cmd.append('-p')
cmd.append(self.property)
cmd.append('-m')
cmd.append(self.protocol)
cmd.append(self.interface)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
(value, default) = out.split(':')
if rc == 0 and value == default:
return True
else:
return False
def property_is_set(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-ifprop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current')
cmd.append('-p')
cmd.append(self.property)
cmd.append('-m')
cmd.append(self.protocol)
cmd.append(self.interface)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
if rc == 0 and self.value == out:
return True
else:
return False
def set_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('set-ifprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property + "=" + self.value)
cmd.append('-m')
cmd.append(self.protocol)
cmd.append(self.interface)
return self.module.run_command(cmd)
def reset_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('reset-ifprop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property)
cmd.append('-m')
cmd.append(self.protocol)
cmd.append(self.interface)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
protocol=dict(required=True, choices=SUPPORTED_PROTOCOLS),
property=dict(required=True, aliases=['name']),
value=dict(required=False),
temporary=dict(default=False, type='bool'),
interface=dict(required=True, default=None, aliases=['nic']),
state=dict(
default='present', choices=['absent', 'present', 'reset']),
),
supports_check_mode=True
)
ifprop = IfProp(module)
rc = None
out = ''
err = ''
result = {}
result['protocol'] = ifprop.protocol
result['property'] = ifprop.property
result['interface'] = ifprop.interface
result['state'] = ifprop.state
if ifprop.value:
result['value'] = ifprop.value
if ifprop.state == 'absent' or ifprop.state == 'reset':
if ifprop.property_exists():
if not ifprop.property_is_modified():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = ifprop.reset_property()
if rc != 0:
module.fail_json(protocol=ifprop.protocol,
property=ifprop.property,
interface=ifprop.interface,
msg=err,
rc=rc)
elif ifprop.state == 'present':
if ifprop.value is None:
module.fail_json(msg='Value is mandatory with state "present"')
if ifprop.property_exists():
if not ifprop.property_is_set():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = ifprop.set_property()
if rc != 0:
module.fail_json(protocol=ifprop.protocol,
property=ifprop.property,
interface=ifprop.interface,
msg=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,260 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Adam Števko <adam.stevko@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ipadm_prop
short_description: Manage protocol properties on Solaris/illumos systems.
description:
- Modify protocol properties on Solaris/illumos systems.
author: Adam Števko (@xen0l)
options:
protocol:
description:
- Specifies the protocol for which we want to manage properties.
required: true
property:
description:
- Specifies the name of property we want to manage.
required: true
value:
description:
- Specifies the value we want to set for the property.
required: false
temporary:
description:
- Specifies that the property value is temporary. Temporary
property values do not persist across reboots.
required: false
default: false
type: bool
state:
description:
- Set or reset the property value.
required: false
default: present
choices: [ "present", "absent", "reset" ]
'''
EXAMPLES = '''
# Set TCP receive buffer size
- ipadm_prop: protocol=tcp property=recv_buf value=65536
# Reset UDP send buffer size to the default value
- ipadm_prop: protocol=udp property=send_buf state=reset
'''
RETURN = '''
protocol:
description: property's protocol
returned: always
type: str
sample: "TCP"
property:
description: name of the property
returned: always
type: str
sample: "recv_maxbuf"
state:
description: state of the target
returned: always
type: str
sample: "present"
temporary:
description: property's persistence
returned: always
type: bool
sample: "True"
value:
description: value of the property. May be int or string depending on property.
returned: always
type: int
sample: "'1024' or 'never'"
'''
from ansible.module_utils.basic import AnsibleModule
SUPPORTED_PROTOCOLS = ['ipv4', 'ipv6', 'icmp', 'tcp', 'udp', 'sctp']
class Prop(object):
def __init__(self, module):
self.module = module
self.protocol = module.params['protocol']
self.property = module.params['property']
self.value = module.params['value']
self.temporary = module.params['temporary']
self.state = module.params['state']
def property_exists(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-prop')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.protocol)
(rc, _, _) = self.module.run_command(cmd)
if rc == 0:
return True
else:
self.module.fail_json(msg='Unknown property "%s" for protocol %s' %
(self.property, self.protocol),
protocol=self.protocol,
property=self.property)
def property_is_modified(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-prop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current,default')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.protocol)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
(value, default) = out.split(':')
if rc == 0 and value == default:
return True
else:
return False
def property_is_set(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('show-prop')
cmd.append('-c')
cmd.append('-o')
cmd.append('current')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.protocol)
(rc, out, _) = self.module.run_command(cmd)
out = out.rstrip()
if rc == 0 and self.value == out:
return True
else:
return False
def set_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('set-prop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property + "=" + self.value)
cmd.append(self.protocol)
return self.module.run_command(cmd)
def reset_property(self):
cmd = [self.module.get_bin_path('ipadm')]
cmd.append('reset-prop')
if self.temporary:
cmd.append('-t')
cmd.append('-p')
cmd.append(self.property)
cmd.append(self.protocol)
return self.module.run_command(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
protocol=dict(required=True, choices=SUPPORTED_PROTOCOLS),
property=dict(required=True),
value=dict(required=False),
temporary=dict(default=False, type='bool'),
state=dict(
default='present', choices=['absent', 'present', 'reset']),
),
supports_check_mode=True
)
prop = Prop(module)
rc = None
out = ''
err = ''
result = {}
result['protocol'] = prop.protocol
result['property'] = prop.property
result['state'] = prop.state
result['temporary'] = prop.temporary
if prop.value:
result['value'] = prop.value
if prop.state == 'absent' or prop.state == 'reset':
if prop.property_exists():
if not prop.property_is_modified():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = prop.reset_property()
if rc != 0:
module.fail_json(protocol=prop.protocol,
property=prop.property,
msg=err,
rc=rc)
elif prop.state == 'present':
if prop.value is None:
module.fail_json(msg='Value is mandatory with state "present"')
if prop.property_exists():
if not prop.property_is_set():
if module.check_mode:
module.exit_json(changed=True)
(rc, out, err) = prop.set_property()
if rc != 0:
module.fail_json(protocol=prop.protocol,
property=prop.property,
msg=err,
rc=rc)
if rc is None:
result['changed'] = False
else:
result['changed'] = True
if out:
result['stdout'] = out
if err:
result['stderr'] = err
module.exit_json(**result)
if __name__ == '__main__':
main()