From 0f05100002a7d3144b41261a7de1ca892565c231 Mon Sep 17 00:00:00 2001
From: Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
Date: Wed, 6 Nov 2013 18:17:34 +0100
Subject: [PATCH] Add zypper_repository module

This change adds the "zypper_repository" module to the packaging library. This
module is used to add and remove additional repositories.
---
 packaging/zypper_repository | 157 ++++++++++++++++++++++++++++++++++++
 1 file changed, 157 insertions(+)
 create mode 100644 packaging/zypper_repository

diff --git a/packaging/zypper_repository b/packaging/zypper_repository
new file mode 100644
index 00000000000..26943b917ec
--- /dev/null
+++ b/packaging/zypper_repository
@@ -0,0 +1,157 @@
+#!/usr/bin/python
+# encoding: utf-8
+
+# (c) 2013, Matthias Vogelgesang <matthias.vogelgesang@gmail.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: zypper_repository
+author: Matthias Vogelgesang
+version_added: "1.4"
+short_description: Add and remove Zypper repositories
+description:
+    - Add or remove Zypper repositories on SUSE and openSUSE
+options:
+    name:
+        required: true
+        default: none
+        description:
+            - A name for the repository.
+    repo:
+        required: true
+        default: none
+        description:
+            - URI of the repository or .repo file.
+    state:
+        required: false
+        choices: [ "absent", "present" ]
+        default: "present"
+        description:
+            - A source string state.
+    description:
+        required: false
+        default: none
+        description:
+            - A description of the repository
+    disable_gpg_check:
+        description:
+          - Whether to disable GPG signature checking of
+            all packages. Has an effect only if state is
+            I(present).
+        required: false
+        default: "no"
+        choices: [ "yes", "no" ]
+        aliases: []
+notes: []
+requirements: [ zypper ]
+'''
+
+EXAMPLES = '''
+# Add NVIDIA repository for graphics drivers
+- zypper_repository: name=nvidia-repo repo='ftp://download.nvidia.com/opensuse/12.2' state=present
+
+# Remove NVIDIA repository
+- zypper_repository: name=nvidia-repo repo='ftp://download.nvidia.com/opensuse/12.2' state=absent
+'''
+
+
+def repo_exists(module, repo):
+    """Return (rc, stdout, stderr, found) tuple"""
+    cmd = ['/usr/bin/zypper', 'lr', '--uri']
+
+    rc, stdout, stderr = module.run_command(cmd, check_rc=False)
+    return (rc, stdout, stderr, repo in stdout)
+
+
+def add_repo(module, repo, alias, description, disable_gpg_check):
+    cmd = ['/usr/bin/zypper', 'ar', '--check', '--refresh']
+
+    if description:
+        cmd.extend(['--name', description])
+
+    if disable_gpg_check:
+        cmd.append('--no-gpgcheck')
+
+    cmd.append(repo)
+
+    if not repo.endswith('.repo'):
+        cmd.append(alias)
+
+    rc, stdout, stderr = module.run_command(cmd, check_rc=False)
+    changed = rc == 0
+    return (rc, stdout, stderr, changed)
+
+
+def remove_repo(module, repo):
+    cmd = ['/usr/bin/zypper', 'rr', repo]
+
+    rc, stdout, stderr = module.run_command(cmd, check_rc=False)
+    changed = rc == 0
+    return (rc, stdout, stderr, changed)
+
+
+def fail_if_rc_is_null(module, rc, stdout, stderr):
+    if rc != 0:
+        module.fail_json(msg=stderr if stderr else stdout)
+
+
+def main():
+    module = AnsibleModule(
+        argument_spec=dict(
+            name=dict(required=True),
+            repo=dict(required=True),
+            state=dict(choices=['present', 'absent'], default='present'),
+            description=dict(required=False),
+            disable_gpg_check = dict(required=False, default='no', type='bool'),
+        ),
+        supports_check_mode=True,
+    )
+
+    repo = module.params['repo']
+    state = module.params['state']
+    name = module.params['name']
+    description = module.params['description']
+    disable_gpg_check = module.params['disable_gpg_check']
+
+    def exit_unchanged():
+        module.exit_json(changed=False, repo=repo, state=state, name=name)
+
+    rc, stdout, stderr, exists = repo_exists(module, repo)
+    fail_if_rc_is_null(module, rc, stdout, stderr)
+
+    if state == 'present':
+        if exists:
+            exit_unchanged()
+
+        result = add_repo(module, repo, name, description, disable_gpg_check)
+    elif state == 'absent':
+        if not exists:
+            exit_unchanged()
+
+        result = remove_repo(module, repo)
+
+    rc, stdout, stderr, changed = result
+    fail_if_rc_is_null(module, rc, stdout, stderr)
+
+    module.exit_json(changed=changed, repo=repo, state=state)
+
+# this is magic, see lib/ansible/module_common.py
+#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
+
+main()