mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 12:50:22 -07:00
Adding files to ansible core modules.
This commit is contained in:
parent
d3b826dda2
commit
d9a071089b
10 changed files with 3013 additions and 0 deletions
210
lib/ansible/modules/network/cumulus/cl_ports.py
Executable file
210
lib/ansible/modules/network/cumulus/cl_ports.py
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2016, Cumulus Networks <ce-ceng@cumulusnetworks.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: cl_ports
|
||||
version_added: "2.1"
|
||||
author: "Cumulus Networks (@CumulusNetworks)"
|
||||
short_description: Configure Cumulus Switch port attributes (ports.conf)
|
||||
description:
|
||||
- Set the initial port attribute defined in the Cumulus Linux ports.conf,
|
||||
file. This module does not do any error checking at the moment. Be careful
|
||||
to not include ports that do not exist on the switch. Carefully read the
|
||||
original ports.conf file for any exceptions or limitations.
|
||||
For more details go the Configure Switch Port Attribute Documentation at
|
||||
http://docs.cumulusnetworks.com
|
||||
options:
|
||||
speed_10g:
|
||||
description:
|
||||
- list of ports to run initial run at 10G
|
||||
speed_40g:
|
||||
description:
|
||||
- list of ports to run initial run at 40G
|
||||
speed_4_by_10g:
|
||||
description:
|
||||
- list of 40G ports that will be unganged to run as 4 10G ports.
|
||||
speed_40g_div_4:
|
||||
description:
|
||||
- list of 10G ports that will be ganged to form a 40G port
|
||||
'''
|
||||
EXAMPLES = '''
|
||||
Example playbook entries using the cl_ports module to manage the switch
|
||||
attributes defined in the ports.conf file on Cumulus Linux
|
||||
|
||||
## Unganged port config using simple args
|
||||
- name: configure ports.conf setup
|
||||
cl_ports: speed_4_by_10g="swp1, swp32" speed_40g="swp2-31"
|
||||
notify: restart switchd
|
||||
|
||||
## Unganged port configuration on certain ports using complex args
|
||||
|
||||
- name: configure ports.conf setup
|
||||
cl_ports:
|
||||
speed_4_by_10g: ['swp1-3', 'swp6']
|
||||
speed_40g: ['swp4-5', 'swp7-32']
|
||||
notify: restart switchd
|
||||
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
changed:
|
||||
description: whether the interface was changed
|
||||
returned: changed
|
||||
type: bool
|
||||
sample: True
|
||||
msg:
|
||||
description: human-readable report of success or failure
|
||||
returned: always
|
||||
type: string
|
||||
sample: "interface bond0 config updated"
|
||||
'''
|
||||
|
||||
PORTS_CONF = '/etc/cumulus/ports.conf'
|
||||
|
||||
|
||||
def hash_existing_ports_conf(module):
|
||||
module.ports_conf_hash = {}
|
||||
if not os.path.exists(PORTS_CONF):
|
||||
return False
|
||||
|
||||
try:
|
||||
existing_ports_conf = open(PORTS_CONF).readlines()
|
||||
except IOError, error_msg:
|
||||
_msg = "Failed to open %s: %s" % (PORTS_CONF, error_msg)
|
||||
module.fail_json(msg=_msg)
|
||||
return # for testing only should return on module.fail_json
|
||||
|
||||
for _line in existing_ports_conf:
|
||||
_m0 = re.match(r'^(\d+)=(\w+)', _line)
|
||||
if _m0:
|
||||
_portnum = int(_m0.group(1))
|
||||
_speed = _m0.group(2)
|
||||
module.ports_conf_hash[_portnum] = _speed
|
||||
|
||||
|
||||
def generate_new_ports_conf_hash(module):
|
||||
new_ports_conf_hash = {}
|
||||
convert_hash = {
|
||||
'speed_40g_div_4': '40G/4',
|
||||
'speed_4_by_10g': '4x10G',
|
||||
'speed_10g': '10G',
|
||||
'speed_40g': '40G'
|
||||
}
|
||||
for k in module.params.keys():
|
||||
port_range = module.params[k]
|
||||
port_setting = convert_hash[k]
|
||||
if port_range:
|
||||
port_range = [x for x in port_range if x]
|
||||
for port_str in port_range:
|
||||
port_range_str = port_str.replace('swp', '').split('-')
|
||||
if len(port_range_str) == 1:
|
||||
new_ports_conf_hash[int(port_range_str[0])] = \
|
||||
port_setting
|
||||
else:
|
||||
int_range = map(int, port_range_str)
|
||||
portnum_range = range(int_range[0], int_range[1]+1)
|
||||
for i in portnum_range:
|
||||
new_ports_conf_hash[i] = port_setting
|
||||
module.new_ports_hash = new_ports_conf_hash
|
||||
|
||||
|
||||
def compare_new_and_old_port_conf_hash(module):
|
||||
ports_conf_hash_copy = module.ports_conf_hash.copy()
|
||||
module.ports_conf_hash.update(module.new_ports_hash)
|
||||
port_num_length = len(module.ports_conf_hash.keys())
|
||||
orig_port_num_length = len(ports_conf_hash_copy.keys())
|
||||
if port_num_length != orig_port_num_length:
|
||||
module.fail_json(msg="Port numbering is wrong. \
|
||||
Too many or two few ports configured")
|
||||
return False
|
||||
elif ports_conf_hash_copy == module.ports_conf_hash:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def make_copy_of_orig_ports_conf(module):
|
||||
if os.path.exists(PORTS_CONF + '.orig'):
|
||||
return
|
||||
|
||||
try:
|
||||
shutil.copyfile(PORTS_CONF, PORTS_CONF + '.orig')
|
||||
except IOError, error_msg:
|
||||
_msg = "Failed to save the original %s: %s" % (PORTS_CONF, error_msg)
|
||||
module.fail_json(msg=_msg)
|
||||
return # for testing only
|
||||
|
||||
def write_to_ports_conf(module):
|
||||
"""
|
||||
use tempfile to first write out config in temp file
|
||||
then write to actual location. may help prevent file
|
||||
corruption. Ports.conf is a critical file for Cumulus.
|
||||
Don't want to corrupt this file under any circumstance.
|
||||
"""
|
||||
temp = tempfile.NamedTemporaryFile()
|
||||
try:
|
||||
try:
|
||||
temp.write('# Managed By Ansible\n')
|
||||
for k in sorted(module.ports_conf_hash.keys()):
|
||||
port_setting = module.ports_conf_hash[k]
|
||||
_str = "%s=%s\n" % (k, port_setting)
|
||||
temp.write(_str)
|
||||
temp.seek(0)
|
||||
shutil.copyfile(temp.name, PORTS_CONF)
|
||||
except IOError, error_msg:
|
||||
module.fail_json(
|
||||
msg="Failed to write to %s: %s" % (PORTS_CONF, error_msg))
|
||||
finally:
|
||||
temp.close()
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
speed_40g_div_4=dict(type='list'),
|
||||
speed_4_by_10g=dict(type='list'),
|
||||
speed_10g=dict(type='list'),
|
||||
speed_40g=dict(type='list')
|
||||
),
|
||||
required_one_of=[['speed_40g_div_4',
|
||||
'speed_4_by_10g',
|
||||
'speed_10g',
|
||||
'speed_40g']]
|
||||
)
|
||||
|
||||
_changed = False
|
||||
hash_existing_ports_conf(module)
|
||||
generate_new_ports_conf_hash(module)
|
||||
if compare_new_and_old_port_conf_hash(module):
|
||||
make_copy_of_orig_ports_conf(module)
|
||||
write_to_ports_conf(module)
|
||||
_changed = True
|
||||
_msg = "/etc/cumulus/ports.conf changed"
|
||||
else:
|
||||
_msg = 'No change in /etc/ports.conf'
|
||||
module.exit_json(changed=_changed, msg=_msg)
|
||||
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
# from ansible.module_utils.urls import *
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue