Skip to content

Add namespace filters in external audit event destinations for groups

Hitesh Raghuvanshi requested to merge 424175-group-project-filter-list into master

What does this MR do and why?

Added namespace (subgroup and project) filters in the query for listing down all the external audit event destinations for a group.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

  1. Add 2 audit event destinations for a top-level group by following steps mentioned in https://docs.gitlab.com/ee/administration/audit_event_streaming/#add-a-new-http-destination.
  2. Create 1 subgroup and 1 project under the group, you can create more if you want or have deeper level of inheritance for subgroup and project.
  3. Open rails console gdk rails c
    1. Get the top level group object, all its external destinations and the objects of the subgroup and project namespace for which you want to create filter by running following example commands:
       group = Group.find(35)
       destinations = group.external_audit_event_destinations
       subgroup = Group.find(38)
       project_namespace = Project.find(56).project_namespace
    1. Now create filters for any 2 of the destinations, 1 for subgroup and 1 for the project by running following sample commands:
       AuditEvents::Streaming::HTTP::NamespaceFilter.create(external_audit_event_destination: destinations.first, namespace: subgroup)
       AuditEvents::Streaming::HTTP::NamespaceFilter.create(external_audit_event_destination: destinations.last, namespace: project_namespace)
    1. Make sure the filters have been created by running following command and it should return 2 objects.
       AuditEvents::Streaming::HTTP::NamespaceFilter.all
  4. Now open graphql explorer and run following query by replacing name of group with the one that you had for the top-level group:
query externalAuditEventDestinations {
  group(fullPath: "Twitter") {
    id
    externalAuditEventDestinations {
      nodes {
        destinationUrl
        verificationToken
        id
        name
        headers {
          nodes {
            key
            value
            id
            active
          }
        }
        eventTypeFilters
        namespaceFilter {
          id
          namespace {
            id
            name
            fullName
          }
          externalAuditEventDestination {
           id 
          }
        }
      }
    }
  }
}
  1. The output of query in step 4 would be something like:
Output - Click to expand
{
  "data": {
    "group": {
      "id": "gid://gitlab/Group/35",
      "externalAuditEventDestinations": {
        "nodes": [
          {
            "destinationUrl": "https://www.example4.com",
            "verificationToken": "FAiwUAQq3tFHoteK3K6zATw6",
            "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/4",
            "name": "asd",
            "headers": {
              "nodes": []
            },
            "eventTypeFilters": [],
            "namespaceFilter": null
          },
          {
            "destinationUrl": "https://www.example3.com",
            "verificationToken": "waGppKK5VMuLoyqSEjQE9958",
            "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/3",
            "name": "subproj3",
            "headers": {
              "nodes": []
            },
            "eventTypeFilters": [],
            "namespaceFilter": {
              "id": "gid://gitlab/AuditEvents::Streaming::HTTP::NamespaceFilter/2",
              "namespace": {
                "id": "gid://gitlab/Namespaces::ProjectNamespace/99",
                "name": "subproj3",
                "fullName": "Twitter / sub1 / sub2 / subproj3"
              },
              "externalAuditEventDestination": {
                "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/3"
              }
            }
          },
          {
            "destinationUrl": "https://www.example1.com",
            "verificationToken": "wDm1skvxTThg1SgxkLrhfTKn",
            "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/2",
            "name": "subg1",
            "headers": {
              "nodes": []
            },
            "eventTypeFilters": [],
            "namespaceFilter": {
              "id": "gid://gitlab/AuditEvents::Streaming::HTTP::NamespaceFilter/3",
              "namespace": {
                "id": "gid://gitlab/Group/98",
                "name": "sub2",
                "fullName": "Twitter / sub1 / sub2"
              },
              "externalAuditEventDestination": {
                "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/2"
              }
            }
          },
          {
            "destinationUrl": "https://www.example.com",
            "verificationToken": "ApNFMM5yNY75TVPCYZL2XCEx",
            "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/1",
            "name": "example",
            "headers": {
              "nodes": []
            },
            "eventTypeFilters": [],
            "namespaceFilter": {
              "id": "gid://gitlab/AuditEvents::Streaming::HTTP::NamespaceFilter/1",
              "namespace": {
                "id": "gid://gitlab/Group/35",
                "name": "Twitter",
                "fullName": "Twitter"
              },
              "externalAuditEventDestination": {
                "id": "gid://gitlab/AuditEvents::ExternalAuditEventDestination/1"
              }
            }
          }
        ]
      }
    }
  }
}

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #424175 (closed)

Edited by Hitesh Raghuvanshi

Merge request reports