GitLab
Discover GitLab projects, sync rules from a repository, comment on merge requests with their impact, and open merge requests for rule requests.
The GitLab tool (nistor-tool-gitlab, tool id gitlab) owns everything in Nistor that calls the GitLab API. It does four
separate things, and you can use any of them without the others:
| Feature | What it does | Switched on by |
|---|---|---|
| Repositories as nodes | Every repository Nistor knows about becomes a GitlabProject node, and a token can discover the rest of a group. |
The gitlab tool in the compiler configuration, and optionally GITLAB_DISCOVERY_TOKEN |
| Rules from a repository | Rules kept as files in a repository are synced to Nistor, by CI push or by Nistor pulling them. | CI push needs nothing on GitLab. Pull needs GITOPS_PULL_ENABLED. |
| Merge-request impact comment | A merge request gets a comment listing the nodes, rules and incidents it affects. | GITOPS_MR_BOT_ENABLED, a GitOps connection and a webhook |
| Rule-request merge requests | When someone requests a rule and a reviewer approves it, Nistor opens a merge request that adds the rule to your rules repository. | RULE_REQUEST_* settings |
The package README calls the tool Alpha, as does its classifier (see the overview).
What needs an Enterprise module#
None of the four features does. One section of the merge-request comment depends on a module: "DQ checks touched" lists rules whose action is a data-quality check, which come from the Data quality module (Nistor Enterprise). Without it, that section reads "none".
What the features share#
CI push needs nothing here. The other features need these three things:
- The tool must be active in the environment. Add
{"id": "gitlab"}to the environment's compiler configuration (below). Pull sync, the merge-request comment, rule-request merge requests and the test of a GitOps connection all refuse while the tool is not listed there. The list is re-read every minute. - A default Git host. Set
DEPLOYMENTS_DEFAULT_GIT_HOST, or leave it empty and Nistor uses the host ofRULE_REQUEST_GITLAB_URL. Nistor sends a GitLab token only to that host, whatever repository address a connection names. - Tokens as secret names. A GitOps connection and the rule-request flow name a Secret Manager secret, by its name
and not its path. The backend's service account needs
roles/secretmanager.secretAccessoron it.
The reference Terraform root has no input for the settings on this page. Set the plain ones on the backend role through
role_extra_env_vars. GITLAB_DISCOVERY_TOKEN is itself a token and must reach the compiler as a secret reference,
which that input cannot express.
Make the tool active and find repositories#
Save a compiler configuration with a gitlab entry (see CLI):
[
{
"environment": "prod",
"tools": [
{
"id": "gitlab",
"config": {
"groups": ["acme/data"],
"discover_known_groups": true,
"include_subgroups": false,
"include_archived": false
}
}
]
}
]
A compile builds GitlabProject nodes from two scopes:
- Known repositories. The repositories the backend already knows, on your GitLab host: GitOps connections, CI deployment reports, deployment provenance (including every Dataform remote) and the repository that owns a config-as-code rule. These need no token.
- Discovery. Only with
GITLAB_DISCOVERY_TOKENset: the projects of every group ingroups, and, withdiscover_known_groups(defaulttrue), the parent group of every known repository.include_subgroupsandinclude_archiveddefault tofalse.
If GitLab or the backend is down during a compile, the previous nodes are kept. A group that Nistor derived itself and that the token cannot see is skipped quietly. A group you listed that fails is reported.
A repository is linked to what it deploys when the graph is read (as "deployed by"), and never as lineage.
The gitlab connection#
You can create a connection of type gitlab in the web shell (Connections, /admin/connections):
| Field | Required | Meaning |
|---|---|---|
base_url |
yes | The root of the GitLab site, without /api/v4. |
| Secret | Required | Meaning |
|---|---|---|
token |
yes | A token that can read the API. |
The test calls GET {base_url}/api/v4/version with the token and is healthy only when the reply is a version document.
Nothing else reads this connection yet: discovery and the API clients use the settings on this page. A GitOps connection
(below) is a different thing, with its own token.
Rules from a repository#
A repository keeps its rules as top-level *.json, *.yaml or *.yml files in one directory, each file a list of rules.
There are two ways to get them into Nistor, and one repository uses exactly one:
| CI push | Pull | |
|---|---|---|
| Who calls whom | Your pipeline calls Nistor (nistor rules sync). |
Nistor reads the repository. |
| Calls GitLab | No. It works with any Git host. | Yes. |
| Needs | NISTOR_API_URL and NISTOR_API_TOKEN in the pipeline |
GITOPS_PULL_ENABLED=true, a GitOps connection in pull mode |
| What it syncs | Rules (nistor rules sync), alerts (nistor alerts sync), contracts (nistor odcs sync), and deployment records (nistor deployments record) |
Rules only |
Pull mode, on a GitOps connection:
- Create the connection on the GitOps page of the web shell (
/gitops) in the mode labelled "Pull". The API value of that mode still carries the product's former name, so use the page. - Its fields:
repo_url,repo_project_path,branch_mapping(defaultdevtodev,testtotest,prodtoprod),rules_directory(defaultrules/),gitlab_token_secret(a secret name), andpoll_interval_minutes(default 5, from 1 to 1440). - Each backend syncs only the branch mapped to its own environment, and at most one branch per environment.
- A sync reads one commit, all or nothing: if any file fails to parse or validate, nothing is written. A head that did not change is a no change. Rules that came from this repository and are no longer in it are removed.
- A repository that is pulled refuses CI reports: remove its sync job, or switch the connection to CI push.
- Creating a pull connection, or changing its repository, branch mapping, directory or token, needs
config:manage. Other changes to GitOps connections needconnections:manage.
Check a rule file before you push it:
nistor rules validate --dir rules/
nistor rules sync --env prod --dir rules/ --source-repo acme/rules --delete-orphaned
Merge-request impact comment#
The bot reads a merge request and posts one comment saying what it touches. To switch it on:
-
Set
GITOPS_MR_BOT_ENABLED=trueon the backend. -
Create a GitOps connection for the repository and set its
mr_impact_enabledtotrue, withgitlab_token_secretnaming the secret that holds the token. -
Create a webhook endpoint for the connection. The response carries the endpoint's secret once, and its path:
curl -X POST "$NISTOR_API_URL/api/v1/webhooks/" \ -H "Authorization: Bearer $NISTOR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"slug": "acme-rules-mr", "name": "acme rules merge requests", "webhook_type": "gitlab_mr", "gitops_connection_id": "<connection-uuid>"}' -
In the GitLab project, add a webhook that points at
https://<your-nistor-host>/api/webhooks/acme-rules-mr, with the secret as its secret token, for merge request events. Nistor checks theX-Gitlab-Tokenheader against it.
The receiver route has no sign-in of its own: it checks the token and nothing else, so your proxy must let GitLab reach
/api/webhooks/. While the bot is off, the endpoint answers 404 exactly as an unknown path does.
The bot analyses a merge request when it is opened, reopened, or updated with new commits, and not when it is closed, merged or approved. It runs inside the backend, two analyses at a time, and does the same head commit only once. It maps the changed files to nodes by three sources: Dataform files, Terraform files and rule files. The comment, which it edits in place on later pushes, has these sections:
- affected nodes and the size of their blast radius (the changed nodes and what is downstream);
- scheduling rules that match them;
- data-quality checks that match them (see above);
- open incidents on them;
- an estimated BigQuery cost delta, which this release does not compute ("not available in this release");
- files that matched no node, with their count.
To see what the bot would post without posting it, call POST /api/v1/gitops/mr-preview with gitops_connection_id
and mr_iid (needs gitops:view).
Rule-request merge requests#
In the web shell a person can request a rule. When a reviewer approves the request, Nistor opens a merge request in your rules repository that adds the rule to a file. If the approval fails, the request stays unapproved.
| Setting | Default | Meaning |
|---|---|---|
RULE_REQUEST_GITLAB_URL |
https://gitlab.example.com |
The GitLab address the merge requests are opened on. Keep it non-empty. |
RULE_REQUEST_GITLAB_TOKEN_SECRET |
empty | The name of the secret holding the token. Empty means every approval fails. |
RULE_REQUEST_REPO_PROJECT_PATH |
your-group/nistor |
The project (group/project) that receives the merge requests. |
RULE_REQUEST_RULES_DIR |
a directory of Nistor's own deployment repository | The directory of the repository where the rule files live. Set it to yours. |
RULE_REQUEST_MR_TARGET_BRANCH |
empty | The branch the merge request targets. Empty means the repository's default branch, which the token must be able to read. |
The environment variables GITLAB_TOKEN and GITOPS_GITLAB_TOKEN, when set, take precedence over the secret. They are
meant for development and test.
The file is chosen from the action of the rule, and the file names are fixed in the code:
| Action | File in RULE_REQUEST_RULES_DIR |
|---|---|
dataform_run, and any action not listed here |
dwh_rules.json |
data_quality_check |
data_quality_rules.json |
microstrategy_refresh |
microstrategy_rules.json |
bigquery_export_gcs, bigquery_copy |
export_rules.json |
The code accepts seven file names in all, and refuses any other: data_insight_rules.json, data_mart.json,
data_quality_rules.json, dwh_rules.json, export_rules.json, historization_rules.json and
microstrategy_rules.json. The file is created if it does not exist, and must be a JSON array of rules if it does.
Nistor gives the rule a code_id of the form <prefix>/<slug>, commits to a new branch with the message
feat(rules): add <code_id> (Nistor rule request), and opens the merge request. If an approval is retried, Nistor
reuses the open or merged merge request of that request instead of opening a second one.
Permissions#
| Use | Role and scope the GitLab token needs |
|---|---|
Discovery (GITLAB_DISCOVERY_TOKEN) |
A group access token with the Reporter role and read_api |
| Pull sync | At least Reporter, with read_repository |
| Merge-request impact comment | At least Reporter, with api: read_api reads the merge request, and posting a note needs api |
| Rule-request merge requests | A project access token with the Developer role and api |
The gitlab connection test |
A token that can read the API |
In Nistor, GitOps connections and webhook endpoints need connections:manage (pull connections also config:manage),
a merge-request preview needs gitops:view, and replacing the compiler configuration needs compiler:trigger.
Settings#
| Variable | Default | Meaning |
|---|---|---|
GITOPS_PULL_ENABLED |
false |
Allow pull-mode connections. |
GITOPS_MR_BOT_ENABLED |
false |
Allow the merge-request bot, its webhook and its preview. |
DEPLOYMENTS_DEFAULT_GIT_HOST |
empty | The one host tokens are sent to, and the host a bare group/project is read against. |
GITLAB_DISCOVERY_TOKEN |
none | The discovery token. Without it, only known repositories become nodes. |
RULE_REQUEST_* |
see above | The rule-request merge-request flow. |