Initial commit: GitLab repository delivery middleware

HTTP service that fetches GitLab repository archives for configured
customers, merges them into a single tarball, and returns an encrypted
payload. Includes Nix flake for reproducible builds.
This commit is contained in:
illustris
2026-02-15 17:03:34 +05:30
commit f9b48fb6f0
12 changed files with 502 additions and 0 deletions

95
src/config.go Normal file
View File

@@ -0,0 +1,95 @@
package main
import (
"encoding/hex"
"fmt"
"os"
"github.com/BurntSushi/toml"
)
type rawConfig struct {
Schema string `toml:"schema"`
Config struct {
GitLabURL string `toml:"gitlab_url"`
GitLabAPIKey string `toml:"gitlab_api_key"`
} `toml:"config"`
Customers map[string]rawCustomer `toml:"customers"`
}
type rawCustomer struct {
Key string `toml:"key"`
Repos []string `toml:"repos"`
}
type ResolvedConfig struct {
GitLabURL string
GitLabAPIKey string
Customers map[string]ResolvedCustomer
}
type ResolvedCustomer struct {
Key []byte
Repos []string
}
func LoadConfig(path string) (*ResolvedConfig, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("reading config: %w", err)
}
expanded := os.Expand(string(data), os.Getenv)
var raw rawConfig
if err := toml.Unmarshal([]byte(expanded), &raw); err != nil {
return nil, fmt.Errorf("parsing config: %w", err)
}
if err := validateRawConfig(&raw); err != nil {
return nil, err
}
resolved := &ResolvedConfig{
GitLabURL: raw.Config.GitLabURL,
GitLabAPIKey: raw.Config.GitLabAPIKey,
Customers: make(map[string]ResolvedCustomer, len(raw.Customers)),
}
for name, cust := range raw.Customers {
key, err := hex.DecodeString(cust.Key)
if err != nil {
return nil, fmt.Errorf("customer %q: invalid hex key: %w", name, err)
}
resolved.Customers[name] = ResolvedCustomer{
Key: key,
Repos: cust.Repos,
}
}
return resolved, nil
}
func validateRawConfig(raw *rawConfig) error {
if raw.Schema != "v1" {
return fmt.Errorf("unsupported schema: %q (expected \"v1\")", raw.Schema)
}
if raw.Config.GitLabURL == "" {
return fmt.Errorf("config.gitlab_url is required")
}
if raw.Config.GitLabAPIKey == "" {
return fmt.Errorf("config.gitlab_api_key is required")
}
if len(raw.Customers) == 0 {
return fmt.Errorf("at least one customer is required")
}
for name, cust := range raw.Customers {
if len(cust.Key) != 64 {
return fmt.Errorf("customer %q: key must be 64 hex characters (got %d)", name, len(cust.Key))
}
if len(cust.Repos) == 0 {
return fmt.Errorf("customer %q: repos list must not be empty", name)
}
}
return nil
}