From a71071dfcc3d86ed480126d7db3e5ee1f8b49e16 Mon Sep 17 00:00:00 2001 From: June Date: Sat, 15 Feb 2025 04:20:29 +0100 Subject: [PATCH 1/2] add option to NetBox role for patch. NetBox for OIDC group and role map. Add option to NetBox role to make it patch NetBox to add custom pipeline code for OIDC group and role mapping. The custom pipeline code is licensed under the Creative Commons: CC BY-SA 4.0 license. See: https://github.com/goauthentik/authentik/blob/main/LICENSE https://github.com/goauthentik/authentik/blob/main/website/integrations/services/netbox/index.md https://docs.goauthentik.io/integrations/services/netbox/ https://git.hamburg.ccc.de/CCCHH/nix-infra/commit/5676b1a4680dbe706686f38902f5607ec33330ff --- README.md | 3 +- roles/netbox/README.md | 12 +++- roles/netbox/defaults/main.yaml | 1 + ...oup_and_role_mapping_custom_pipeline.patch | 61 +++++++++++++++++++ roles/netbox/meta/argument_specs.yaml | 4 ++ roles/netbox/tasks/main.yaml | 8 +++ 6 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 roles/netbox/defaults/main.yaml create mode 100644 roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch diff --git a/README.md b/README.md index ab14d1d..f16438c 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,5 @@ Im Ansible-Repo müssen diese Sachen hinzugefügt werden: ## License -This CCCHH ansible-ccchh repository is licensed under the [MIT License](./LICENSE). +This CCCHH ansible-ccchh repository is licensed under the [MIT License](./LICENSE). +[`0001_oidc_group_and_role_mapping_custom_pipeline.patch`](./roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch) is licensed under the Creative Commons: CC BY-SA 4.0 license. diff --git a/roles/netbox/README.md b/roles/netbox/README.md index 38b7968..a83cffe 100644 --- a/roles/netbox/README.md +++ b/roles/netbox/README.md @@ -18,7 +18,9 @@ Should work on Debian-based distributions. ## Optional Arguments -None. +- `netbox__patch_oidc_group_and_role_mapping_custom_pipeline`: Whether or not to patch NetBox to add custom pipeline code for OIDC group and role mapping. + See [Custom Pipeline Code for OIDC Group and Role Mapping](#custom-pipeline-code-for-oidc-group-and-role-mapping) for more infos. + Defaults to `false`. ## NetBox Configuration @@ -71,6 +73,14 @@ The relevant documentation on how to do that can be found here: - Web server setup docs: - Example base nginx config: +## Custom Pipeline Code for OIDC Group and Role Mapping + +Setting the option `netbox__patch_oidc_group_and_role_mapping_custom_pipeline` to `true` makes this role patch NetBox to add custom pipeline code for OIDC group and role mapping. +Note that this role uses a patch for NetBox >= 4.0.0. +The patch is available in `files/0001_oidc_group_and_role_mapping_custom_pipeline.patch`, licensed under the CC BY-SA 4.0 license and taken from [this authentik NetBox documentation](https://docs.goauthentik.io/integrations/services/netbox/). +The documentation also shows how to use the pipeline code by defining a custom `SOCIAL_AUTH_PIPELINE`, which you also need to do, as the configuration isn't provided by this role. +See also [the default settings.py](https://github.com/netbox-community/netbox/blob/main/netbox/netbox/settings.py) for the default `SOCIAL_AUTH_PIPELINE`. + ## Links & Resources - The NetBox Git Repo: diff --git a/roles/netbox/defaults/main.yaml b/roles/netbox/defaults/main.yaml new file mode 100644 index 0000000..5dcbbee --- /dev/null +++ b/roles/netbox/defaults/main.yaml @@ -0,0 +1 @@ +netbox__patch_oidc_group_and_role_mapping_custom_pipeline: false diff --git a/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch b/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch new file mode 100644 index 0000000..89f805a --- /dev/null +++ b/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch @@ -0,0 +1,61 @@ +diff --git a/netbox/netbox/custom_pipeline.py b/netbox/netbox/custom_pipeline.py +new file mode 100644 +index 000000000..470f388dc +--- /dev/null ++++ b/netbox/netbox/custom_pipeline.py +@@ -0,0 +1,55 @@ ++# Licensed under Creative Commons: CC BY-SA 4.0 license. ++# https://github.com/goauthentik/authentik/blob/main/LICENSE ++# https://github.com/goauthentik/authentik/blob/main/website/integrations/services/netbox/index.md ++# https://docs.goauthentik.io/integrations/services/netbox/ ++from netbox.authentication import Group ++ ++class AuthFailed(Exception): ++ pass ++ ++def add_groups(response, user, backend, *args, **kwargs): ++ try: ++ groups = response['groups'] ++ except KeyError: ++ pass ++ ++ # Add all groups from oAuth token ++ for group in groups: ++ group, created = Group.objects.get_or_create(name=group) ++ user.groups.add(group) ++ ++def remove_groups(response, user, backend, *args, **kwargs): ++ try: ++ groups = response['groups'] ++ except KeyError: ++ # Remove all groups if no groups in oAuth token ++ user.groups.clear() ++ pass ++ ++ # Get all groups of user ++ user_groups = [item.name for item in user.groups.all()] ++ # Get groups of user which are not part of oAuth token ++ delete_groups = list(set(user_groups) - set(groups)) ++ ++ # Delete non oAuth token groups ++ for delete_group in delete_groups: ++ group = Group.objects.get(name=delete_group) ++ user.groups.remove(group) ++ ++ ++def set_roles(response, user, backend, *args, **kwargs): ++ # Remove Roles temporary ++ user.is_superuser = False ++ user.is_staff = False ++ try: ++ groups = response['groups'] ++ except KeyError: ++ # When no groups are set ++ # save the user without Roles ++ user.save() ++ pass ++ ++ # Set roles is role (superuser or staff) is in groups ++ user.is_superuser = True if 'superusers' in groups else False ++ user.is_staff = True if 'staff' in groups else False ++ user.save() diff --git a/roles/netbox/meta/argument_specs.yaml b/roles/netbox/meta/argument_specs.yaml index f836b43..c0368ef 100644 --- a/roles/netbox/meta/argument_specs.yaml +++ b/roles/netbox/meta/argument_specs.yaml @@ -10,3 +10,7 @@ argument_specs: netbox__config: type: str required: true + netbox__patch_oidc_group_and_role_mapping_custom_pipeline: + type: bool + required: false + default: false diff --git a/roles/netbox/tasks/main.yaml b/roles/netbox/tasks/main.yaml index 89bf4a6..0d2cdce 100644 --- a/roles/netbox/tasks/main.yaml +++ b/roles/netbox/tasks/main.yaml @@ -25,6 +25,14 @@ - Run upgrade script - Ensure netbox systemd services are set up and up-to-date +- name: Ensure patch for adding custom pipeline code for OIDC group and role mapping is applied + ansible.posix.patch: + src: 0001_oidc_group_and_role_mapping_custom_pipeline.patch + basedir: /opt/netbox/ + when: netbox__patch_oidc_group_and_role_mapping_custom_pipeline + notify: + - Ensure netbox systemd services are set up and up-to-date + - name: Ensure netbox user block: - name: Ensure netbox group exists From c0ae5dcdcdd5179d8ad3a841f801d7d88d8f8c11 Mon Sep 17 00:00:00 2001 From: June Date: Sat, 15 Feb 2025 04:44:30 +0100 Subject: [PATCH 2/2] move to copy --- README.md | 2 +- roles/netbox/README.md | 8 +-- roles/netbox/defaults/main.yaml | 2 +- ...oup_and_role_mapping_custom_pipeline.patch | 61 ------------------- ...om_pipeline_oidc_group_and_role_mapping.py | 55 +++++++++++++++++ roles/netbox/meta/argument_specs.yaml | 2 +- roles/netbox/tasks/main.yaml | 23 +++++-- 7 files changed, 80 insertions(+), 73 deletions(-) delete mode 100644 roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch create mode 100644 roles/netbox/files/custom_pipeline_oidc_group_and_role_mapping.py diff --git a/README.md b/README.md index f16438c..6906a7f 100644 --- a/README.md +++ b/README.md @@ -49,4 +49,4 @@ Im Ansible-Repo müssen diese Sachen hinzugefügt werden: ## License This CCCHH ansible-ccchh repository is licensed under the [MIT License](./LICENSE). -[`0001_oidc_group_and_role_mapping_custom_pipeline.patch`](./roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch) is licensed under the Creative Commons: CC BY-SA 4.0 license. +[`custom_pipeline_oidc_group_and_role_mapping.py`](./roles/netbox/files/custom_pipeline_oidc_group_and_role_mapping.py) is licensed under the Creative Commons: CC BY-SA 4.0 license. diff --git a/roles/netbox/README.md b/roles/netbox/README.md index a83cffe..3e5a584 100644 --- a/roles/netbox/README.md +++ b/roles/netbox/README.md @@ -18,7 +18,7 @@ Should work on Debian-based distributions. ## Optional Arguments -- `netbox__patch_oidc_group_and_role_mapping_custom_pipeline`: Whether or not to patch NetBox to add custom pipeline code for OIDC group and role mapping. +- `netbox__custom_pipeline_oidc_group_and_role_mapping`: Whether or not to have custom pipeline code for OIDC group and role mapping present. See [Custom Pipeline Code for OIDC Group and Role Mapping](#custom-pipeline-code-for-oidc-group-and-role-mapping) for more infos. Defaults to `false`. @@ -75,9 +75,9 @@ The relevant documentation on how to do that can be found here: ## Custom Pipeline Code for OIDC Group and Role Mapping -Setting the option `netbox__patch_oidc_group_and_role_mapping_custom_pipeline` to `true` makes this role patch NetBox to add custom pipeline code for OIDC group and role mapping. -Note that this role uses a patch for NetBox >= 4.0.0. -The patch is available in `files/0001_oidc_group_and_role_mapping_custom_pipeline.patch`, licensed under the CC BY-SA 4.0 license and taken from [this authentik NetBox documentation](https://docs.goauthentik.io/integrations/services/netbox/). +Setting the option `netbox__custom_pipeline_oidc_group_and_role_mapping` to `true` makes this role ensure custom pipeline code for OIDC group and role mapping is present. +Note that this role uses code for NetBox >= 4.0.0. +The code is available in `files/custom_pipeline_oidc_group_and_role_mapping.py`, licensed under the CC BY-SA 4.0 license and taken from [this authentik NetBox documentation](https://docs.goauthentik.io/integrations/services/netbox/). The documentation also shows how to use the pipeline code by defining a custom `SOCIAL_AUTH_PIPELINE`, which you also need to do, as the configuration isn't provided by this role. See also [the default settings.py](https://github.com/netbox-community/netbox/blob/main/netbox/netbox/settings.py) for the default `SOCIAL_AUTH_PIPELINE`. diff --git a/roles/netbox/defaults/main.yaml b/roles/netbox/defaults/main.yaml index 5dcbbee..49b518e 100644 --- a/roles/netbox/defaults/main.yaml +++ b/roles/netbox/defaults/main.yaml @@ -1 +1 @@ -netbox__patch_oidc_group_and_role_mapping_custom_pipeline: false +netbox__custom_pipeline_oidc_group_and_role_mapping: false diff --git a/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch b/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch deleted file mode 100644 index 89f805a..0000000 --- a/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/netbox/netbox/custom_pipeline.py b/netbox/netbox/custom_pipeline.py -new file mode 100644 -index 000000000..470f388dc ---- /dev/null -+++ b/netbox/netbox/custom_pipeline.py -@@ -0,0 +1,55 @@ -+# Licensed under Creative Commons: CC BY-SA 4.0 license. -+# https://github.com/goauthentik/authentik/blob/main/LICENSE -+# https://github.com/goauthentik/authentik/blob/main/website/integrations/services/netbox/index.md -+# https://docs.goauthentik.io/integrations/services/netbox/ -+from netbox.authentication import Group -+ -+class AuthFailed(Exception): -+ pass -+ -+def add_groups(response, user, backend, *args, **kwargs): -+ try: -+ groups = response['groups'] -+ except KeyError: -+ pass -+ -+ # Add all groups from oAuth token -+ for group in groups: -+ group, created = Group.objects.get_or_create(name=group) -+ user.groups.add(group) -+ -+def remove_groups(response, user, backend, *args, **kwargs): -+ try: -+ groups = response['groups'] -+ except KeyError: -+ # Remove all groups if no groups in oAuth token -+ user.groups.clear() -+ pass -+ -+ # Get all groups of user -+ user_groups = [item.name for item in user.groups.all()] -+ # Get groups of user which are not part of oAuth token -+ delete_groups = list(set(user_groups) - set(groups)) -+ -+ # Delete non oAuth token groups -+ for delete_group in delete_groups: -+ group = Group.objects.get(name=delete_group) -+ user.groups.remove(group) -+ -+ -+def set_roles(response, user, backend, *args, **kwargs): -+ # Remove Roles temporary -+ user.is_superuser = False -+ user.is_staff = False -+ try: -+ groups = response['groups'] -+ except KeyError: -+ # When no groups are set -+ # save the user without Roles -+ user.save() -+ pass -+ -+ # Set roles is role (superuser or staff) is in groups -+ user.is_superuser = True if 'superusers' in groups else False -+ user.is_staff = True if 'staff' in groups else False -+ user.save() diff --git a/roles/netbox/files/custom_pipeline_oidc_group_and_role_mapping.py b/roles/netbox/files/custom_pipeline_oidc_group_and_role_mapping.py new file mode 100644 index 0000000..470f388 --- /dev/null +++ b/roles/netbox/files/custom_pipeline_oidc_group_and_role_mapping.py @@ -0,0 +1,55 @@ +# Licensed under Creative Commons: CC BY-SA 4.0 license. +# https://github.com/goauthentik/authentik/blob/main/LICENSE +# https://github.com/goauthentik/authentik/blob/main/website/integrations/services/netbox/index.md +# https://docs.goauthentik.io/integrations/services/netbox/ +from netbox.authentication import Group + +class AuthFailed(Exception): + pass + +def add_groups(response, user, backend, *args, **kwargs): + try: + groups = response['groups'] + except KeyError: + pass + + # Add all groups from oAuth token + for group in groups: + group, created = Group.objects.get_or_create(name=group) + user.groups.add(group) + +def remove_groups(response, user, backend, *args, **kwargs): + try: + groups = response['groups'] + except KeyError: + # Remove all groups if no groups in oAuth token + user.groups.clear() + pass + + # Get all groups of user + user_groups = [item.name for item in user.groups.all()] + # Get groups of user which are not part of oAuth token + delete_groups = list(set(user_groups) - set(groups)) + + # Delete non oAuth token groups + for delete_group in delete_groups: + group = Group.objects.get(name=delete_group) + user.groups.remove(group) + + +def set_roles(response, user, backend, *args, **kwargs): + # Remove Roles temporary + user.is_superuser = False + user.is_staff = False + try: + groups = response['groups'] + except KeyError: + # When no groups are set + # save the user without Roles + user.save() + pass + + # Set roles is role (superuser or staff) is in groups + user.is_superuser = True if 'superusers' in groups else False + user.is_staff = True if 'staff' in groups else False + user.save() diff --git a/roles/netbox/meta/argument_specs.yaml b/roles/netbox/meta/argument_specs.yaml index c0368ef..0506389 100644 --- a/roles/netbox/meta/argument_specs.yaml +++ b/roles/netbox/meta/argument_specs.yaml @@ -10,7 +10,7 @@ argument_specs: netbox__config: type: str required: true - netbox__patch_oidc_group_and_role_mapping_custom_pipeline: + netbox__custom_pipeline_oidc_group_and_role_mapping: type: bool required: false default: false diff --git a/roles/netbox/tasks/main.yaml b/roles/netbox/tasks/main.yaml index 0d2cdce..dffa746 100644 --- a/roles/netbox/tasks/main.yaml +++ b/roles/netbox/tasks/main.yaml @@ -25,11 +25,24 @@ - Run upgrade script - Ensure netbox systemd services are set up and up-to-date -- name: Ensure patch for adding custom pipeline code for OIDC group and role mapping is applied - ansible.posix.patch: - src: 0001_oidc_group_and_role_mapping_custom_pipeline.patch - basedir: /opt/netbox/ - when: netbox__patch_oidc_group_and_role_mapping_custom_pipeline +- name: Ensures custom pipeline code for OIDC group and role mapping is present + ansible.builtin.copy: + src: custom_pipeline_oidc_group_and_role_mapping.py + dest: /opt/netbox/netbox/netbox/custom_pipeline_oidc_mapping.py + mode: "0644" + owner: root + group: root + when: netbox__custom_pipeline_oidc_group_and_role_mapping + become: true + notify: + - Ensure netbox systemd services are set up and up-to-date + +- name: Ensures custom pipeline code for OIDC group and role mapping is not present + ansible.builtin.file: + path: /opt/netbox/netbox/netbox/custom_pipeline_oidc_mapping.py + state: absent + when: not netbox__custom_pipeline_oidc_group_and_role_mapping + become: true notify: - Ensure netbox systemd services are set up and up-to-date