From 65d29aa8319d52c7458af8a58932bd9f5066205d Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Wed, 15 Apr 2026 16:39:12 -0500 Subject: [PATCH 1/3] feat(keystone): add ability to define role permissions to projects Currently we can assign role permissions to domains but not to projects. This expands the allowable configuration to projects. It also sets defaults in case someone has not defined roles or projects so that the ansible does not fail. --- .../keystone_bootstrap/defaults/main.yml | 9 ++++++ .../keystone_bootstrap/tasks/sso_groups.yml | 10 ++++++- .../tasks/sso_project_role.yml | 28 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 ansible/roles/keystone_bootstrap/tasks/sso_project_role.yml diff --git a/ansible/roles/keystone_bootstrap/defaults/main.yml b/ansible/roles/keystone_bootstrap/defaults/main.yml index 705d1050f..4b68e7e3e 100644 --- a/ansible/roles/keystone_bootstrap/defaults/main.yml +++ b/ansible/roles/keystone_bootstrap/defaults/main.yml @@ -11,6 +11,9 @@ keystone_bootstrap_project_domains: description: Sandbox Projects # these groups live inside the sso domain +# Each group can have both domain_roles and project_roles: +# - domain_roles: grants permissions at domain level (can use inherited flag) +# - project_roles: grants permissions at project level (no inherited flag needed) keystone_bootstrap_groups: - name: ucadmin desc: 'Users Federated with Admin' @@ -59,3 +62,9 @@ keystone_bootstrap_groups: - domain: infra role: member inherited: true + # Example of project-level role assignments (optional) + # project_roles: + # - project: baremetal + # role: member + # - project: shared-services + # role: reader diff --git a/ansible/roles/keystone_bootstrap/tasks/sso_groups.yml b/ansible/roles/keystone_bootstrap/tasks/sso_groups.yml index a87081b9e..e0fb830f9 100644 --- a/ansible/roles/keystone_bootstrap/tasks/sso_groups.yml +++ b/ansible/roles/keystone_bootstrap/tasks/sso_groups.yml @@ -25,7 +25,15 @@ # so need to do this manually done - name: Assign role to group for domain ansible.builtin.include_tasks: sso_domain_role.yml - loop: "{{ group_item.domain_roles }}" + loop: "{{ group_item.domain_roles | default([]) }}" + loop_control: + loop_var: role_item + vars: + group_id: "{{ _group.group.id }}" + +- name: Assign role to group for project + ansible.builtin.include_tasks: sso_project_role.yml + loop: "{{ group_item.project_roles | default([]) }}" loop_control: loop_var: role_item vars: diff --git a/ansible/roles/keystone_bootstrap/tasks/sso_project_role.yml b/ansible/roles/keystone_bootstrap/tasks/sso_project_role.yml new file mode 100644 index 000000000..294881d2b --- /dev/null +++ b/ansible/roles/keystone_bootstrap/tasks/sso_project_role.yml @@ -0,0 +1,28 @@ +--- +# Copyright (c) 2026 Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +- name: Create the role if it does not exist + openstack.cloud.identity_role: + name: "{{ role_item.role }}" + state: present + +- name: Assign role to group for project + openstack.cloud.role_assignment: + group: "{{ group_id }}" + project: "{{ role_item.project }}" + role: "{{ role_item.role }}" + state: present + when: dont_set_roles is not defined From 700b9640a986821dc0693cc6cce5d2a9d310ca84 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Thu, 16 Apr 2026 08:38:47 -0500 Subject: [PATCH 2/3] chore: add additional permission groups for jobs and secrets to Nautobot Added a permission group called 'job-execution' which allows jobs to be executed. Add a permission group to let us view secrets configurations and git repositories. --- .../nautobot_permissions/defaults/main.yml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ansible/roles/nautobot_permissions/defaults/main.yml b/ansible/roles/nautobot_permissions/defaults/main.yml index a0cd958c6..4e854615e 100644 --- a/ansible/roles/nautobot_permissions/defaults/main.yml +++ b/ansible/roles/nautobot_permissions/defaults/main.yml @@ -10,6 +10,10 @@ nautobot_permissions_groups: user-api-tokens: - ucadmin - ucuser + job-execution: + - ucadmin + sys-admin: + - ucadmin # definition of a permission and the various settings on that permission nautobot_permissions_permissions: @@ -93,3 +97,22 @@ nautobot_permissions_permissions: - users.token constraints: - user: "$user" + job-execution: + description: Execute diagnostic and maintenance jobs for hardware troubleshooting + enabled: true + actions: + - run + object_types: + - extras.job + sys-admin: + description: System administration read access for git repositories and secrets + enabled: true + actions: + - view + object_types: + # Git repository management - view source control integrations + - extras.gitrepository + # Secrets management - view system secrets and credentials + - extras.secret + - extras.secretsgroup + - extras.secretsgroupassociation From 89e960a36b7c9bc36539fa86078d479e57e13240 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Thu, 16 Apr 2026 09:18:24 -0500 Subject: [PATCH 3/3] feat: make it possible to create more domains and projects in domains Make it possible to configure more projects in the infra domain by variablizing the projects. Further make it possible to create additional domains as well. --- ansible/keystone-post-deploy.yaml | 1 + .../roles/keystone_bootstrap/tasks/main.yml | 3 -- .../defaults/main.yml | 15 ++++++++++ .../keystone_domains_projects/tasks/main.yml | 28 +++++++++++++++++++ .../tasks/projects.yml} | 17 ++++------- 5 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 ansible/roles/keystone_domains_projects/defaults/main.yml create mode 100644 ansible/roles/keystone_domains_projects/tasks/main.yml rename ansible/roles/{keystone_bootstrap/tasks/baremetal.yml => keystone_domains_projects/tasks/projects.yml} (66%) diff --git a/ansible/keystone-post-deploy.yaml b/ansible/keystone-post-deploy.yaml index a8a249b25..7116a1cd8 100644 --- a/ansible/keystone-post-deploy.yaml +++ b/ansible/keystone-post-deploy.yaml @@ -22,4 +22,5 @@ ansible.builtin.import_tasks: tasks/check_openstack_auth.yml roles: + - role: keystone_domains_projects - role: keystone_bootstrap diff --git a/ansible/roles/keystone_bootstrap/tasks/main.yml b/ansible/roles/keystone_bootstrap/tasks/main.yml index 661e67532..82c1caf8f 100644 --- a/ansible/roles/keystone_bootstrap/tasks/main.yml +++ b/ansible/roles/keystone_bootstrap/tasks/main.yml @@ -7,9 +7,6 @@ role: admin state: present -- name: Define baremetal - ansible.builtin.include_tasks: baremetal.yml - - name: Define SSO ansible.builtin.include_tasks: sso.yml diff --git a/ansible/roles/keystone_domains_projects/defaults/main.yml b/ansible/roles/keystone_domains_projects/defaults/main.yml new file mode 100644 index 000000000..8112ef39d --- /dev/null +++ b/ansible/roles/keystone_domains_projects/defaults/main.yml @@ -0,0 +1,15 @@ +--- +# Default variables for keystone_domains_projects role +# This role creates domains and projects inside of them + +# Define the domains and their projects +# Note: projects key is optional - domains can be created without projects +keystone_domains_projects_list: + - domain_name: infra + description: 'System Infra' + projects: + - project_name: baremetal + description: 'Ironic resources' + # Example of domain without projects: + # - domain_name: example + # description: 'Example domain with no projects' diff --git a/ansible/roles/keystone_domains_projects/tasks/main.yml b/ansible/roles/keystone_domains_projects/tasks/main.yml new file mode 100644 index 000000000..00f92386f --- /dev/null +++ b/ansible/roles/keystone_domains_projects/tasks/main.yml @@ -0,0 +1,28 @@ +--- +# Copyright (c) 2026 Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: "Create domain {{ item.domain_name }}" + openstack.cloud.identity_domain: + name: "{{ item.domain_name }}" + description: "{{ item.description }}" + state: present + loop: "{{ keystone_domains_projects_list }}" + +- name: "Create projects for domain {{ item.domain_name }}" + ansible.builtin.include_tasks: projects.yml + vars: + domain: "{{ item }}" + loop: "{{ keystone_domains_projects_list }}" + when: item.projects is defined and item.projects | length > 0 diff --git a/ansible/roles/keystone_bootstrap/tasks/baremetal.yml b/ansible/roles/keystone_domains_projects/tasks/projects.yml similarity index 66% rename from ansible/roles/keystone_bootstrap/tasks/baremetal.yml rename to ansible/roles/keystone_domains_projects/tasks/projects.yml index 1112e8542..cdf2a0944 100644 --- a/ansible/roles/keystone_bootstrap/tasks/baremetal.yml +++ b/ansible/roles/keystone_domains_projects/tasks/projects.yml @@ -1,5 +1,5 @@ --- -# Copyright (c) 2025 Rackspace Technology, Inc. +# Copyright (c) 2026 Rackspace Technology, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -13,15 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -- name: Create 'infra' domain - openstack.cloud.identity_domain: - name: infra - description: 'System Infra' - state: present - -- name: Create 'baremetal' project in 'infra' domain +- name: "Create project {{ item.project_name }}" openstack.cloud.project: - name: baremetal - domain: infra - description: 'Ironic Resources' + name: "{{ item.project_name }}" + domain: "{{ domain.domain_name }}" + description: "{{ item.description }}" state: present + loop: "{{ domain.projects }}"