gitlab modules: unify authentication method (#64989)

* gitlab modules: unify authentication method
* gitlab module utils: remove useless import
* gitlab module utils: add documentation
* gitlab module utils: use distutil to compare version
* gitlab modules: sanity
* gitlab modules: remove useless import
* gitlab module utils: add missing import
* add changelog
This commit is contained in:
Guillaume Martinez 2019-11-19 11:00:34 +01:00 committed by Abhijeet Kasurde
parent bc479fcafc
commit 4e6fa59ec1
9 changed files with 61 additions and 104 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Fix GitLab modules authentication by handling `python-gitlab` library version >= 1.13.0 (https://github.com/ansible/ansible/issues/64770)

View file

@ -6,14 +6,27 @@
from __future__ import absolute_import from __future__ import absolute_import
import json import json
from distutils.version import StrictVersion
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
from ansible.module_utils._text import to_native
try: try:
from urllib import quote_plus # Python 2.X from urllib import quote_plus # Python 2.X
except ImportError: except ImportError:
from urllib.parse import quote_plus # Python 3+ from urllib.parse import quote_plus # Python 3+
import traceback
GITLAB_IMP_ERR = None
try:
import gitlab
HAS_GITLAB_PACKAGE = True
except Exception:
GITLAB_IMP_ERR = traceback.format_exc()
HAS_GITLAB_PACKAGE = False
def request(module, api_url, project, path, access_token, private_token, rawdata='', method='GET'): def request(module, api_url, project, path, access_token, private_token, rawdata='', method='GET'):
url = "%s/v4/projects/%s%s" % (api_url, quote_plus(project), path) url = "%s/v4/projects/%s%s" % (api_url, quote_plus(project), path)
@ -59,3 +72,33 @@ def findGroup(gitlab_instance, identifier):
return None return None
return project return project
def gitlabAuthentication(module):
gitlab_url = module.params['api_url']
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try:
# python-gitlab library remove support for username/password authentication since 1.13.0
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
# This condition allow to still support older version of the python-gitlab library
if StrictVersion(gitlab.__version__) < StrictVersion("1.13.0"):
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
else:
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e))
return gitlab_instance

View file

@ -132,7 +132,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import findProject from ansible.module_utils.gitlab import findProject, gitlabAuthentication
class GitLabDeployKey(object): class GitLabDeployKey(object):
@ -260,12 +260,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
gitlab_url = re.sub('/api.*', '', module.params['api_url'])
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
state = module.params['state'] state = module.params['state']
project_identifier = module.params['project'] project_identifier = module.params['project']
key_title = module.params['title'] key_title = module.params['title']
@ -275,15 +269,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e))
gitlab_deploy_key = GitLabDeployKey(module, gitlab_instance) gitlab_deploy_key = GitLabDeployKey(module, gitlab_instance)

View file

@ -140,7 +140,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import findGroup from ansible.module_utils.gitlab import findGroup, gitlabAuthentication
class GitLabGroup(object): class GitLabGroup(object):
@ -278,12 +278,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
validate_certs = module.params['validate_certs']
gitlab_url = module.params['api_url']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
group_name = module.params['name'] group_name = module.params['name']
group_path = module.params['path'] group_path = module.params['path']
description = module.params['description'] description = module.params['description']
@ -294,15 +288,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2" % to_native(e))
# Define default group_path based on group_name # Define default group_path based on group_name
if group_path is None: if group_path is None:

View file

@ -177,7 +177,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import findProject from ansible.module_utils.gitlab import findProject, gitlabAuthentication
class GitLabHook(object): class GitLabHook(object):
@ -326,12 +326,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
gitlab_url = re.sub('/api.*', '', module.params['api_url'])
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
state = module.params['state'] state = module.params['state']
project_identifier = module.params['project'] project_identifier = module.params['project']
hook_url = module.params['hook_url'] hook_url = module.params['hook_url']
@ -349,15 +343,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e))
gitlab_hook = GitLabHook(module, gitlab_instance) gitlab_hook = GitLabHook(module, gitlab_instance)

