Add mode to delete LDAP users
Create a new parameter mode to remove LDAP user with keystone account and sudo access if exists. The playbook run a set of tasks to remove the user in all subclouds. The objective of the playbook is to remove the specified ldap account to disallow future ssh connects to the system using the account. The playbook works for stand-alone as well as Distributed Cloud systems. Test Plan: PASS: Create user with mode 'create' and then delete the same user using mode 'delete'. PASS: Verify the user deleted can not connect using SSH to all subclouds PASS: Verify the script can run in stand-alone system PASS: Verify the script can run in distributed cloud Story: 2009759 Task: 44537 Signed-off-by: Alexandre Horst <alexandre.horst@windriver.com> Change-Id: I7271d77b2daa5beb5d55052ad7c9c2f0c4f36719
This commit is contained in:
parent
e849974678
commit
25370ed25e
@ -32,8 +32,12 @@
|
||||
# ansible-playbook --inventory inventory-secure --ask-vault-pass \
|
||||
# --extra-vars='user_id=JohnDoo sudo_permission=yes' \
|
||||
# /usr/share/ansible/stx-ansible/playbooks/manage_local_ldap_account.yml
|
||||
|
||||
|
||||
#
|
||||
# If you wish to delete an existing user account (e.g. na-admin):
|
||||
#
|
||||
# ansible-playbook --inventory inventory --extra-vars='user_id=na-admin \
|
||||
# mode=delete' /usr/share/ansible/stx-ansible/playbooks/manage_local_ldap_account.yml
|
||||
#
|
||||
|
||||
[all:vars]
|
||||
ansible_user=sysadmin
|
||||
|
@ -32,10 +32,18 @@
|
||||
# playbook enables this option while the user account creation is progressing
|
||||
# and disables it when complete.
|
||||
#
|
||||
# Example command:
|
||||
# Example to add user 'na-admin' (mode=create is default):
|
||||
# ansible-playbook --inventory inventory --extra-vars='user_id=na-admin' \
|
||||
# /usr/share/ansible/stx-ansible/playbooks/manage_local_ldap_account.yml
|
||||
#
|
||||
# Example to add user 'na-admin' with the use of variable mode=create:
|
||||
# ansible-playbook --inventory inventory --extra-vars='user_id=na-admin mode=create' \
|
||||
# /usr/share/ansible/stx-ansible/playbooks/manage_local_ldap_account.yml
|
||||
#
|
||||
# Example to delete user 'na-admin':
|
||||
# ansible-playbook --inventory inventory --extra-vars='user_id=na-admin \
|
||||
# mode=delete' /usr/share/ansible/stx-ansible/playbooks/manage_local_ldap_account.yml
|
||||
#
|
||||
|
||||
- hosts: systemcontroller
|
||||
gather_facts: no
|
||||
@ -45,24 +53,44 @@
|
||||
prompt: "What is the name of the user account?"
|
||||
private: no
|
||||
|
||||
- name: user_password
|
||||
prompt: "What is the password for the user account?"
|
||||
private: yes
|
||||
unsafe: yes
|
||||
|
||||
pre_tasks:
|
||||
- set_fact:
|
||||
password_change_period: 90
|
||||
password_warning_period: 2
|
||||
in_mode: "{{ mode }}"
|
||||
when: mode is defined
|
||||
|
||||
- name: Validate in_mode
|
||||
fail:
|
||||
msg: "The mode must be 'create' or 'delete'."
|
||||
when: "in_mode not in ['create', 'delete']"
|
||||
|
||||
- name: Validate user_id
|
||||
fail:
|
||||
msg: "The user account cannot be empty. Please provide a valid user account."
|
||||
when: user_id == ''
|
||||
|
||||
- name: Validate user_password
|
||||
fail:
|
||||
msg: "The password cannot be empty. Please provide a valid password for the user account."
|
||||
when: user_password == ''
|
||||
- name: Default to create if mode is not specified
|
||||
set_fact:
|
||||
in_mode: "create"
|
||||
when: "in_mode is not defined"
|
||||
|
||||
- block:
|
||||
- pause:
|
||||
prompt: "What is the password for the user account?"
|
||||
echo: no
|
||||
register: prompt
|
||||
no_log: no
|
||||
- set_fact:
|
||||
in_user_password: "{{ prompt.user_input }}"
|
||||
no_log: no
|
||||
- name: Validate user_password
|
||||
fail:
|
||||
msg: "The password cannot be empty. Please provide a valid password for the user account."
|
||||
when: "in_mode == 'create' and ( in_user_password is not defined and in_user_password == '' )"
|
||||
when: in_mode == 'create'
|
||||
|
||||
- set_fact:
|
||||
password_change_period: 90
|
||||
password_warning_period: 2
|
||||
|
||||
# The user id and password variables need to be explicitly set here.
|
||||
# Otherwise, there would be undefined variable errors in subsequent
|
||||
@ -70,7 +98,6 @@
|
||||
- name: Set the user id and password facts for subsequent plays
|
||||
set_fact:
|
||||
in_user_id: "{{ user_id }}"
|
||||
in_user_password: "{{ user_password }}"
|
||||
|
||||
- name: Set sudo_permission flag fact upfront
|
||||
set_fact:
|
||||
@ -82,8 +109,14 @@
|
||||
vars:
|
||||
ssh_internal_args: -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
|
||||
|
||||
roles:
|
||||
- manage-local-ldap-account/create-account
|
||||
tasks:
|
||||
- include_role:
|
||||
name: manage-local-ldap-account/create-account
|
||||
when: in_mode == 'create'
|
||||
|
||||
- include_role:
|
||||
name: manage-local-ldap-account/delete-account
|
||||
when: in_mode == 'delete'
|
||||
|
||||
- hosts: all
|
||||
gather_facts: no
|
||||
@ -91,5 +124,45 @@
|
||||
vars:
|
||||
ssh_internal_args: -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
|
||||
|
||||
roles:
|
||||
- manage-local-ldap-account/create-keystone-account
|
||||
tasks:
|
||||
- name: Enable AllowTcpForwarding setting in ssh config
|
||||
lineinfile:
|
||||
regexp: ^[ \t]*AllowTcpForwarding([ \t]+.*)$
|
||||
line: AllowTcpForwarding yes
|
||||
dest: /etc/ssh/sshd_config
|
||||
validate: sshd -t -f %s
|
||||
notify:
|
||||
- reload sshd
|
||||
become: yes
|
||||
when: ('systemcontroller' in group_names)
|
||||
|
||||
- meta: flush_handlers
|
||||
|
||||
- name: Manage keystone user {{ in_user_id }}
|
||||
block:
|
||||
- include_role:
|
||||
name: manage-local-ldap-account/create-keystone-account
|
||||
when: in_mode == 'create'
|
||||
|
||||
- include_role:
|
||||
name: manage-local-ldap-account/delete-keystone-account
|
||||
when: in_mode == 'delete'
|
||||
|
||||
always:
|
||||
- name: Disable AllowTcpForwarding setting in ssh config
|
||||
lineinfile:
|
||||
regexp: ^[ \t]*AllowTcpForwarding([ \t]+.*)$
|
||||
line: AllowTcpForwarding no
|
||||
dest: /etc/ssh/sshd_config
|
||||
validate: sshd -t -f %s
|
||||
notify:
|
||||
- reload sshd
|
||||
when: ('systemcontroller' in group_names)
|
||||
become: yes
|
||||
|
||||
handlers:
|
||||
- name: reload sshd
|
||||
service:
|
||||
name: sshd
|
||||
state: reloaded
|
||||
become: true
|
||||
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Tasks to populate the inventory with managed subclouds.
|
||||
|
||||
- name: Populate inventory with subclouds
|
||||
add_host:
|
||||
name: "{{ in_item }}"
|
||||
groups: "subclouds"
|
||||
in_user_id: "{{ in_user_id }}"
|
||||
ssh_internal_args: "{{ ssh_internal_args }}"
|
||||
ansible_ssh_common_args:
|
||||
'-o ProxyCommand="sshpass -p {{ ansible_password }} ssh -W [%h]:%p -q {{ ansible_user }}@{{ ansible_host }}"'
|
||||
in_sudo_permission: "{{ in_sudo_permission }}"
|
||||
in_mode: "{{ in_mode }}"
|
||||
in_user_password: "{{ in_user_password if in_mode == 'create' else '' }}"
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# The file has tasks to get/set some flags related to distributed cloud.
|
||||
|
||||
- name: Get distributed_cloud role
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
system show | grep distributed_cloud_role | awk '{ print $4 }'
|
||||
register: distributed_cloud_role
|
||||
|
||||
- name: Set if system is a DC
|
||||
set_fact:
|
||||
is_dc: "{{ true if distributed_cloud_role.stdout == 'systemcontroller' else false }}"
|
@ -0,0 +1,28 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# The file has tasks to get/set some flags related to subclouds from
|
||||
# central system controller. This role also builds the list of subclouds
|
||||
# that are currently online and managed to be used in the next play.
|
||||
|
||||
- name: Set os_param_region_name if system is a DC
|
||||
set_fact:
|
||||
os_param_region_name: "{{ '--os-region-name SystemController' if is_dc | bool else '' }}"
|
||||
|
||||
- name: Tasks for distributed cloud
|
||||
block:
|
||||
- name: Get subcloud list
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
dcmanager subcloud list --format yaml
|
||||
register: subcloud_list_result
|
||||
|
||||
- name: Set a list for subclouds
|
||||
set_fact:
|
||||
subcloud_list: "{{ subcloud_list | default([]) + [ item.name ] }}"
|
||||
when: (item.management == "managed" and item.availability == "online")
|
||||
loop: "{{ subcloud_list_result.stdout | from_yaml if subcloud_list_result.stdout else [] }}"
|
||||
|
||||
when: is_dc | bool
|
@ -3,10 +3,9 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Tasks to check LDAP user existence, to create LDAP users and to set new
|
||||
# initial password and to create home directory. If the system is distributed
|
||||
# cloud, this role also builds the list of subclouds that are currently online
|
||||
# and managed to be used in the next play.
|
||||
# Tasks to check LDAP user existence, to create LDAP users and set a new
|
||||
# initial password, and to create the home directory. If the system is
|
||||
# distributed cloud, it dynamically adds subclouds to the target host list.
|
||||
|
||||
- name: Check if LDAP user exists
|
||||
shell: ldapsearch -x -LLL uid={{ in_user_id }}
|
||||
@ -38,46 +37,18 @@
|
||||
no_log: true
|
||||
when: in_user_id_check.stdout == ""
|
||||
|
||||
- name: Get distributed_cloud role
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
system show | grep distributed_cloud_role | awk '{ print $4 }'
|
||||
register: distributed_cloud_role
|
||||
- name: Get distributed cloud role
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/get-distributed-role
|
||||
|
||||
- name: Set if system is a DC
|
||||
set_fact:
|
||||
is_dc: "{{ true if distributed_cloud_role.stdout == 'systemcontroller' else false }}"
|
||||
|
||||
- name: Tasks for distributed cloud
|
||||
block:
|
||||
- name: Get subcloud list
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
dcmanager subcloud list --format yaml
|
||||
register: subcloud_list_result
|
||||
|
||||
- name: Set a list for subclouds
|
||||
set_fact:
|
||||
subcloud_list: "{{ subcloud_list | default([]) + [ item.name ] }}"
|
||||
when: (item.management == "managed" and item.availability == "online")
|
||||
loop: "{{ subcloud_list_result.stdout | from_yaml if subcloud_list_result.stdout else [] }}"
|
||||
|
||||
- name: Populate inventory with subclouds
|
||||
add_host:
|
||||
name: "{{ item }}"
|
||||
groups: "subclouds"
|
||||
in_user_id: "{{ in_user_id }}"
|
||||
in_user_password: "{{ in_user_password }}"
|
||||
password_change_period: "{{ password_change_period }}"
|
||||
password_warning_period: "{{ password_warning_period }}"
|
||||
ssh_internal_args: "{{ ssh_internal_args }}"
|
||||
ansible_ssh_common_args:
|
||||
'-o ProxyCommand="sshpass -p {{ ansible_password }} ssh -W [%h]:%p -q {{ ansible_user }}@{{ ansible_host }}"'
|
||||
in_sudo_permission: "{{ in_sudo_permission }}"
|
||||
loop: "{{ subcloud_list }}"
|
||||
- name: Get online subclouds
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/get-online-subclouds
|
||||
|
||||
- name: Populate inventory with subclouds
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/add-hosts
|
||||
vars:
|
||||
in_item: "{{ item }}"
|
||||
loop: "{{ subcloud_list }}"
|
||||
when: is_dc | bool
|
||||
|
||||
- name: Set os_param_region_name if system is a DC
|
||||
set_fact:
|
||||
os_param_region_name: "{{ '--os-region-name SystemController' if is_dc | bool else '' }}"
|
||||
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Handler to reload sshd service
|
||||
|
||||
- name: reload sshd
|
||||
service:
|
||||
name: sshd
|
||||
state: reloaded
|
||||
become: true
|
@ -7,110 +7,83 @@
|
||||
# controller, and subclouds as well for distributed systems with specific
|
||||
# admin role.
|
||||
|
||||
- name: Create keystone user {{ in_user_id }}
|
||||
- name: Create keystone user on System Controller
|
||||
block:
|
||||
- name: Enable AllowTcpForwarding setting in ssh config
|
||||
lineinfile:
|
||||
regexp: ^[ \t]*AllowTcpForwarding([ \t]+.*)$
|
||||
line: AllowTcpForwarding yes
|
||||
dest: /etc/ssh/sshd_config
|
||||
validate: sshd -t -f %s
|
||||
notify:
|
||||
- reload sshd
|
||||
become: yes
|
||||
when: ('systemcontroller' in group_names)
|
||||
- name: Create the keystone user {{ in_user_id }}
|
||||
expect:
|
||||
command: >-
|
||||
/bin/sh -c 'source /etc/platform/openrc; openstack {{ os_param_region_name }} user create --project
|
||||
admin --password-prompt {{ in_user_id }}'
|
||||
responses:
|
||||
Password: '{{ in_user_password }}'
|
||||
"\\~\\$": exit
|
||||
|
||||
- meta: flush_handlers
|
||||
- name: Add keystone user to the admin role
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
openstack {{ os_param_region_name }} role add --user {{ in_user_id }} --project admin admin
|
||||
|
||||
- name: Create keystone user on System Controller
|
||||
block:
|
||||
- name: Create the keystone user {{ in_user_id }}
|
||||
expect:
|
||||
command: >-
|
||||
/bin/sh -c 'source /etc/platform/openrc; openstack {{ os_param_region_name }} user create --project
|
||||
admin --password-prompt {{ in_user_id }}'
|
||||
responses:
|
||||
Password: '{{ in_user_password }}'
|
||||
"\\~\\$": exit
|
||||
when: ('systemcontroller' in group_names)
|
||||
|
||||
- name: Add keystone user to the admin role
|
||||
shell: |
|
||||
source /etc/platform/openrc
|
||||
openstack {{ os_param_region_name }} role add --user {{ in_user_id }} --project admin admin
|
||||
- name: Complete keystone user creation on the subcloud
|
||||
block:
|
||||
- name: Wait for keystone user to propagate to all subclouds
|
||||
shell: source /etc/platform/openrc; openstack user show {{ in_user_id }}
|
||||
register: user_output
|
||||
until: user_output.rc == 0
|
||||
retries: 12
|
||||
delay: 10
|
||||
|
||||
when: ('systemcontroller' in group_names)
|
||||
- name: Create LDAP user keystone-account home directory on the subcloud
|
||||
expect:
|
||||
command: ssh {{ ssh_internal_args }} {{ in_user_id }}@localhost
|
||||
responses:
|
||||
s password: "{{ in_user_password }}"
|
||||
"\\~\\$": exit
|
||||
# do not show passwords in the logs
|
||||
no_log: true
|
||||
|
||||
- name: Complete keystone user creation on the subcloud
|
||||
block:
|
||||
- name: Wait for keystone user to propagate to all subclouds
|
||||
shell: source /etc/platform/openrc; openstack user show {{ in_user_id }}
|
||||
register: user_output
|
||||
until: user_output.rc == 0
|
||||
retries: 12
|
||||
delay: 10
|
||||
when: ('systemcontroller' not in group_names)
|
||||
|
||||
- name: Create LDAP user keystone-account home directory on the subcloud
|
||||
expect:
|
||||
command: ssh {{ ssh_internal_args }} {{ in_user_id }}@localhost
|
||||
responses:
|
||||
s password: "{{ in_user_password }}"
|
||||
"\\~\\$": exit
|
||||
# do not show passwords in the logs
|
||||
no_log: true
|
||||
- name: Retrieve region name
|
||||
shell: source /etc/platform/openrc; system show | grep region_name | awk '{ print $4 }'
|
||||
register: region_name
|
||||
|
||||
when: ('systemcontroller' not in group_names)
|
||||
- name: Retrieve management network floating IP
|
||||
shell: >-
|
||||
source /etc/platform/openrc; system addrpool-list --nowrap |
|
||||
awk -F \| '$3 ~ / management / { gsub(/ /,"",$8); print $8 }'
|
||||
register: management_floating_ip
|
||||
|
||||
- name: Retrieve region name
|
||||
shell: source /etc/platform/openrc; system show | grep region_name | awk '{ print $4 }'
|
||||
register: region_name
|
||||
- name: Generate keystone user credentials file
|
||||
template:
|
||||
src: openrc-template.j2
|
||||
dest: /home/{{ in_user_id }}/{{ in_user_id }}-openrc
|
||||
owner: "{{ in_user_id }}"
|
||||
group: users
|
||||
mode: 0600
|
||||
become: yes
|
||||
|
||||
- name: Retrieve management network floating IP
|
||||
shell: >-
|
||||
source /etc/platform/openrc; system addrpool-list --nowrap |
|
||||
awk -F \| '$3 ~ / management / { gsub(/ /,"",$8); print $8 }'
|
||||
register: management_floating_ip
|
||||
- name: Add LDAP user to 'root' group
|
||||
command: usermod -a -G root {{ in_user_id }}
|
||||
become: yes
|
||||
when: in_sudo_permission
|
||||
|
||||
- name: Generate keystone user credentials file
|
||||
template:
|
||||
src: openrc-template.j2
|
||||
dest: /home/{{ in_user_id }}/{{ in_user_id }}-openrc
|
||||
owner: "{{ in_user_id }}"
|
||||
group: users
|
||||
mode: 0600
|
||||
become: yes
|
||||
- name: Retrieve LDAP user groups
|
||||
command: groups {{ in_user_id }}
|
||||
register: user_groups
|
||||
|
||||
- name: Add LDAP user to 'root' group
|
||||
command: usermod -a -G root {{ in_user_id }}
|
||||
become: yes
|
||||
when: in_sudo_permission
|
||||
- name: Set array of user groups to check
|
||||
set_fact:
|
||||
user_group_array: ['users', 'sys_protected']
|
||||
|
||||
- name: Retrieve LDAP user groups
|
||||
command: groups {{ in_user_id }}
|
||||
register: user_groups
|
||||
- name: Update array of user groups to include root group if sudo permission is granted
|
||||
set_fact:
|
||||
user_group_array: "{{ user_group_array }} + ['root']"
|
||||
when: in_sudo_permission
|
||||
|
||||
- name: Set array of user groups to check
|
||||
set_fact:
|
||||
user_group_array: ['users', 'sys_protected']
|
||||
|
||||
- name: Update array of user groups to include root group if sudo permission is granted
|
||||
set_fact:
|
||||
user_group_array: "{{ user_group_array }} + ['root']"
|
||||
when: in_sudo_permission
|
||||
|
||||
- name: Verify LDAP user groups
|
||||
fail:
|
||||
msg: "{{ in_user_id }} is not part of group {{ item }}"
|
||||
when: item not in user_groups.stdout
|
||||
loop: "{{ user_group_array }}"
|
||||
|
||||
always:
|
||||
- name: Disable AllowTcpForwarding setting in ssh config
|
||||
lineinfile:
|
||||
regexp: ^[ \t]*AllowTcpForwarding([ \t]+.*)$
|
||||
line: AllowTcpForwarding no
|
||||
dest: /etc/ssh/sshd_config
|
||||
validate: sshd -t -f %s
|
||||
notify:
|
||||
- reload sshd
|
||||
when: ('systemcontroller' in group_names)
|
||||
become: yes
|
||||
- name: Verify LDAP user groups
|
||||
fail:
|
||||
msg: "{{ in_user_id }} is not part of group {{ item }}"
|
||||
when: item not in user_groups.stdout
|
||||
loop: "{{ user_group_array }}"
|
||||
|
@ -0,0 +1,33 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Tasks to check LDAP user existence, to delete LDAP account. If the system is
|
||||
# distributed cloud, it dynamically adds subclouds to the target host list.
|
||||
|
||||
- name: Check if LDAP user exists
|
||||
command: ldapsearch -x -LLL uid={{ in_user_id }}
|
||||
register: in_user_id_check
|
||||
become: yes
|
||||
|
||||
- name: Delete LDAP user {{ in_user_id }} only if it exists
|
||||
command: ldapdeleteuser {{ in_user_id }}
|
||||
become: yes
|
||||
when: in_user_id_check.stdout | length != 0
|
||||
|
||||
- name: Get distributed role
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/get-distributed-role
|
||||
|
||||
- name: Get online subclouds
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/get-online-subclouds
|
||||
|
||||
- name: Populate inventory with subclouds
|
||||
include_role:
|
||||
name: manage-local-ldap-account/common/add-hosts
|
||||
vars:
|
||||
in_item: "{{ item }}"
|
||||
loop: "{{ subcloud_list }}"
|
||||
when: is_dc | bool
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Tasks to delete both keystone and LDAP user account inside the system
|
||||
# controller, and subclouds as well for distributed systems.
|
||||
|
||||
- name: Delete keystone user on System Controller
|
||||
block:
|
||||
- name: Delete the keystone user {{ in_user_id }}
|
||||
shell: >-
|
||||
source /etc/platform/openrc; openstack {{ os_param_region_name }} user delete {{ in_user_id }}
|
||||
|
||||
when: ('systemcontroller' in group_names)
|
||||
|
||||
- name: Wait for keystone user to be deleted in all subclouds
|
||||
shell: source /etc/platform/openrc; ! openstack user show {{ in_user_id }}
|
||||
register: user_output
|
||||
until: user_output.rc == 0
|
||||
retries: 12
|
||||
delay: 10
|
||||
when: ('systemcontroller' not in group_names)
|
Loading…
Reference in New Issue
Block a user