Skip to content

Commit 9185e1c

Browse files
committed
feat(sync-users): add synchronization script for gitlab
1 parent 6fdc138 commit 9185e1c

File tree

7 files changed

+886
-7
lines changed

7 files changed

+886
-7
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ Should you have any inquiries or need assistance, please don't hesitate to conta
66

77
Below is a brief overview of the tools available in this repository:
88

9-
Tools | Description
10-
------------ | -------------
11-
[api-migration](./api-migration) | Facilitates the migration of incident remediation progress across different environments, including SaaS ↔ Self-Hosted, Self-Hosted ↔ Self-Hosted, and SaaS ↔ SaaS.
12-
[new-arch-migration](./new-arch-migration) | Assists in transitioning from the legacy GitGuardian architecture to the new architecture for Self-Hosted environments.
13-
[helm-preflights](./helm-preflights) | Ensures GitGuardian requirements are met prior installation or upgrade via [Helm on existing clusters](https://docs.gitguardian.com/self-hosting/installation/installation-existing-helm) by conducting tests from both the local user and the Kubernetes cluster.
14-
[honeytoken-tools](./honeytoken-tools) | Script to disseminate honeytokens in your repositories via Pull Requests
15-
[team-mapping-github-gitguardian](./team-mapping-github-gitguardian) | An example script using the GitHub and GitGuardian APIs to map GitHub Teams and the repositories they own to GitGuardian Teams and their perimeters.
9+
| Tools | Description |
10+
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
11+
| [api-migration](./api-migration) | Facilitates the migration of incident remediation progress across different environments, including SaaS ↔ Self-Hosted, Self-Hosted ↔ Self-Hosted, and SaaS ↔ SaaS. |
12+
| [new-arch-migration](./new-arch-migration) | Assists in transitioning from the legacy GitGuardian architecture to the new architecture for Self-Hosted environments. |
13+
| [helm-preflights](./helm-preflights) | Ensures GitGuardian requirements are met prior installation or upgrade via [Helm on existing clusters](https://docs.gitguardian.com/self-hosting/installation/installation-existing-helm) by conducting tests from both the local user and the Kubernetes cluster. |
14+
| [honeytoken-tools](./honeytoken-tools) | Script to disseminate honeytokens in your repositories via Pull Requests |
15+
| [team-mapping-github-gitguardian](./team-mapping-github-gitguardian) | An example script using the GitHub and GitGuardian APIs to map GitHub Teams and the repositories they own to GitGuardian Teams and their perimeters. |
16+
| [team-mapping-gitlab-gitguardian](./team-mapping-gitlab-gitguardian) | An example script using the Gitlab and GitGuardian APIs to map Gitlab Groups and the repositories they own to GitGuardian Teams and their perimeters. |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
## 2025-01-02
4+
5+
### Added
6+
7+
- Support user and user team synchronization.
8+
- Support project and team sources synchronization.
9+
- Rely on python Logging and support logging level in the configuration.
10+
- Use py-gitguardian for calls made to the GitGuardian API.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Team mapping: Gitlab to GitGuardian
2+
3+
The included scripts provide an example of using the Gitlab and GitGuardian
4+
APIs to map Gitlab groups and the repositories they own to GitGuardian Teams and
5+
their perimeters.
6+
7+
> [!CAUTION]
8+
> This is example code that can be used as a starting point for your own
9+
> solution. While we're happy to answer questions about it _it is not a
10+
> supported part of the product_.
11+
12+
### Installation
13+
14+
The easiest method of installation is to use Python virtual environment (venv):
15+
16+
```
17+
unzip team-mapping-gitlab-gitguardian.zip
18+
cd team-mapping-gitlab-gitguardian
19+
python3 -mvenv .venv
20+
source .venv/bin/activate
21+
pip install -r requirements.txt
22+
```
23+
24+
### Configuration
25+
26+
Three environment variables must be set to configure the connection:
27+
28+
- `GITLAB_URL` - The base URL for your Gitlab instance.
29+
- `GITLAB_ACCESS_TOKEN` - A Gitlab PAT with `read_api` and `read_user` permissions.
30+
- `GITGUARDIAN_API_KEY` - A GitGuardian API Service Account Token with `members:read`, `members:write`, `teams:read`, `teams:write`, `sources:read` and `sources:write` permissions.
31+
32+
> [!TIP]
33+
> If a Personal Access Token is used, the user who owns the PAT will be added
34+
> to all teams when they're created. SATs are preferred for this reason.
35+
36+
Optional environment variables:
37+
38+
- `GITGUARDIAN_INSTANCE` - The URL of a self-hosted GitGuardian instance. Just the scheme and hostname: https://gitguardian.example.com
39+
- `SEND_EMAIL` - Defines whether we should send an email to users when sending invitations
40+
- `EXCLUDE_ADMIN` - Defines whether we should exclude admin users from sync
41+
- `DEFAULT_INCIDENT_PERMISSION` - Defines the default incident permission level for team members, defaults to `can_edit`, it's value must be one of :
42+
- `can_view` : For read permissions
43+
- `can_edit` : For read and write permissions
44+
- `full_access` : For manager permissions
45+
46+
In order to ensure you have the correct configuration, you can run the following command to display the configuration:
47+
48+
```
49+
python config.py
50+
```
51+
52+
### Nested groups
53+
54+
Teams in GitGuardian will be created based on the name of the deepest group (not the **full path**) of every user's group.
55+
56+
This means that if a user is in `top-group / middle-group / bottom-group`, he will be added to the team `bottom-group` in GitGuardian.
57+
58+
### Invoking
59+
60+
Upon invocation, the script will sync teams and their perimeters from Gitlab to GitGuardian. It can be invoked like this:
61+
62+
```
63+
python sync_gitlab.py
64+
```
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import logging
2+
import os
3+
4+
from pygitguardian.client import GGClient
5+
from functools import cached_property
6+
from dataclasses import dataclass
7+
8+
from pygitguardian.models import IncidentPermission
9+
10+
11+
@dataclass
12+
class Config:
13+
gitlab_token: str
14+
gitguardian_api_key: str
15+
gitguardian_url: str
16+
17+
gitlab_url: str
18+
19+
send_email: bool
20+
exclude_admin: bool
21+
default_incident_permission: IncidentPermission = IncidentPermission.EDIT
22+
logger_level: str = logging.INFO
23+
24+
@classmethod
25+
def from_env(cls):
26+
incident_permission = cls.default_incident_permission
27+
if incident_permission_env := os.environ.get("DEFAULT_INCIDENT_PERMISSION"):
28+
incident_permission = IncidentPermission(incident_permission_env)
29+
30+
logger_level = logging._nameToLevel(os.environ.get("LOG_LEVEL", "INFO"))
31+
32+
return cls(
33+
gitlab_token=os.environ["GITLAB_ACCESS_TOKEN"],
34+
gitguardian_api_key=os.environ["GITGUARDIAN_API_KEY"],
35+
gitlab_url=os.environ.get("GITLAB_URL", "https://gitlab.com"),
36+
gitguardian_url=os.environ.get(
37+
"GITGUARDIAN_INSTANCE", "https://api.gitguardian.com"
38+
),
39+
send_email=os.environ.get("SEND_EMAIL", "True") == "True",
40+
exclude_admin=os.environ.get("EXCLUDE_ADMIN", "True") == "True",
41+
default_incident_permission=incident_permission,
42+
logger_level=logger_level,
43+
)
44+
45+
@cached_property
46+
def client(self):
47+
return GGClient(api_key=self.gitguardian_api_key, base_uri=self.gitguardian_url)
48+
49+
def __repr__(self):
50+
return (
51+
"Config("
52+
f"send_email={self.send_email}, "
53+
f"gitlab_url={self.gitlab_url}, "
54+
f"gitlab_token={self.gitlab_token}, "
55+
f"exclude_admin={self.exclude_admin}, "
56+
f"gitguardian_url={self.gitguardian_url}, "
57+
f"gitguardian_api_key={self.gitguardian_api_key}, "
58+
f"default_incident_permission={self.default_incident_permission}"
59+
")"
60+
)
61+
62+
63+
CONFIG = Config.from_env()
64+
65+
if __name__ == "__main__":
66+
print(CONFIG)

0 commit comments

Comments
 (0)