Skip to content

Instantly share code, notes, and snippets.

@sysadmind
Last active April 1, 2016 14:58
Show Gist options
  • Save sysadmind/3b8f7fa36c6addedb266ed8033cf0d6a to your computer and use it in GitHub Desktop.
Save sysadmind/3b8f7fa36c6addedb266ed8033cf0d6a to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Joe Adams <adams10301@gmail.com>
#
# This file is part of Ansible
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
DOCUMENTATION = '''
---
module: pulp_repo
author: "Joe Adams <adams10301@gmail.com>"
short_description: Add or remove Pulp repos from a remote host.
description:
- Add or remove Pulp repos from a remote host.
version_added: "2.1"
options:
name:
description:
- name of the repo to add or remove (correlates to pulp's repo-id)
required: true
default: null
state:
description:
- The repo state
required: false
default: present
choices: [ "present", "absent" ]
repo_type:
description:
- Repo plugin type to use (i.e. rpm, docker)
required: true
default: null
login_user:
description:
- User to connect to the pulp server as.
required: false
default: null
login_password:
description:
- Password to connect to the pulp server with.
required: false
default: null
feed_url:
description:
- Upstream feed URL to receive updates from.
required: false
default: null
relative_url:
description:
- Relative url for the local repository.
required: false
default: null
'''
EXAMPLES = '''
# Create a new repo with name 'my_repo'
- pulp_repo: name=my_repo state=present
# Create a repo with a feed and a relative URL
- pulp_repo: name=my_centos_updates feed_url='http://mirror.centos.org/centos/6/updates/x86_64/' relative_url='centos/6/updates' state=present
# Remove a repo from the pulp server
- pulp_repo: name=my_old_repo state=absent
'''
import pipes
class pulp_server(object):
"""
Class to interact with a pulp server
"""
def __init__(self, module, repo_type, username=None, password=None):
if username:
self.username = username
if password:
self.password = password
self.module = module
self.repo_type = repo_type
self.get_pulp_absolute_path()
self.set_pulp_base_command()
def check_repo_exists(self, repo):
repo_exists = [x for x in self.repo_list if 'repo_id' in x.keys() and x['repo_id'] == repo]
if len(repo_exists):
return True
return False
def compare_repo_feed_url(self, repo_id, feed_url):
repo_array = [x for x in self.repo_list if 'repo_id' in x.keys() and x['repo_id'] == repo_id]
if repo_array[0]['feed_url'] == feed_url:
return True
else:
return False
def compare_repo_relative_url(self, repo_id, relative_url):
repo_array = [x for x in self.repo_list if 'repo_id' in x.keys() and x['repo_id'] == repo_id]
if repo_array[0]['relative_url'] == relative_url:
return True
else:
return False
def create_repo(self, repo_id, feed_url=None, relative_url=None):
cmd = self.pulp_command
cmd += "create "
cmd += "--repo-id=%s " % pipes.quote(repo_id)
if feed_url:
cmd += " --feed=%s " % pipes.quote(feed_url)
if relative_url:
cmd += " --relative-url=%s " % pipes.quote(relative_url)
results = self.module.run_command(cmd)
if results[0] != 0:
self.module.fail_json(msg="Failed to create repo.", output=results[1])
else:
return True
def delete_repo(self, repo_id):
cmd = self.pulp_command
cmd += " delete "
cmd += " --repo-id=%s " % pipes.quote(repo_id)
results = self.module.run_command(cmd)
if results[0] != 0:
self.module.fail_json(msg="Failed to delete repo.", output=results[1])
else:
return True
def get_pulp_absolute_path(self):
self.pulp_absolute_path = self.module.get_bin_path('pulp-admin')
if not self.pulp_absolute_path:
module.fail_json(msg="pulp-admin binary could not be found.")
def parse_repo_list(self, repo_list):
repo_list_lines = repo_list.split("\n")[4:]
all_repos = []
repo = {}
for line in repo_list_lines:
# If we have a blank line, we're in between 2 repos
if line == '':
all_repos.append(repo)
repo = {}
continue
if line.startswith('Id:'):
repo['repo_id'] = line.split(":", 1)[1].strip()
continue
if line.startswith('Display Name:'):
repo['display_name'] = line.split(":", 1)[1].strip()
continue
if line.startswith('Description:'):
repo['description'] = line.split(":", 1)[1].strip()
continue
if line.startswith(' Feed:'):
repo['feed_url'] = line.split(":", 1)[1].strip()
continue
if line.startswith(' Relative URL:'):
repo['relative_url'] = line.split(":", 1)[1].strip()
continue
return all_repos
def set_pulp_base_command(self):
cmd = self.pulp_absolute_path
if self.username:
cmd += " --username=%s" % pipes.quote(self.username)
if self.password:
cmd += " --password=%s" % pipes.quote(self.password)
cmd += " %s repo" % pipes.quote(self.repo_type)
cmd += " "
self.pulp_command = cmd
def set_repo_feed_url(self, repo_id, feed_url):
cmd = self.pulp_command
cmd += "update "
cmd += " --repo-id=%s " % repo_id
cmd += " --feed=%s " % feed_url
update_output = self.module.run_command(cmd)
if update_output[0] != 0:
self.module.fail_json(msg="Error setting feed URL on repo.")
def set_repo_relative_url(self, repo_id, relative_url):
cmd = self.pulp_command
cmd += "update "
cmd += " --repo-id=%s " % repo_id
cmd += " --relative-url=%s " % relative_url
update_output = self.module.run_command(cmd)
if update_output[0] != 0:
self.module.fail_json(msg="Error setting relative URL on repo.")
def set_repo_list(self):
cmd = self.pulp_command
cmd += "list --details"
repo_list_output = self.module.run_command(cmd)
if repo_list_output[0] != 0:
self.module.fail_json(msg="Error getting repo list.")
self.repo_list = self.parse_repo_list(repo_list_output[1])
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True, aliases=['repo']),
state=dict(default="present", choices=["absent", "present"]),
repo_type=dict(default=None, required=True),
login_user=dict(default=None),
login_password=dict(default=None),
feed_url=dict(default=None),
relative_url=dict(default=None)
)
)
repo = module.params["name"]
state = module.params["state"]
login_password = module.params["login_password"]
login_user = module.params["login_user"]
feed_url = module.params["feed_url"]
repo_type = module.params["repo_type"]
relative_url = module.params["relative_url"]
server = pulp_server(module, repo_type, username=login_user, password=login_password)
server.set_repo_list()
repo_exists = server.check_repo_exists(repo)
changed = False
if state == 'absent' and repo_exists:
if server.delete_repo(repo):
changed = True
if state == 'present':
if not repo_exists:
if server.create_repo(repo, feed_url):
changed = True
else:
# Check to make sure all the settings are correct
if not server.compare_repo_feed_url(repo, feed_url):
server.set_repo_feed_url(repo, feed_url)
changed = True
if not server.compare_repo_relative_url(repo, relative_url):
server.set_repo_relative_url(repo, relative_url)
changed = True
module.exit_json(changed=changed, repo=repo)
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.database import *
from ansible.module_utils.mysql import *
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment