diff --git a/roles/os_projects/defaults/main.yml b/roles/os_projects/defaults/main.yml index 59a6a2b..c27a6ac 100644 --- a/roles/os_projects/defaults/main.yml +++ b/roles/os_projects/defaults/main.yml @@ -17,6 +17,28 @@ os_projects_environment: # - 'name': The name of the domain. # - 'description': Optional description for the domain. os_projects_domains: [] +# List of OpenStack groups to create. +# Each item should be a dict containing the following items: +# - 'name': The name of the group. +# - 'domain': The domain to contain the new group. +# - 'description': Optional description for the group. +# - 'create_group': Optional Bookean (Default: true) to indicate whether to +# create the group. This can be useful if the group already exists. +# (e.g. LDAP defined groups) +# - 'users': Optional list of users to add to the group. Each user should be a +# dict containing following items: +# - 'name': The name of the user. +os_projects_groups: [] +# List of OpenStack users to create. +# Each item should be a dict containing the following items: +# - 'name': The name of the user. +# - 'password': The user's password. +# - 'domain': The domain in which to register users. +# - 'openrc_file': Optional path to an environment file to create. +# - 'create_user': Optional boolean (Default: true) to indicate whether to +# create the user. This can be useful if the user already exists. +# (e.g. LDAP defined users) +os_projects_users: [] # List of OpenStack projects to create. # Each item should be a dict containing the following items: # - 'name': The name of the project. @@ -26,11 +48,14 @@ os_projects_domains: [] # - 'users': Optional list of users to register. Each user should be a dict # containing the following items: # - 'name': The name of the user. -# - 'password': The user's password. # - 'roles': Optional list of roles to assign to the user in the project. # - 'domain_roles': Optional list of roles to assign to the user in the user # domain. -# - 'openrc_file': Optional path to an environment file to create. +# - 'groups': Optional list of groups to register. Each group should be a dict +# containing the following items: +# - 'name': The name of the group. +# - 'domain': The domain to contain the new group. +# - 'roles': Optional list of roles to assign to the group in the project. # - 'keypairs': Optional list of SSH key pairs to register with Nova. Each key # pair should be a dict containing the following items: # - 'name': The name of the keypair. diff --git a/roles/os_projects/tasks/groups.yml b/roles/os_projects/tasks/groups.yml new file mode 100644 index 0000000..0557109 --- /dev/null +++ b/roles/os_projects/tasks/groups.yml @@ -0,0 +1,37 @@ +--- +- name: Ensure the groups exist + openstack.cloud.identity_group: + auth_type: "{{ os_projects_auth_type }}" + auth: "{{ os_projects_admin_auth }}" + region_name: "{{ os_projects_region | default(omit) }}" + cacert: "{{ os_projects_cacert | default(omit) }}" + cloud: "{{ os_projects_cloud | default(omit) }}" + interface: "{{ os_projects_interface | default(omit, true) }}" + name: "{{ group.name }}" + description: "{{ group.description }}" + domain_id: "{{ group_domain_id }}" + state: present + wait: true + when: group.create_group | default(true) | bool + environment: "{{ os_projects_environment }}" + vars: + group_domain_id: "{{ (group.domain in os_projects_domain_to_id.values()) | ternary(group.domain, os_projects_domain_to_id[group.domain]) }}" + loop_control: + label: "{{ group.name }}" + +- name: Ensure users are added to the group + openstack.cloud.group_assignment: + auth_type: "{{ os_projects_auth_type }}" + auth: "{{ os_projects_admin_auth }}" + region_name: "{{ os_projects_region | default(omit) }}" + cacert: "{{ os_projects_cacert | default(omit) }}" + cloud: "{{ os_projects_cloud | default(omit) }}" + interface: "{{ os_projects_interface | default(omit, true) }}" + user: "{{ item.name }}" + group: "{{ group.name }}" + state: present + wait: true + with_items: "{{ group.users }}" + environment: "{{ os_projects_environment }}" + loop_control: + label: "{{ group.name }}: {{ item.name }}" diff --git a/roles/os_projects/tasks/projects.yml b/roles/os_projects/tasks/projects.yml index 54c6fa4..9c38698 100644 --- a/roles/os_projects/tasks/projects.yml +++ b/roles/os_projects/tasks/projects.yml @@ -139,8 +139,20 @@ - name: Include users.yml ansible.builtin.include_tasks: users.yml + with_items: "{{ os_projects_users }}" + loop_control: + loop_var: user + +- name: Include groups.yml + ansible.builtin.include_tasks: groups.yml + with_items: "{{ os_projects_groups }}" + loop_control: + loop_var: group + +- name: Include role_assignment.yml + ansible.builtin.include_tasks: role_assignment.yml with_items: "{{ os_projects }}" - when: project.users is defined + when: project.users is defined or project.groups is defined loop_control: loop_var: project diff --git a/roles/os_projects/tasks/role_assignment.yml b/roles/os_projects/tasks/role_assignment.yml new file mode 100644 index 0000000..ec9b532 --- /dev/null +++ b/roles/os_projects/tasks/role_assignment.yml @@ -0,0 +1,65 @@ +--- +- name: Ensure users have required project roles + openstack.cloud.role_assignment: + auth_type: "{{ os_projects_auth_type }}" + auth: "{{ os_projects_admin_auth }}" + region_name: "{{ os_projects_region | default(omit) }}" + cacert: "{{ os_projects_cacert | default(omit) }}" + cloud: "{{ os_projects_cloud | default(omit) }}" + interface: "{{ os_projects_interface | default(omit, true) }}" + user: "{{ item.0.name }}" + project: "{{ project.name }}" + role: "{{ item.1 }}" + user_domain: "{{ project.user_domain | default(omit, true) }}" + project_domain: "{{ project.project_domain | default(omit, true) }}" + state: present + with_subelements: + - "{{ project.users }}" + - roles + - skip_missing: true + environment: "{{ os_projects_environment }}" + loop_control: + label: "{{ project.name }}: {{ item.0.name }}: {{ item.1 }}" + +- name: Ensure users have required domain roles + openstack.cloud.role_assignment: + auth_type: "{{ os_projects_auth_type }}" + auth: "{{ os_projects_admin_auth }}" + region_name: "{{ os_projects_region | default(omit) }}" + cacert: "{{ os_projects_cacert | default(omit) }}" + cloud: "{{ os_projects_cloud | default(omit) }}" + interface: "{{ os_projects_interface | default(omit, true) }}" + user: "{{ item.0.name }}" + domain: "{{ domain_is_id | ternary(project.user_domain, os_projects_domain_to_id[project.user_domain]) }}" + role: "{{ item.1 }}" + state: present + with_subelements: + - "{{ project.users }}" + - domain_roles + - skip_missing: true + environment: "{{ os_projects_environment }}" + vars: + domain_is_id: "{{ project.user_domain in os_projects_domain_to_id.values() }}" + loop_control: + label: "{{ project.user_domain }}: {{ item.0.name }}: {{ item.1 }}" + +- name: Ensure groups have required project roles + openstack.cloud.role_assignment: + auth_type: "{{ os_projects_auth_type }}" + auth: "{{ os_projects_admin_auth }}" + region_name: "{{ os_projects_region | default(omit) }}" + cacert: "{{ os_projects_cacert | default(omit) }}" + cloud: "{{ os_projects_cloud | default(omit) }}" + interface: "{{ os_projects_interface | default(omit, true) }}" + group: "{{ item.0.name }}" + project: "{{ project.name }}" + role: "{{ item.1 }}" + project_domain: "{{ project.project_domain | default(omit, true) }}" + state: present + with_subelements: + - "{{ project.groups }}" + - roles + - skip_missing: true + environment: "{{ os_projects_environment }}" + loop_control: + label: "{{ project.name }}: {{ item.0.name }}: {{ item.1 }}" diff --git a/roles/os_projects/tasks/users.yml b/roles/os_projects/tasks/users.yml index ecb219d..2056d00 100644 --- a/roles/os_projects/tasks/users.yml +++ b/roles/os_projects/tasks/users.yml @@ -1,5 +1,5 @@ --- -- name: Ensure project users exist +- name: Ensure users exist openstack.cloud.identity_user: auth_type: "{{ os_projects_auth_type }}" auth: "{{ os_projects_admin_auth }}" @@ -7,67 +7,17 @@ cacert: "{{ os_projects_cacert | default(omit) }}" cloud: "{{ os_projects_cloud | default(omit) }}" interface: "{{ os_projects_interface | default(omit, true) }}" - name: "{{ item.name }}" - description: "{{ item.description | default(omit) }}" - email: "{{ item.email | default(omit) }}" - password: "{{ item.password | default(omit) }}" - # NOTE(bbezak): identity_user looks up default_project in the user domain - # ('domain'). Omit default_project for cross-domain users to avoid false - # "No Project found" errors. - default_project: "{{ (user_domain_id == project_domain_id) | ternary(project.name, omit) }}" + name: "{{ user.name }}" + description: "{{ user.description | default(omit) }}" + email: "{{ user.email | default(omit) }}" + password: "{{ user.password | default(omit) }}" domain: "{{ user_domain_id }}" state: present enabled: true wait: true - with_items: "{{ project.users }}" - when: item.create_user | default(true) | bool + when: user.create_user | default(true) | bool environment: "{{ os_projects_environment }}" vars: - user_domain_id: "{{ (project.user_domain in os_projects_domain_to_id.values()) | ternary(project.user_domain, os_projects_domain_to_id[project.user_domain]) }}" - project_domain_id: "{{ (project.project_domain in os_projects_domain_to_id.values()) | ternary(project.project_domain, os_projects_domain_to_id[project.project_domain]) }}" + user_domain_id: "{{ (user.domain in os_projects_domain_to_id.values()) | ternary(user.domain, os_projects_domain_to_id[user.domain]) }}" loop_control: - label: "{{ project.name }}: {{ item.name }}" - -- name: Ensure users have required project roles - openstack.cloud.role_assignment: - auth_type: "{{ os_projects_auth_type }}" - auth: "{{ os_projects_admin_auth }}" - region_name: "{{ os_projects_region | default(omit) }}" - cacert: "{{ os_projects_cacert | default(omit) }}" - cloud: "{{ os_projects_cloud | default(omit) }}" - interface: "{{ os_projects_interface | default(omit, true) }}" - user: "{{ item.0.name }}" - project: "{{ project.name }}" - role: "{{ item.1 }}" - user_domain: "{{ project.user_domain | default(omit, true) }}" - project_domain: "{{ project.project_domain | default(omit, true) }}" - state: present - with_subelements: - - "{{ project.users }}" - - roles - - skip_missing: true - environment: "{{ os_projects_environment }}" - loop_control: - label: "{{ project.name }}: {{ item.0.name }}: {{ item.1 }}" - -- name: Ensure users have required domain roles - openstack.cloud.role_assignment: - auth_type: "{{ os_projects_auth_type }}" - auth: "{{ os_projects_admin_auth }}" - region_name: "{{ os_projects_region | default(omit) }}" - cacert: "{{ os_projects_cacert | default(omit) }}" - cloud: "{{ os_projects_cloud | default(omit) }}" - interface: "{{ os_projects_interface | default(omit, true) }}" - user: "{{ item.0.name }}" - domain: "{{ domain_is_id | ternary(project.user_domain, os_projects_domain_to_id[project.user_domain]) }}" - role: "{{ item.1 }}" - state: present - with_subelements: - - "{{ project.users }}" - - domain_roles - - skip_missing: true - environment: "{{ os_projects_environment }}" - vars: - domain_is_id: "{{ project.user_domain in os_projects_domain_to_id.values() }}" - loop_control: - label: "{{ project.user_domain }}: {{ item.0.name }}: {{ item.1 }}" + label: "{{ user.name }}"