diff options
Diffstat (limited to 'systems/eldiron/gitolite')
-rw-r--r-- | systems/eldiron/gitolite/default.nix | 127 | ||||
-rwxr-xr-x | systems/eldiron/gitolite/gitolite_ldap_groups.sh | 15 | ||||
-rw-r--r-- | systems/eldiron/gitolite/ldap_gitolite.sh | 28 |
3 files changed, 170 insertions, 0 deletions
diff --git a/systems/eldiron/gitolite/default.nix b/systems/eldiron/gitolite/default.nix new file mode 100644 index 0000000..1885234 --- /dev/null +++ b/systems/eldiron/gitolite/default.nix | |||
@@ -0,0 +1,127 @@ | |||
1 | { lib, pkgs, config, ... }: | ||
2 | let | ||
3 | cfg = config.myServices.gitolite; | ||
4 | in { | ||
5 | options.myServices.gitolite = { | ||
6 | enable = lib.mkEnableOption "my gitolite service"; | ||
7 | gitoliteDir = lib.mkOption { | ||
8 | type = lib.types.str; | ||
9 | default = "/var/lib/gitolite"; | ||
10 | }; | ||
11 | }; | ||
12 | |||
13 | config = lib.mkIf cfg.enable { | ||
14 | myServices.dns.zones."immae.eu".subdomains.git = | ||
15 | with config.myServices.dns.helpers; ips servers.eldiron.ips.main; | ||
16 | |||
17 | myServices.chatonsProperties.services.gitolite = { | ||
18 | file.datetime = "2022-08-21T10:01:00"; | ||
19 | service = { | ||
20 | name = "Gitolite"; | ||
21 | description = "Gitolite allows you to setup git hosting on a central server, with fine-grained access control and many more powerful features."; | ||
22 | website = "https://git.immae.eu"; | ||
23 | logo = "https://git.immae.eu/cgit-css/favicon.ico"; | ||
24 | status.level = "OK"; | ||
25 | status.description = "OK"; | ||
26 | registration."" = ["MEMBER" "CLIENT"]; | ||
27 | registration.load = "OPEN"; | ||
28 | install.type = "PACKAGE"; | ||
29 | guide.user = "https://www.immae.eu/docs/forge-logicielle.html"; | ||
30 | }; | ||
31 | software = { | ||
32 | name = "Gitolite"; | ||
33 | website = "https://gitolite.com/gitolite/"; | ||
34 | license.url = "https://github.com/sitaramc/gitolite/blob/master/COPYING"; | ||
35 | license.name = "GNU General Public License v2.0"; | ||
36 | version = pkgs.gitolite.version; | ||
37 | source.url = "https://github.com/sitaramc/gitolite"; | ||
38 | }; | ||
39 | }; | ||
40 | myServices.ssh.modules.gitolite = { | ||
41 | snippet = builtins.readFile ./ldap_gitolite.sh; | ||
42 | dependencies = [ pkgs.gitolite ]; | ||
43 | vars.ldap_group = "cn=users,cn=gitolite,ou=services,dc=immae,dc=eu"; | ||
44 | vars.shell_path = "${pkgs.gitolite}/bin/gitolite-shell"; | ||
45 | vars.services = let | ||
46 | toLine = login: key: ''command="${pkgs.gitolite}/bin/gitolite-shell ${login}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ${key}''; | ||
47 | in builtins.concatStringsSep "\n" [ | ||
48 | (toLine "naemon" config.myEnv.monitoring.ssh_public_key) | ||
49 | (toLine "buildbot" config.myEnv.buildbot.ssh_key.public) | ||
50 | ]; | ||
51 | }; | ||
52 | networking.firewall.allowedTCPPorts = [ 9418 ]; | ||
53 | |||
54 | secrets.keys."gitolite/ldap_password" = { | ||
55 | user = "gitolite"; | ||
56 | group = "gitolite"; | ||
57 | permissions = "0400"; | ||
58 | text = config.myEnv.tools.gitolite.ldap.password; | ||
59 | }; | ||
60 | |||
61 | services.gitDaemon = { | ||
62 | enable = true; | ||
63 | user = "gitolite"; | ||
64 | group = "gitolite"; | ||
65 | basePath = "${cfg.gitoliteDir}/repositories"; | ||
66 | }; | ||
67 | |||
68 | system.activationScripts.gitolite = let | ||
69 | deps = [ pkgs.openldap pkgs.stdenv.shellPackage pkgs.gnugrep pkgs.coreutils ]; | ||
70 | gitolite_ldap_groups = pkgs.runCommand "gitolite_ldap_groups.sh" { | ||
71 | buildInputs = [ pkgs.makeWrapper ]; | ||
72 | } '' | ||
73 | makeWrapper "${./gitolite_ldap_groups.sh}" "$out" \ | ||
74 | --prefix PATH : ${lib.makeBinPath deps} \ | ||
75 | --set LDAP_PASS_PATH ${config.secrets.fullPaths."gitolite/ldap_password"} | ||
76 | ''; | ||
77 | in { | ||
78 | deps = [ "users" ]; | ||
79 | text = '' | ||
80 | if [ -d ${cfg.gitoliteDir} ]; then | ||
81 | ln -sf ${gitolite_ldap_groups} ${cfg.gitoliteDir}/gitolite_ldap_groups.sh | ||
82 | chmod g+rx ${cfg.gitoliteDir} | ||
83 | fi | ||
84 | if [ -f ${cfg.gitoliteDir}/projects.list ]; then | ||
85 | chmod g+r ${cfg.gitoliteDir}/projects.list | ||
86 | fi | ||
87 | ''; | ||
88 | }; | ||
89 | |||
90 | users.users.wwwrun.extraGroups = [ "gitolite" ]; | ||
91 | users.users.gitolite.extraGroups = [ "keys" ]; | ||
92 | |||
93 | users.users.gitolite.packages = let | ||
94 | python-packages = python-packages: with python-packages; [ | ||
95 | simplejson | ||
96 | apprise | ||
97 | sleekxmpp | ||
98 | urllib3 | ||
99 | pyyaml | ||
100 | ]; | ||
101 | in | ||
102 | [ | ||
103 | # For some reason it absolutely wants to include "doc" output | ||
104 | ((pkgs.python39.withPackages python-packages) // { doc = ""; }) | ||
105 | pkgs.nettools | ||
106 | pkgs.findutils | ||
107 | ]; | ||
108 | # Installation: https://git.immae.eu/mantisbt/view.php?id=93 | ||
109 | services.gitolite = { | ||
110 | enable = true; | ||
111 | adminPubkey = config.myEnv.sshd.rootKeys.immae_dilion; | ||
112 | }; | ||
113 | myServices.monitoring.fromMasterActivatedPlugins = [ "git" ]; | ||
114 | myServices.monitoring.fromMasterObjects.service = [ | ||
115 | { | ||
116 | service_description = "gitolite is working"; | ||
117 | host_name = config.hostEnv.fqdn; | ||
118 | use = "external-web-service"; | ||
119 | check_command = "check_git"; | ||
120 | |||
121 | servicegroups = "webstatus-remote-services"; | ||
122 | _webstatus_name = "Git"; | ||
123 | _webstatus_url = "git.immae.eu"; | ||
124 | } | ||
125 | ]; | ||
126 | }; | ||
127 | } | ||
diff --git a/systems/eldiron/gitolite/gitolite_ldap_groups.sh b/systems/eldiron/gitolite/gitolite_ldap_groups.sh new file mode 100755 index 0000000..ffa2dab --- /dev/null +++ b/systems/eldiron/gitolite/gitolite_ldap_groups.sh | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/usr/bin/env bash | ||
2 | |||
3 | uid_param="$1" | ||
4 | ldap_host="ldap://ldap.immae.eu" | ||
5 | ldap_binddn="cn=gitolite,ou=services,dc=immae,dc=eu" | ||
6 | ldap_bindpw="$(cat $LDAP_PASS_PATH)" | ||
7 | ldap_searchbase="dc=immae,dc=eu" | ||
8 | ldap_scope="subtree" | ||
9 | |||
10 | ldap_options="-H ${ldap_host} -ZZ -x -D ${ldap_binddn} -w ${ldap_bindpw} -b ${ldap_searchbase} -s ${ldap_scope}" | ||
11 | |||
12 | ldap_filter="(&(memberOf=cn=groups,cn=gitolite,ou=services,dc=immae,dc=eu)(|(member=uid=${uid_param},ou=users,dc=immae,dc=eu)(member=uid=${uid_param},ou=group_users,dc=immae,dc=eu)))" | ||
13 | ldap_result=$(ldapsearch ${ldap_options} -LLL "${ldap_filter}" cn | grep 'cn:' | cut -d' ' -f2) | ||
14 | |||
15 | echo "$ldap_result" | ||
diff --git a/systems/eldiron/gitolite/ldap_gitolite.sh b/systems/eldiron/gitolite/ldap_gitolite.sh new file mode 100644 index 0000000..75a39bf --- /dev/null +++ b/systems/eldiron/gitolite/ldap_gitolite.sh | |||
@@ -0,0 +1,28 @@ | |||
1 | ### This snippet is not standalone and must be integrated in the global ldap_authorized_keys.sh | ||
2 | LDAP_GITOLITE_MEMBER="@gitolite_ldap_group@" | ||
3 | GITOLITE_SHELL="@gitolite_shell_path@" | ||
4 | |||
5 | if [[ $user == gitolite ]]; then | ||
6 | allowed_logins=$(LDAP_BASE=$USER_LDAP_BASE \ | ||
7 | ldap_search '(memberOf='$LDAP_GITOLITE_MEMBER')' '' \ | ||
8 | | grep ^dn \ | ||
9 | | sed -e "s/^dn: uid=\([^,]*\),.*$USER_LDAP_BASE$/'\1'/" \ | ||
10 | | paste -sd,) | ||
11 | |||
12 | psql_search "SELECT login, key FROM ldap_users_ssh_keys WHERE realm = 'immae' AND 'git' = ANY(usage) AND login IN ($allowed_logins);" | while IFS='|' read user key; do | ||
13 | if [[ $user == "immae" ]] || [[ $user == "denise" ]]; then | ||
14 | # Capitalize first letter (backward compatibility) | ||
15 | user=$(sed -r 's/^([a-z])/\U\1/' <<< "$user") | ||
16 | fi | ||
17 | if [ ! -z "$key" ]; then | ||
18 | if [[ $key != *$'\n'* ]] && [[ $key == ssh-* ]]; then | ||
19 | echo -n 'command="'$GITOLITE_SHELL' '$user'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ' | ||
20 | echo $key | ||
21 | fi | ||
22 | fi | ||
23 | done | ||
24 | cat <<EOF | ||
25 | @gitolite_services@ | ||
26 | EOF | ||
27 | exit 0 | ||
28 | fi | ||