View file

@ -165,7 +165,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import findGroup, findProject from ansible.module_utils.gitlab import findGroup, findProject, gitlabAuthentication
class GitLabProject(object): class GitLabProject(object):
@ -302,12 +302,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
gitlab_url = module.params['api_url']
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
group_identifier = module.params['group'] group_identifier = module.params['group']
project_name = module.params['name'] project_name = module.params['name']
project_path = module.params['path'] project_path = module.params['path']
@ -323,15 +317,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e))
# Set project_path to project_name if it is empty. # Set project_path to project_name if it is empty.
if project_path is None: if project_path is None:

View file

@ -122,6 +122,8 @@ except Exception:
GITLAB_IMP_ERR = traceback.format_exc() GITLAB_IMP_ERR = traceback.format_exc()
HAS_GITLAB_PACKAGE = False HAS_GITLAB_PACKAGE = False
from ansible.module_utils.gitlab import gitlabAuthentication
class GitlabProjectVariables(object): class GitlabProjectVariables(object):
@ -225,8 +227,6 @@ def main():
supports_check_mode=True supports_check_mode=True
) )
api_url = module.params['api_url']
gitlab_token = module.params['api_token']
purge = module.params['purge'] purge = module.params['purge']
var_list = module.params['vars'] var_list = module.params['vars']
state = module.params['state'] state = module.params['state']
@ -234,14 +234,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=api_url, private_token=gitlab_token)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2" % to_native(e))
this_gitlab = GitlabProjectVariables(module=module, gitlab_instance=gitlab_instance) this_gitlab = GitlabProjectVariables(module=module, gitlab_instance=gitlab_instance)

View file

@ -159,6 +159,8 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import gitlabAuthentication
try: try:
cmp cmp
except NameError: except NameError:
@ -306,12 +308,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
gitlab_url = module.params['api_url']
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
state = module.params['state'] state = module.params['state']
runner_description = module.params['description'] runner_description = module.params['description']
runner_active = module.params['active'] runner_active = module.params['active']
@ -325,15 +321,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2" % to_native(e))
gitlab_runner = GitLabRunner(module, gitlab_instance) gitlab_runner = GitLabRunner(module, gitlab_instance)
runner_exists = gitlab_runner.existsRunner(runner_description) runner_exists = gitlab_runner.existsRunner(runner_description)

View file

@ -176,7 +176,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
from ansible.module_utils.gitlab import findGroup from ansible.module_utils.gitlab import findGroup, gitlabAuthentication
class GitLabUser(object): class GitLabUser(object):
@ -431,11 +431,6 @@ def main():
) )
) )
gitlab_url = module.params['api_url']
validate_certs = module.params['validate_certs']
gitlab_user = module.params['api_username']
gitlab_password = module.params['api_password']
gitlab_token = module.params['api_token']
user_name = module.params['name'] user_name = module.params['name']
state = module.params['state'] state = module.params['state']
user_username = module.params['username'].lower() user_username = module.params['username'].lower()
@ -452,15 +447,7 @@ def main():
if not HAS_GITLAB_PACKAGE: if not HAS_GITLAB_PACKAGE:
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR) module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
try: gitlab_instance = gitlabAuthentication(module)
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
gitlab_instance.auth()
except (gitlab.exceptions.GitlabAuthenticationError, gitlab.exceptions.GitlabGetError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s" % to_native(e))
except (gitlab.exceptions.GitlabHttpError) as e:
module.fail_json(msg="Failed to connect to GitLab server: %s. \
GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e))
gitlab_user = GitLabUser(module, gitlab_instance) gitlab_user = GitLabUser(module, gitlab_instance)
user_exists = gitlab_user.existsUser(user_username) user_exists = gitlab_user.existsUser(user_username)