krebs.git.rules: specify type
This commit is contained in:
parent
68655d1ddf
commit
cdb590be50
@ -44,8 +44,74 @@ let
|
|||||||
default = "/etc/git";
|
default = "/etc/git";
|
||||||
};
|
};
|
||||||
repos = mkOption {
|
repos = mkOption {
|
||||||
type = types.attrsOf (types.submodule ({
|
type = types.attrsOf subtypes.repo;
|
||||||
|
default = {};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
testing = {
|
||||||
|
name = "testing";
|
||||||
|
hooks.post-update = '''
|
||||||
|
#! /bin/sh
|
||||||
|
set -euf
|
||||||
|
echo post-update hook: $* >&2
|
||||||
|
''';
|
||||||
|
};
|
||||||
|
testing2 = { name = "testing2"; };
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Repositories.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
root-desc = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Text printed below the heading on the repository index page.
|
||||||
|
Default value: "a fast webinterface for the git dscm".
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
root-title = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Text printed as heading on the repository index page.
|
||||||
|
Default value: "Git Repository Browser".
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
rules = mkOption {
|
||||||
|
type = types.listOf subtypes.rule;
|
||||||
|
default = [];
|
||||||
|
example = literalExample ''
|
||||||
|
singleton {
|
||||||
|
user = [ config.krebs.users.tv ];
|
||||||
|
repo = [ testing ]; # see literal example of repos
|
||||||
|
perm = push "refs/*" (with lib.git; [
|
||||||
|
non-fast-forward create delete merge
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Rules.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO put into krebs/4lib/types.nix?
|
||||||
|
subtypes = {
|
||||||
|
repo = types.submodule ({
|
||||||
options = {
|
options = {
|
||||||
|
collaborators = mkOption {
|
||||||
|
type = types.listOf types.user;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of users that should be able to fetch from this repo.
|
||||||
|
|
||||||
|
This option is currently not used by krebs.git but instead can be
|
||||||
|
used to create rules. See e.g. <stockholm/tv/2configs/git.nix> for
|
||||||
|
an example.
|
||||||
|
'';
|
||||||
|
};
|
||||||
desc = mkOption {
|
desc = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
@ -82,48 +148,69 @@ let
|
|||||||
# TODO allow every configured user to fetch the repository via SSH.
|
# TODO allow every configured user to fetch the repository via SSH.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}));
|
});
|
||||||
|
rule = types.submodule ({ config, ... }: {
|
||||||
default = {};
|
options = {
|
||||||
|
user = mkOption {
|
||||||
example = literalExample ''
|
type = types.listOf types.user;
|
||||||
{
|
|
||||||
testing = {
|
|
||||||
name = "testing";
|
|
||||||
hooks.post-update = '''
|
|
||||||
#! /bin/sh
|
|
||||||
set -euf
|
|
||||||
echo post-update hook: $* >&2
|
|
||||||
''';
|
|
||||||
};
|
|
||||||
testing2 = { name = "testing2"; };
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
description = ''
|
description = ''
|
||||||
Repositories.
|
List of users this rule should apply to.
|
||||||
|
Checked by authorize-command.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
root-desc = mkOption {
|
repo = mkOption {
|
||||||
|
type = types.listOf subtypes.repo;
|
||||||
|
description = ''
|
||||||
|
List of repos this rule should apply to.
|
||||||
|
Checked by authorize-command.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
perm = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
# TODO generate enum argument from krebs/4lib/git.nix
|
||||||
|
options = {
|
||||||
|
allow-commands = mkOption {
|
||||||
|
type = types.listOf (types.enum (with git; [
|
||||||
|
git-receive-pack
|
||||||
|
git-upload-pack
|
||||||
|
]));
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of commands the rule's users are allowed to execute.
|
||||||
|
Checked by authorize-command.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
allow-receive-ref = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Text printed below the heading on the repository index page.
|
Ref that can receive objects.
|
||||||
Default value: "a fast webinterface for the git dscm".
|
Checked by authorize-push.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
root-title = mkOption {
|
allow-receive-modes = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.listOf (types.enum (with git; [
|
||||||
default = null;
|
fast-forward
|
||||||
|
non-fast-forward
|
||||||
|
create
|
||||||
|
delete
|
||||||
|
merge
|
||||||
|
]));
|
||||||
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Text printed as heading on the repository index page.
|
List of allowed receive modes.
|
||||||
Default value: "Git Repository Browser".
|
Checked by pre-receive hook.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
rules = mkOption {
|
|
||||||
type = types.unspecified;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
description = ''
|
||||||
|
Permissions granted.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
git-imp = {
|
git-imp = {
|
||||||
system.activationScripts.git-init = "${init-script}";
|
system.activationScripts.git-init = "${init-script}";
|
||||||
@ -131,18 +218,18 @@ let
|
|||||||
# TODO maybe put all scripts here and then use PATH?
|
# TODO maybe put all scripts here and then use PATH?
|
||||||
environment.etc."${etc-base}".source =
|
environment.etc."${etc-base}".source =
|
||||||
scriptFarm "git-ssh-authorizers" {
|
scriptFarm "git-ssh-authorizers" {
|
||||||
authorize-command = makeAuthorizeScript (map ({ repo, user, perm }: [
|
authorize-command = makeAuthorizeScript (map (rule: [
|
||||||
(map getName (ensureList user))
|
(map getName (ensureList rule.user))
|
||||||
(map getName (ensureList repo))
|
(map getName (ensureList rule.repo))
|
||||||
(map getName perm.allow-commands)
|
(map getName rule.perm.allow-commands)
|
||||||
]) cfg.rules);
|
]) cfg.rules);
|
||||||
|
|
||||||
authorize-push = makeAuthorizeScript (map ({ repo, user, perm }: [
|
authorize-push = makeAuthorizeScript (map (rule: [
|
||||||
(map getName (ensureList user))
|
(map getName (ensureList rule.user))
|
||||||
(map getName (ensureList repo))
|
(map getName (ensureList rule.repo))
|
||||||
(ensureList perm.allow-receive-ref)
|
(ensureList rule.perm.allow-receive-ref)
|
||||||
(map getName perm.allow-receive-modes)
|
(map getName rule.perm.allow-receive-modes)
|
||||||
]) (filter (x: hasAttr "allow-receive-ref" x.perm) cfg.rules));
|
]) (filter (rule: rule.perm.allow-receive-ref != null) cfg.rules));
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraUsers = singleton rec {
|
users.extraUsers = singleton rec {
|
||||||
|
@ -9,7 +9,7 @@ let
|
|||||||
enable = true;
|
enable = true;
|
||||||
root-title = "public repositories at ${config.krebs.build.host.name}";
|
root-title = "public repositories at ${config.krebs.build.host.name}";
|
||||||
root-desc = "keep calm and engage";
|
root-desc = "keep calm and engage";
|
||||||
repos = mapAttrs (_: s: removeAttrs s ["collaborators"]) repos;
|
repos = repos;
|
||||||
rules = rules;
|
rules = rules;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -99,7 +99,7 @@ let
|
|||||||
repo = [ repo ];
|
repo = [ repo ];
|
||||||
perm = fetch;
|
perm = fetch;
|
||||||
} ++
|
} ++
|
||||||
optional (length (repo.collaborators or []) > 0) {
|
optional (repo.collaborators or [] != []) {
|
||||||
user = repo.collaborators;
|
user = repo.collaborators;
|
||||||
repo = [ repo ];
|
repo = [ repo ];
|
||||||
perm = fetch;
|
perm = fetch;
|
||||||
|
Loading…
Reference in New Issue
Block a user