mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 13:56:09 -07:00 
			
		
		
		
	Use semantic markup (modules d-g) (#6672)
* Use semantic markup.
* 'ignore:' is no longer needed.
* E() now works better.
(cherry picked from commit 2ed82e0318)
Co-authored-by: Felix Fontein <felix@fontein.de>
		
	
			
		
			
				
	
	
		
			279 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| # Copyright (c) 2021, Álvaro Torres Cogollo
 | |
| # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
 | |
| # SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| from __future__ import absolute_import, division, print_function
 | |
| __metaclass__ = type
 | |
| 
 | |
| DOCUMENTATION = '''
 | |
| ---
 | |
| module: github_repo
 | |
| short_description: Manage your repositories on Github
 | |
| version_added: 2.2.0
 | |
| description:
 | |
|   - Manages Github repositories using PyGithub library.
 | |
|   - Authentication can be done with O(access_token) or with O(username) and O(password).
 | |
| extends_documentation_fragment:
 | |
|   - community.general.attributes
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: full
 | |
|   diff_mode:
 | |
|     support: none
 | |
| options:
 | |
|   username:
 | |
|     description:
 | |
|     - Username used for authentication.
 | |
|     - This is only needed when not using O(access_token).
 | |
|     type: str
 | |
|     required: false
 | |
|   password:
 | |
|     description:
 | |
|     - Password used for authentication.
 | |
|     - This is only needed when not using O(access_token).
 | |
|     type: str
 | |
|     required: false
 | |
|   access_token:
 | |
|     description:
 | |
|     - Token parameter for authentication.
 | |
|     - This is only needed when not using O(username) and O(password).
 | |
|     type: str
 | |
|     required: false
 | |
|   name:
 | |
|     description:
 | |
|     - Repository name.
 | |
|     type: str
 | |
|     required: true
 | |
|   description:
 | |
|     description:
 | |
|     - Description for the repository.
 | |
|     - Defaults to empty if O(force_defaults=true), which is the default in this module.
 | |
|     - Defaults to empty if O(force_defaults=false) when creating a new repository.
 | |
|     - This is only used when O(state) is V(present).
 | |
|     type: str
 | |
|     required: false
 | |
|   private:
 | |
|     description:
 | |
|     - Whether the repository should be private or not.
 | |
|     - Defaults to V(false) if O(force_defaults=true), which is the default in this module.
 | |
|     - Defaults to V(false) if O(force_defaults=false) when creating a new repository.
 | |
|     - This is only used when O(state=present).
 | |
|     type: bool
 | |
|     required: false
 | |
|   state:
 | |
|     description:
 | |
|     - Whether the repository should exist or not.
 | |
|     type: str
 | |
|     default: present
 | |
|     choices: [ absent, present ]
 | |
|     required: false
 | |
|   organization:
 | |
|     description:
 | |
|     - Organization for the repository.
 | |
|     - When O(state=present), the repository will be created in the current user profile.
 | |
|     type: str
 | |
|     required: false
 | |
|   api_url:
 | |
|     description:
 | |
|     - URL to the GitHub API if not using github.com but you own instance.
 | |
|     type: str
 | |
|     default: 'https://api.github.com'
 | |
|     version_added: "3.5.0"
 | |
|   force_defaults:
 | |
|     description:
 | |
|     - Overwrite current O(description) and O(private) attributes with defaults if set to V(true), which currently is the default.
 | |
|     - The default for this option will be deprecated in a future version of this collection, and eventually change to V(false).
 | |
|     type: bool
 | |
|     default: true
 | |
|     required: false
 | |
|     version_added: 4.1.0
 | |
| requirements:
 | |
| - PyGithub>=1.54
 | |
| notes:
 | |
| - For Python 3, PyGithub>=1.54 should be used.
 | |
| - "For Python 3.5, PyGithub==1.54 should be used. More information: U(https://pygithub.readthedocs.io/en/latest/changes.html#version-1-54-november-30-2020)."
 | |
| - "For Python 2.7, PyGithub==1.45 should be used. More information: U(https://pygithub.readthedocs.io/en/latest/changes.html#version-1-45-december-29-2019)."
 | |
| author:
 | |
| - Álvaro Torres Cogollo (@atorrescogollo)
 | |
| '''
 | |
| 
 | |
| EXAMPLES = '''
 | |
| - name: Create a Github repository
 | |
|   community.general.github_repo:
 | |
|     access_token: mytoken
 | |
|     organization: MyOrganization
 | |
|     name: myrepo
 | |
|     description: "Just for fun"
 | |
|     private: true
 | |
|     state: present
 | |
|     force_defaults: false
 | |
|   register: result
 | |
| 
 | |
| - name: Delete the repository
 | |
|   community.general.github_repo:
 | |
|     username: octocat
 | |
|     password: password
 | |
|     organization: MyOrganization
 | |
|     name: myrepo
 | |
|     state: absent
 | |
|   register: result
 | |
| '''
 | |
| 
 | |
| RETURN = '''
 | |
| repo:
 | |
|   description: Repository information as JSON. See U(https://docs.github.com/en/rest/reference/repos#get-a-repository).
 | |
|   returned: success and O(state=present)
 | |
|   type: dict
 | |
| '''
 | |
| 
 | |
| import traceback
 | |
| from ansible.module_utils.basic import AnsibleModule, missing_required_lib
 | |
| 
 | |
| GITHUB_IMP_ERR = None
 | |
| try:
 | |
|     from github import Github, GithubException, GithubObject
 | |
|     from github.GithubException import UnknownObjectException
 | |
|     HAS_GITHUB_PACKAGE = True
 | |
| except Exception:
 | |
|     GITHUB_IMP_ERR = traceback.format_exc()
 | |
|     HAS_GITHUB_PACKAGE = False
 | |
| 
 | |
| 
 | |
| def authenticate(username=None, password=None, access_token=None, api_url=None):
 | |
|     if not api_url:
 | |
|         return None
 | |
| 
 | |
|     if access_token:
 | |
|         return Github(base_url=api_url, login_or_token=access_token)
 | |
|     else:
 | |
|         return Github(base_url=api_url, login_or_token=username, password=password)
 | |
| 
 | |
| 
 | |
| def create_repo(gh, name, organization=None, private=None, description=None, check_mode=False):
 | |
|     result = dict(
 | |
|         changed=False,
 | |
|         repo=dict())
 | |
|     if organization:
 | |
|         target = gh.get_organization(organization)
 | |
|     else:
 | |
|         target = gh.get_user()
 | |
| 
 | |
|     repo = None
 | |
|     try:
 | |
|         repo = target.get_repo(name=name)
 | |
|         result['repo'] = repo.raw_data
 | |
|     except UnknownObjectException:
 | |
|         if not check_mode:
 | |
|             repo = target.create_repo(
 | |
|                 name=name,
 | |
|                 private=GithubObject.NotSet if private is None else private,
 | |
|                 description=GithubObject.NotSet if description is None else description,
 | |
|             )
 | |
|             result['repo'] = repo.raw_data
 | |
| 
 | |
|         result['changed'] = True
 | |
| 
 | |
|     changes = {}
 | |
|     if private is not None:
 | |
|         if repo is None or repo.raw_data['private'] != private:
 | |
|             changes['private'] = private
 | |
|     if description is not None:
 | |
|         if repo is None or repo.raw_data['description'] not in (description, description or None):
 | |
|             changes['description'] = description
 | |
| 
 | |
|     if changes:
 | |
|         if not check_mode:
 | |
|             repo.edit(**changes)
 | |
| 
 | |
|         result['repo'].update({
 | |
|             'private': repo._private.value if not check_mode else private,
 | |
|             'description': repo._description.value if not check_mode else description,
 | |
|         })
 | |
|         result['changed'] = True
 | |
| 
 | |
|     return result
 | |
| 
 | |
| 
 | |
| def delete_repo(gh, name, organization=None, check_mode=False):
 | |
|     result = dict(changed=False)
 | |
|     if organization:
 | |
|         target = gh.get_organization(organization)
 | |
|     else:
 | |
|         target = gh.get_user()
 | |
|     try:
 | |
|         repo = target.get_repo(name=name)
 | |
|         if not check_mode:
 | |
|             repo.delete()
 | |
|         result['changed'] = True
 | |
|     except UnknownObjectException:
 | |
|         pass
 | |
| 
 | |
|     return result
 | |
| 
 | |
| 
 | |
| def run_module(params, check_mode=False):
 | |
|     if params['force_defaults']:
 | |
|         params['description'] = params['description'] or ''
 | |
|         params['private'] = params['private'] or False
 | |
| 
 | |
|     gh = authenticate(
 | |
|         username=params['username'], password=params['password'], access_token=params['access_token'],
 | |
|         api_url=params['api_url'])
 | |
|     if params['state'] == "absent":
 | |
|         return delete_repo(
 | |
|             gh=gh,
 | |
|             name=params['name'],
 | |
|             organization=params['organization'],
 | |
|             check_mode=check_mode
 | |
|         )
 | |
|     else:
 | |
|         return create_repo(
 | |
|             gh=gh,
 | |
|             name=params['name'],
 | |
|             organization=params['organization'],
 | |
|             private=params['private'],
 | |
|             description=params['description'],
 | |
|             check_mode=check_mode
 | |
|         )
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     module_args = dict(
 | |
|         username=dict(type='str'),
 | |
|         password=dict(type='str', no_log=True),
 | |
|         access_token=dict(type='str', no_log=True),
 | |
|         name=dict(type='str', required=True),
 | |
|         state=dict(type='str', required=False, default="present",
 | |
|                    choices=["present", "absent"]),
 | |
|         organization=dict(type='str', required=False, default=None),
 | |
|         private=dict(type='bool'),
 | |
|         description=dict(type='str'),
 | |
|         api_url=dict(type='str', required=False, default='https://api.github.com'),
 | |
|         force_defaults=dict(type='bool', default=True),
 | |
|     )
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=module_args,
 | |
|         supports_check_mode=True,
 | |
|         required_together=[('username', 'password')],
 | |
|         required_one_of=[('username', 'access_token')],
 | |
|         mutually_exclusive=[('username', 'access_token')]
 | |
|     )
 | |
| 
 | |
|     if not HAS_GITHUB_PACKAGE:
 | |
|         module.fail_json(msg=missing_required_lib(
 | |
|             "PyGithub"), exception=GITHUB_IMP_ERR)
 | |
| 
 | |
|     try:
 | |
|         result = run_module(module.params, module.check_mode)
 | |
|         module.exit_json(**result)
 | |
|     except GithubException as e:
 | |
|         module.fail_json(msg="Github error. {0}".format(repr(e)))
 | |
|     except Exception as e:
 | |
|         module.fail_json(msg="Unexpected error. {0}".format(repr(e)))
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |