From 054eb90ae52b6065caf7d5a52dc887bff06b46a2 Mon Sep 17 00:00:00 2001 From: Amin Vakil Date: Fri, 14 May 2021 12:30:59 +0430 Subject: [PATCH] gitlab_user: add expires_at option (#2450) * gitlab_user: add expires_at option * Add changelog * Add integration test * Add expires_at to addSshKeyToUser function * password is required if state is set to present * Check expires_at will not be added to a present ssh key * add documentation about present ssh key * add expires_at to unit tests * Improve documentation Co-authored-by: Felix Fontein * Only pass expires_at to api when it is not None * Emphasize on SSH public key * Apply felixfontein suggestion Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein --- ...450-gitlab_user-add_expires_at_option.yaml | 3 + .../source_control/gitlab/gitlab_user.py | 28 +++- .../targets/gitlab_user/defaults/main.yml | 3 + .../targets/gitlab_user/tasks/main.yml | 12 +- .../targets/gitlab_user/tasks/sshkey.yml | 134 ++++++++++++++++++ .../source_control/gitlab/test_gitlab_user.py | 6 +- 6 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml create mode 100644 tests/integration/targets/gitlab_user/tasks/sshkey.yml diff --git a/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml b/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml new file mode 100644 index 0000000000..290e13847a --- /dev/null +++ b/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - gitlab_user - add ``expires_at`` option (https://github.com/ansible-collections/community.general/issues/2325). diff --git a/plugins/modules/source_control/gitlab/gitlab_user.py b/plugins/modules/source_control/gitlab/gitlab_user.py index 9fefe1aff9..4d300ea842 100644 --- a/plugins/modules/source_control/gitlab/gitlab_user.py +++ b/plugins/modules/source_control/gitlab/gitlab_user.py @@ -57,16 +57,22 @@ options: type: str sshkey_name: description: - - The name of the sshkey + - The name of the SSH public key. type: str sshkey_file: description: - - The ssh key itself. + - The SSH public key itself. type: str + sshkey_expires_at: + description: + - The expiration date of the SSH public key in ISO 8601 format C(YYYY-MM-DDTHH:MM:SSZ). + - This is only used when adding new SSH public keys. + type: str + version_added: 3.1.0 group: description: - Id or Full path of parent group in the form of group/name. - - Add user as an member to this group. + - Add user as a member to this group. type: str access_level: description: @@ -254,7 +260,8 @@ class GitLabUser(object): if options['sshkey_name'] and options['sshkey_file']: key_changed = self.addSshKeyToUser(user, { 'name': options['sshkey_name'], - 'file': options['sshkey_file']}) + 'file': options['sshkey_file'], + 'expires_at': options['sshkey_expires_at']}) changed = changed or key_changed # Assign group @@ -295,7 +302,7 @@ class GitLabUser(object): ''' @param user User object - @param sshkey Dict containing sshkey infos {"name": "", "file": ""} + @param sshkey Dict containing sshkey infos {"name": "", "file": "", "expires_at": ""} ''' def addSshKeyToUser(self, user, sshkey): if not self.sshKeyExists(user, sshkey['name']): @@ -303,9 +310,13 @@ class GitLabUser(object): return True try: - user.keys.create({ + parameter = { 'title': sshkey['name'], - 'key': sshkey['file']}) + 'key': sshkey['file'], + } + if sshkey['expires_at'] is not None: + parameter['expires_at'] = sshkey['expires_at'] + user.keys.create(parameter) except gitlab.exceptions.GitlabCreateError as e: self._module.fail_json(msg="Failed to assign sshkey to user: %s" % to_native(e)) return True @@ -471,6 +482,7 @@ def main(): email=dict(type='str'), sshkey_name=dict(type='str'), sshkey_file=dict(type='str', no_log=False), + sshkey_expires_at=dict(type='str', no_log=False), group=dict(type='str'), access_level=dict(type='str', default="guest", choices=["developer", "guest", "maintainer", "master", "owner", "reporter"]), confirm=dict(type='bool', default=True), @@ -503,6 +515,7 @@ def main(): user_email = module.params['email'] user_sshkey_name = module.params['sshkey_name'] user_sshkey_file = module.params['sshkey_file'] + user_sshkey_expires_at = module.params['sshkey_expires_at'] group_path = module.params['group'] access_level = module.params['access_level'] confirm = module.params['confirm'] @@ -549,6 +562,7 @@ def main(): "email": user_email, "sshkey_name": user_sshkey_name, "sshkey_file": user_sshkey_file, + "sshkey_expires_at": user_sshkey_expires_at, "group_path": group_path, "access_level": access_level, "confirm": confirm, diff --git a/tests/integration/targets/gitlab_user/defaults/main.yml b/tests/integration/targets/gitlab_user/defaults/main.yml index a6755cf412..bbe016b0a8 100644 --- a/tests/integration/targets/gitlab_user/defaults/main.yml +++ b/tests/integration/targets/gitlab_user/defaults/main.yml @@ -1,3 +1,6 @@ gitlab_user: ansible_test_user gitlab_user_pass: Secr3tPassw00rd gitlab_user_email: root@localhost +gitlab_sshkey_name: ansibletest +gitlab_sshkey_file: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDI8GIMlrirf+zsvBpxnF0daykP6YEJ5wytZXhDGD2dZXg9Tln0KUSDgreT3FDgoabjlOmG1L/nhu6ML76WCsmc/wnVMlXlDlQpVJSQ2PCxGNs9WRW7Y/Pk6t9KtV/VSYr0LaPgLEU8VkffSUBJezbKa1cssjb4CmRRqcePRNYpgCXdK05TEgFvmXl9qIM8Domf1ak1PlbyMmi/MytzHmnVFzxgUKv5c0Mr+vguCi131gPdh3QSf5AHPLEoO9LcMfu2IO1zvl61wYfsJ0Wn2Fncw+tJQfUin0ffTFgUIsGqki04/YjXyWynjSwQf5Jym4BYM0i2zlDUyRxs4/Tfp4yvJFik42ambzjLK6poq+iCpQReeYih9WZUaZwUQe7zYWhTOuoV7ydsk8+kDRMPidF9K5zWkQnglGrOzdbTqnhxNpwHCg2eSRJ49kPYLOH76g8P7IQvl+zluG0o8Nndir1WcYil4D4CCBskM8WbmrElZH1CRyP/NQMNIf4hFMItTjk= ansible@ansible +gitlab_sshkey_expires_at: 2030-01-01T00:00:00.000Z diff --git a/tests/integration/targets/gitlab_user/tasks/main.yml b/tests/integration/targets/gitlab_user/tasks/main.yml index 6cbcd14c34..dddf7aaea8 100644 --- a/tests/integration/targets/gitlab_user/tasks/main.yml +++ b/tests/integration/targets/gitlab_user/tasks/main.yml @@ -56,7 +56,7 @@ - gitlab_user_state_again.user.is_admin == False -- name: Update User Test => Make User Admin +- name: Update User Test => Make User Admin gitlab_user: api_url: "{{ gitlab_host }}" email: "{{ gitlab_user_email }}" @@ -189,8 +189,8 @@ api_url: "{{ gitlab_host }}" validate_certs: False - # note: the only way to check if a password really is what it is expected - # to be is to use it for login, so we use it here instead of the + # note: the only way to check if a password really is what it is expected + # to be is to use it for login, so we use it here instead of the # default token assuming that a user can always change its own password api_username: "{{ gitlab_user }}" api_password: "{{ gitlab_user_pass }}" @@ -205,8 +205,8 @@ - name: Check PW setting return state assert: that: - # note: there is no way to determine if a password has changed or - # not, so it can only be always yellow or always green, we + # note: there is no way to determine if a password has changed or + # not, so it can only be always yellow or always green, we # decided for always green for now - gitlab_user_state is not changed @@ -248,3 +248,5 @@ assert: that: - gitlab_user_state is not changed + +- include_tasks: sshkey.yml diff --git a/tests/integration/targets/gitlab_user/tasks/sshkey.yml b/tests/integration/targets/gitlab_user/tasks/sshkey.yml new file mode 100644 index 0000000000..2d2067e74b --- /dev/null +++ b/tests/integration/targets/gitlab_user/tasks/sshkey.yml @@ -0,0 +1,134 @@ +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: Create gitlab user with sshkey credentials + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + state: present + register: gitlab_user_sshkey + +- name: Check user has been created correctly + assert: + that: + - gitlab_user_sshkey is changed + +- name: Create gitlab user again + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + state: present + register: gitlab_user_sshkey_again + +- name: Check state is not changed + assert: + that: + - gitlab_user_sshkey_again is not changed + +- name: Add expires_at to an already created gitlab user with ssh key + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_created_user_sshkey_expires_at + +- name: Check expires_at will not be added to a present ssh key + assert: + that: + - gitlab_user_created_user_sshkey_expires_at is not changed + +- name: Remove created gitlab user + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + validate_certs: false + state: absent + register: gitlab_user_sshkey_remove + +- name: Check user has been removed correctly + assert: + that: + - gitlab_user_sshkey_remove is changed + +- name: Create gitlab user with sshkey and expires_at + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_sshkey_expires_at + +- name: Check user has been created correctly + assert: + that: + - gitlab_user_sshkey_expires_at is changed + +- name: Create gitlab user with sshkey and expires_at again + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_sshkey_expires_at_again + +- name: Check state is not changed + assert: + that: + - gitlab_user_sshkey_expires_at_again is not changed + +- name: Remove created gitlab user + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + validate_certs: false + state: absent + register: gitlab_user_sshkey_expires_at_remove + +- name: Check user has been removed correctly + assert: + that: + - gitlab_user_sshkey_expires_at_remove is changed diff --git a/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py b/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py index 4a47654a8c..5722854e17 100644 --- a/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py +++ b/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py @@ -144,7 +144,8 @@ class TestGitlabUser(GitlabModuleTestCase): 'name': "Public key", 'file': "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJe" "jgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4" - "soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="}) + "soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", + 'expires_at': ""}) self.assertEqual(rvalue, False) rvalue = self.moduleUtil.addSshKeyToUser(user, { @@ -153,7 +154,8 @@ class TestGitlabUser(GitlabModuleTestCase): "dRuSuA5zszUJzYPPUSRAX3BCgTqLqYx//UuVncK7YqLVSbbwjKR2Ez5lISgCnVfLVEXzwhv+" "xawxKWmI7hJ5S0tOv6MJ+IxyTa4xcKwJTwB86z22n9fVOQeJTR2dSOH1WJrf0PvRk+KVNY2j" "TiGHTi9AIjLnyD/jWRpOgtdfkLRc8EzAWrWlgNmH2WOKBw6za0az6XoG75obUdFVdW3qcD0x" - "c809OHLi7FDf+E7U4wiZJCFuUizMeXyuK/SkaE1aee4Qp5R4dxTR4TP9M1XAYkf+kF0W9srZ+mhF069XD/zhUPJsvwEF"}) + "c809OHLi7FDf+E7U4wiZJCFuUizMeXyuK/SkaE1aee4Qp5R4dxTR4TP9M1XAYkf+kF0W9srZ+mhF069XD/zhUPJsvwEF", + 'expires_at': "2027-01-01"}) self.assertEqual(rvalue, True) @with_httmock(resp_get_group)