summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Sprygada <psprygada@ansible.com>2016-06-23 12:27:33 -0700
committerPeter Sprygada <psprygada@ansible.com>2016-06-23 12:27:33 -0700
commit77922f82e2cf726cb269bf34f1f735072812b7e2 (patch)
treedd5c1f1d8d99054801e697aaa25c7a5ac90457bd
parentc117b9d79b6b79195c04eed87c66640287624943 (diff)
downloadansible-77922f82e2cf726cb269bf34f1f735072812b7e2.tar.gz
initial commit of vyos shared module with Cli transport
This adds support for the VyOS network operating system using the Cli transport. This module will simplify building VyOS based modules in Ansible
-rw-r--r--lib/ansible/module_utils/vyos.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/ansible/module_utils/vyos.py b/lib/ansible/module_utils/vyos.py
new file mode 100644
index 0000000000..1ae74b0900
--- /dev/null
+++ b/lib/ansible/module_utils/vyos.py
@@ -0,0 +1,154 @@
+#
+# (c) 2015 Peter Sprygada, <psprygada@ansible.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/>.
+#
+
+import re
+
+from ansible.module_utils.network import NetworkError, get_module, get_exception
+from ansible.module_utils.network import register_transport, to_list
+from ansible.module_utils.network import Command, NetCli
+from ansible.module_utils.shell import Shell, ShellError, HAS_PARAMIKO
+
+DEFAULT_COMMENT = 'configured by vyos_config'
+
+def argument_spec():
+ return dict(
+ config=dict(),
+ comment=dict(default=DEFAULT_COMMENT),
+ save=dict(type='bool')
+ )
+vyos_argument_spec = argument_spec()
+
+get_config = lambda x: x.params['config'] or x.config.get_config()
+
+def diff_config(candidate, config):
+ updates = set()
+ config = [str(c).replace("'", '') for c in config]
+
+ for line in candidate:
+ item = str(line).replace("'", '')
+
+ if not item.startswith('set') and not item.startswith('delete'):
+ raise ValueError('line must start with either `set` or `delete`')
+
+ elif item.startswith('set') and item not in config:
+ updates.add(line)
+
+ elif item.startswith('delete'):
+ if not config:
+ updates.add(line)
+ else:
+ item = re.sub(r'delete', 'set', item)
+ for entry in config:
+ if entry.startswith(item):
+ updates.add(line)
+
+ return list(updates)
+
+def load_config(module, candidate):
+ config = get_config(module).split('\n')
+ updates = diff_config(candidate, config)
+
+ comment = module.params['comment']
+ save = module.params['save']
+
+ result = dict(changed=False)
+
+ if updates:
+ diff = module.config.load_config(updates)
+ if diff:
+ result['diff'] = dict(prepared=diff)
+
+ result['changed'] = True
+ result['updates'] = updates
+
+ if not module.check_mode:
+ module.config.commit_config(comment=comment)
+ if save:
+ module.config.save_config()
+ else:
+ module.config.abort_config()
+
+ # exit from config mode
+ module.cli('exit')
+
+ return result
+
+
+class Cli(NetCli):
+
+ CLI_PROMPTS_RE = [
+ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"),
+ re.compile(r"\@[\w\-\.]+:\S+?[>#\$] ?$")
+ ]
+
+ CLI_ERRORS_RE = [
+ re.compile(r"\n\s*Invalid command:"),
+ re.compile(r"\nCommit failed"),
+ re.compile(r"\n\s+Set failed"),
+ ]
+
+ def connect(self, params, **kwargs):
+ super(Cli, self).connect(params, kickstart=False, **kwargs)
+ self.shell.send('set terminal length 0')
+ self._connected = True
+
+ ### Cli methods ###
+
+ def run_commands(self, commands, **kwargs):
+ commands = to_list(commands)
+ response = self.execute([str(c) for c in commands])
+ return response
+
+ ### Config methods ###
+
+ def configure(self, commands, commit=True, **kwargs):
+ """Called by Config.__call__
+ """
+ cmds = ['configure']
+ cmds.extend(to_list(commands))
+ response = self.execute(cmds)
+ if commit:
+ self.commit_config()
+ return response
+
+ def load_config(self, commands):
+ self.configure(commands, commit=False)
+ diff = None
+ if not self.execute('compare')[0].startswith('No changes'):
+ diff = self.execute(['show'])[0]
+ return diff
+
+ def get_config(self):
+ return self.execute(['show configuration commands'])[0]
+
+ def commit_config(self, confirm=0, comment=None):
+ if confirm > 0:
+ cmd = 'commit-confirm %s' % confirm
+ else:
+ cmd = 'commit'
+ if comment:
+ cmd += ' comment "%s"' % comment
+ self.execute([cmd])
+
+ def abort_config(self):
+ self.execute(['discard'])
+
+ def save_config(self):
+ self.execute(['save'])
+Cli = register_transport('cli', default=True)(Cli)