From 81333599cfbe6798c76b17391e4812b78172a08b Mon Sep 17 00:00:00 2001 From: David Stygstra Date: Wed, 18 Sep 2013 19:28:41 -0400 Subject: [PATCH] Modules for managing Open vSwitch bridges and ports --- net_infrastructure/openvswitch_bridge | 129 +++++++++++++++++++++++++ net_infrastructure/openvswitch_port | 133 ++++++++++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 net_infrastructure/openvswitch_bridge create mode 100644 net_infrastructure/openvswitch_port diff --git a/net_infrastructure/openvswitch_bridge b/net_infrastructure/openvswitch_bridge new file mode 100644 index 00000000000..2c87aacd396 --- /dev/null +++ b/net_infrastructure/openvswitch_bridge @@ -0,0 +1,129 @@ +#!/usr/bin/env python2 +#coding: utf-8 -*- + +# This module 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. +# +# This software 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 this software. If not, see . + +DOCUMENTATION = ''' +--- +module: openvswitch_bridge +short_description: Manage Open vSwitch bridges +requirements: [ ovs-vsctl ] +description: + - Manage Open vSwitch bridges +options: + bridge: + required: true + description: + - Name of bridge to manage + state: + required: false + default: "present" + choices: [ present, absent ] + description: + - Whether the bridge should exist + timeout: + required: false + default: 5 + description: + - How long to wait for ovs-vswitchd to respond +''' + +EXAMPLES = ''' +# Create a bridge named br-int +- openvswitch_bridge: bridge=br-int state=present +''' + + +class OVSBridge(object): + def __init__(self, module): + self.module = module + self.bridge = module.params['bridge'] + self.state = module.params['state'] + self.timeout = module.params['timeout'] + + def _vsctl(self, command): + '''Run ovs-vsctl command''' + return self.module.run_command(['ovs-vsctl', '-t', str(self.timeout)] + command) + + def exists(self): + '''Check if the bridge already exists''' + rc, _, err = self._vsctl(['br-exists', self.bridge]) + if rc == 0: # See ovs-vsctl(8) for status codes + return True + if rc == 2: + return False + raise Exception(err) + + def add(self): + '''Create the bridge''' + rc, _, err = self._vsctl(['add-br', self.bridge]) + if rc != 0: + raise Exception(err) + + def delete(self): + '''Delete the bridge''' + rc, _, err = self._vsctl(['del-br', self.bridge]) + if rc != 0: + raise Exception(err) + + def check(self): + '''Run check mode''' + try: + if self.state == 'absent' and self.exists(): + changed = True + elif self.state == 'present' and not self.exists(): + changed = True + else: + changed = False + except Exception, e: + self.module.fail_json(msg=str(e)) + self.module.exit_json(changed=changed) + + def run(self): + '''Make the necessary changes''' + result = {'changed': False} + try: + if self.state == 'absent': + if self.exists(): + self.delete() + result['changed'] = True + elif self.state == 'present': + if not self.exists(): + self.add() + result['changed'] = True + except Exception, e: + self.module.fail_json(msg=str(e)) + self.module.exit_json(**result) + + +def main(): + module = AnsibleModule( + argument_spec={ + 'bridge': {'required': True}, + 'state': {'default': 'present', 'choices': ['present', 'absent']}, + 'timeout': {'default': 5, 'type': 'int'} + }, + supports_check_mode=True, + ) + + br = OVSBridge(module) + if module.check_mode: + br.check() + else: + br.run() + + +# this is magic, see lib/ansible/module_common.py +#<> +main() diff --git a/net_infrastructure/openvswitch_port b/net_infrastructure/openvswitch_port new file mode 100644 index 00000000000..3bde7f9a5ce --- /dev/null +++ b/net_infrastructure/openvswitch_port @@ -0,0 +1,133 @@ +#!/usr/bin/env python2 +#coding: utf-8 -*- + +# This module 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. +# +# This software 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 this software. If not, see . + +DOCUMENTATION = ''' +--- +module: openvswitch_port +short_description: Manage Open vSwitch ports +requirements: [ ovs-vsctl ] +description: + - Manage Open vSwitch ports +options: + bridge: + required: true + description: + - Name of bridge to manage + port: + required: true + description: + - Name of port to manage on the bridge + state: + required: false + default: "present" + choices: [ present, absent ] + description: + - Whether the port should exist + timeout: + required: false + default: 5 + description: + - How long to wait for ovs-vswitchd to respond +''' + +EXAMPLES = ''' +# Creates port eth2 on bridge br-ex +- openvswitch_port: bridge=br-ex port=eth2 state=present +''' + + +class OVSPort(object): + def __init__(self, module): + self.module = module + self.bridge = module.params['bridge'] + self.port = module.params['port'] + self.state = module.params['state'] + self.timeout = module.params['timeout'] + + def _vsctl(self, command): + '''Run ovs-vsctl command''' + return self.module.run_command(['ovs-vsctl', '-t', str(self.timeout)] + command) + + def exists(self): + '''Check if the port already exists''' + rc, out, err = self._vsctl(['list-ports', self.bridge]) + if rc != 0: + raise Exception(err) + return any(port.rstrip() == self.port for port in out.split('\n')) + + def add(self): + '''Add the port''' + rc, _, err = self._vsctl(['add-port', self.bridge, self.port]) + if rc != 0: + raise Exception(err) + + def delete(self): + '''Remove the port''' + rc, _, err = self._vsctl(['del-port', self.bridge, self.port]) + if rc != 0: + raise Exception(err) + + def check(self): + '''Run check mode''' + try: + if self.state == 'absent' and self.exists(): + changed = True + elif self.state == 'present' and not self.exists(): + changed = True + else: + changed = False + except Exception, e: + self.module.fail_json(msg=str(e)) + self.module.exit_json(changed=changed) + + def run(self): + '''Make the necessary changes''' + result = {'changed': False} + try: + if self.state == 'absent': + if self.exists(): + self.delete() + result['changed'] = True + elif self.state == 'present': + if not self.exists(): + self.add() + result['changed'] = True + except Exception, e: + self.module.fail_json(msg=str(e)) + self.module.exit_json(**result) + + +def main(): + module = AnsibleModule( + argument_spec={ + 'bridge': {'required': True}, + 'port': {'required': True}, + 'state': {'default': 'present', 'choices': ['present', 'absent']}, + 'timeout': {'default': 5, 'type': 'int'} + }, + supports_check_mode=True, + ) + + port = OVSPort(module) + if module.check_mode: + port.check() + else: + port.run() + + +# this is magic, see lib/ansible/module_common.py +#<> +main()