Major refactoring
This commit is contained in:
10
Makefile
10
Makefile
@@ -1,4 +1,4 @@
|
||||
VERSION := 1.0.0-beta
|
||||
VERSION := 1.0.1-beta
|
||||
BUILD := $(shell git rev-parse --short HEAD)
|
||||
|
||||
GO := go
|
||||
@@ -6,7 +6,13 @@ GO := go
|
||||
BUILD_FLAGS := -buildmode=pie -trimpath
|
||||
LDFLAGS := -linkmode=external -extldflags="-Wl,-z,relro,-z,now" -X git.nevets.tech/Keys/CertManager/internal.Version=$(VERSION) -X git.nevets.tech/Keys/CertManager/internal.Build=$(BUILD)
|
||||
|
||||
build:
|
||||
.PHONY: proto build stage
|
||||
|
||||
proto:
|
||||
@protoc --go_out=./proto --go-grpc_out=./proto proto/hook.proto
|
||||
@protoc --go_out=./proto --go-grpc_out=./proto proto/symlink.proto
|
||||
|
||||
build: proto
|
||||
$(GO) build $(BUILD_FLAGS) -ldflags="$(LDFLAGS)" -o ./certman .
|
||||
@cp ./certman ./certman-$(VERSION)-amd64
|
||||
|
||||
|
||||
15
certman-exec.service
Normal file
15
certman-exec.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=CertMan Executor daemon
|
||||
Requires=certman.socket
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/certman executor
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
certman.socket
Normal file
12
certman.socket
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=certman hook daemon socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/certman.sock
|
||||
SocketUser=root
|
||||
SocketGroup=certsock
|
||||
SocketMode=0660
|
||||
RemoveOnStop=true
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
@@ -135,7 +135,7 @@ func Tick() {
|
||||
|
||||
keyLinks := domainConfig.GetStringSlice("Certificates.key_symlinks")
|
||||
for _, keyLink := range keyLinks {
|
||||
err = internal.LinkFile(filepath.Join(certsDir, domainStr+".crt"), keyLink, domainStr, ".key")
|
||||
err = internal.LinkFile(filepath.Join(certsDir, domainStr+".key"), keyLink, domainStr, ".key")
|
||||
if err != nil {
|
||||
fmt.Printf("Error linking cert %s to %s: %v\n", keyLink, domainStr, err)
|
||||
continue
|
||||
|
||||
57
client/grpc.go
Normal file
57
client/grpc.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.nevets.tech/Keys/CertManager/internal"
|
||||
pb "git.nevets.tech/Keys/CertManager/proto/v1"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
var (
|
||||
tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
|
||||
caFile = flag.String("ca_file", "", "The file containing the CA root cert file")
|
||||
serverAddr = flag.String("addr", "localhost:50051", "The server address in the format of host:port")
|
||||
serverHostOverride = flag.String("server_host_override", "x.test.example.com", "The server name used to verify the hostname returned by the TLS handshake")
|
||||
)
|
||||
|
||||
func SendHook(domain string) {
|
||||
conn, err := grpc.NewClient(
|
||||
"unix:///run/certman.sock",
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("fail to dial: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
client := pb.NewHookServiceClient(conn)
|
||||
|
||||
hooks, err := internal.PostPullHooks(domain)
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting hooks: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, hook := range hooks {
|
||||
sendHook(client, hook)
|
||||
}
|
||||
}
|
||||
|
||||
func sendHook(client pb.HookServiceClient, hook *pb.Hook) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
res, err := client.ExecuteHook(ctx, &pb.ExecuteHookRequest{Hook: hook})
|
||||
if err != nil {
|
||||
fmt.Printf("Error executing hook: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if res.GetError() != "" {
|
||||
fmt.Printf("Error executing hook: %s\n", res.GetError())
|
||||
}
|
||||
}
|
||||
27
commands/executor.go
Normal file
27
commands/executor.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"git.nevets.tech/Keys/CertManager/executor"
|
||||
)
|
||||
|
||||
var executorServer *executor.Server
|
||||
|
||||
func StartExecutorCmd() error {
|
||||
executorServer = &executor.Server{}
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigCh
|
||||
executorServer.Stop()
|
||||
}()
|
||||
if err := executorServer.Start(); err != nil {
|
||||
return fmt.Errorf("failed to start executor server: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -13,8 +13,13 @@ import (
|
||||
|
||||
func NewDomainCmd(domain, domainDir string, dirOverridden bool) error {
|
||||
//TODO add config option for "overriden dir"
|
||||
err := internal.LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Creating new domain %s\n", domain)
|
||||
err := internal.CreateDomainConfig(domain)
|
||||
err = internal.CreateDomainConfig(domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -54,6 +59,11 @@ func InstallCmd(isThin bool, mode string) error {
|
||||
internal.MakeDirs()
|
||||
internal.CreateConfig(mode)
|
||||
|
||||
err := internal.LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.OpenFile("/var/run/certman.pid", os.O_RDONLY|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating pid file: %v", err)
|
||||
@@ -65,7 +75,15 @@ func InstallCmd(isThin bool, mode string) error {
|
||||
|
||||
newUserCmd := exec.Command("useradd", "-d", "/var/local/certman", "-U", "-r", "-s", "/sbin/nologin", "certman")
|
||||
if output, err := newUserCmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("error creating user: %v: output %s", err, output)
|
||||
if !strings.Contains(err.Error(), "exit status 9") {
|
||||
return fmt.Errorf("error creating user: %v: output %s", err, output)
|
||||
}
|
||||
}
|
||||
newGroupCmd := exec.Command("groupadd", "-r", "-U", "certman", "certsock")
|
||||
if output, err := newGroupCmd.CombinedOutput(); err != nil {
|
||||
if !strings.Contains(err.Error(), "exit status 9") {
|
||||
return fmt.Errorf("error creating group: %v: output %s", err, output)
|
||||
}
|
||||
}
|
||||
certmanUser, err := user.Lookup("certman")
|
||||
if err != nil {
|
||||
|
||||
43
executor/executor.go
Normal file
43
executor/executor.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
pb "git.nevets.tech/Keys/CertManager/proto/v1"
|
||||
"github.com/coreos/go-systemd/v22/activation"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
listener net.Listener
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
listeners, err := activation.Listeners()
|
||||
if err != nil {
|
||||
return fmt.Errorf("systemd activation listeners: %v", err)
|
||||
}
|
||||
if len(listeners) != 1 {
|
||||
return fmt.Errorf("systemd activation listeners: expected 1, got %d", len(listeners))
|
||||
}
|
||||
|
||||
s.listener = listeners[0]
|
||||
srv := grpc.NewServer()
|
||||
pb.RegisterHookServiceServer(srv, &hookServer{})
|
||||
|
||||
err = srv.Serve(s.listener)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating grpc listener: %v", err)
|
||||
}
|
||||
fmt.Printf("Started gRPC server on %s\n", s.listener.Addr())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Stop() {
|
||||
if s.listener != nil {
|
||||
_ = s.listener.Close()
|
||||
}
|
||||
}
|
||||
73
executor/hook.go
Normal file
73
executor/hook.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.nevets.tech/Keys/CertManager/internal"
|
||||
pb "git.nevets.tech/Keys/CertManager/proto/v1"
|
||||
)
|
||||
|
||||
type hookServer struct {
|
||||
pb.UnimplementedHookServiceServer
|
||||
}
|
||||
|
||||
func (s *hookServer) ExecuteHook(ctx context.Context, req *pb.ExecuteHookRequest) (*pb.ExecuteHookResponse, error) {
|
||||
h := req.GetHook()
|
||||
if h == nil {
|
||||
return &pb.ExecuteHookResponse{Error: "missing hook"}, nil
|
||||
}
|
||||
|
||||
// Minimal validation
|
||||
if len(h.GetCommand()) == 0 {
|
||||
return &pb.ExecuteHookResponse{Error: "command is empty"}, nil
|
||||
}
|
||||
|
||||
// Timeout
|
||||
timeout := time.Duration(h.GetTimeoutSeconds()) * time.Second
|
||||
if timeout <= 0 {
|
||||
timeout = 30 * time.Second
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
// Build command
|
||||
cmdArgs := h.GetCommand()
|
||||
cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...)
|
||||
if cwd := h.GetCwd(); cwd != "" {
|
||||
cmd.Dir = cwd
|
||||
}
|
||||
|
||||
// Env: inherit current + overlay provided
|
||||
env := os.Environ()
|
||||
for k, v := range h.GetEnv() {
|
||||
env = append(env, k+"="+v)
|
||||
}
|
||||
cmd.Env = env
|
||||
|
||||
// Run as user/group if specified (Linux/Unix)
|
||||
if h.GetUser() != "" || h.GetGroup() != "" {
|
||||
cred, err := internal.MakeCredential(h.GetUser(), h.GetGroup())
|
||||
if err != nil {
|
||||
return &pb.ExecuteHookResponse{Error: brief(err)}, nil
|
||||
}
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Credential: cred,
|
||||
}
|
||||
}
|
||||
|
||||
// We’re intentionally NOT returning stdout/stderr; only a brief error on failure.
|
||||
if err := cmd.Run(); err != nil {
|
||||
// If context deadline hit, make the error message short and explicit.
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
return &pb.ExecuteHookResponse{Error: "hook timed out"}, nil
|
||||
}
|
||||
return &pb.ExecuteHookResponse{Error: brief(err)}, nil
|
||||
}
|
||||
|
||||
return &pb.ExecuteHookResponse{Error: ""}, nil
|
||||
}
|
||||
8
executor/util.go
Normal file
8
executor/util.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package executor
|
||||
|
||||
import "fmt"
|
||||
|
||||
// brief tries to keep errors short and non-leaky.
|
||||
func brief(err error) string {
|
||||
return fmt.Sprintf("hook failed: %v", err)
|
||||
}
|
||||
4
go.mod
4
go.mod
@@ -4,6 +4,7 @@ go 1.25.0
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.23.2
|
||||
github.com/coreos/go-systemd/v22 v22.7.0
|
||||
github.com/go-acme/lego/v4 v4.32.0
|
||||
github.com/go-git/go-billy/v5 v5.8.0
|
||||
github.com/go-git/go-git/v5 v5.17.0
|
||||
@@ -11,6 +12,8 @@ require (
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/viper v1.21.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
google.golang.org/grpc v1.78.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -52,5 +55,6 @@ require (
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/tools v0.42.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
35
go.sum
35
go.sum
@@ -15,8 +15,12 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
||||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
|
||||
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
|
||||
@@ -50,17 +54,18 @@ github.com/go-git/go-git/v5 v5.17.0 h1:AbyI4xf+7DsjINHMu35quAh4wJygKBKBuXVjV/pxe
|
||||
github.com/go-git/go-git/v5 v5.17.0/go.mod h1:f82C4YiLx+Lhi8eHxltLeGC5uBTXSFa6PC5WW9o4SjI=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg=
|
||||
github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA=
|
||||
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
||||
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
||||
@@ -123,6 +128,18 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -163,6 +180,14 @@ golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 h1:Jr5R2J6F6qWyzINc+4AM8t5pfUz6beZpHp678GNrMbE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
pb "git.nevets.tech/Keys/CertManager/proto/v1"
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@@ -186,6 +187,18 @@ func SaveDomainConfigs() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Domain Specific Lookups
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func PostPullHooks(domain string) ([]*pb.Hook, error) {
|
||||
var hooks []*pb.Hook
|
||||
if err := viper.UnmarshalKey("Hooks.PostPull", hooks); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hooks, nil
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Effective lookups (domain → global fallback)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -297,7 +310,7 @@ func CreateDomainConfig(domain string) error {
|
||||
"{domain}", domain,
|
||||
"{key}", key,
|
||||
).Replace(defaultServerDomainConfig)
|
||||
case "Client":
|
||||
case "client":
|
||||
content = strings.NewReplacer(
|
||||
"{domain}", domain,
|
||||
"{key}", key,
|
||||
@@ -393,6 +406,12 @@ crypto_key = '{key}'
|
||||
domain_name = '{domain}'
|
||||
enabled = true
|
||||
|
||||
[Hooks.PostPull]
|
||||
command = []
|
||||
cwd = "/dev/null"
|
||||
timeout_seconds = 30
|
||||
env = { "FOO" = "bar" }
|
||||
|
||||
[Repo]
|
||||
repo_suffix = '-certificates'
|
||||
`
|
||||
|
||||
1
internal/grpc.go
Normal file
1
internal/grpc.go
Normal file
@@ -0,0 +1 @@
|
||||
package internal
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -224,12 +225,12 @@ func LinkFile(source, target, domain, extension string) error {
|
||||
}
|
||||
if linkInfo.IsDir() {
|
||||
target = filepath.Join(target, domain+extension)
|
||||
err = os.Symlink(source, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = os.Symlink(source, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -295,3 +296,64 @@ func ChownRecursive(path string, uid, gid int) error {
|
||||
return os.Chown(name, uid, gid)
|
||||
})
|
||||
}
|
||||
|
||||
func LookupGID(group string) (int, error) {
|
||||
g, err := user.LookupGroup(group)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(g.Gid)
|
||||
}
|
||||
|
||||
// MakeCredential resolves username/groupname to uid/gid for syscall.Credential.
|
||||
// Note: actually *using* different credentials typically requires the server
|
||||
// process to have appropriate privileges (often root).
|
||||
func MakeCredential(username, groupname string) (*syscall.Credential, error) {
|
||||
var uid, gid uint32
|
||||
var haveUID, haveGID bool
|
||||
|
||||
if username != "" {
|
||||
u, err := user.Lookup(username)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unknown user")
|
||||
}
|
||||
parsed, err := strconv.ParseUint(u.Uid, 10, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad uid")
|
||||
}
|
||||
uid = uint32(parsed)
|
||||
haveUID = true
|
||||
|
||||
// If group not explicitly provided, default to user's primary group.
|
||||
if groupname == "" && u.Gid != "" {
|
||||
parsedG, err := strconv.ParseUint(u.Gid, 10, 32)
|
||||
if err == nil {
|
||||
gid = uint32(parsedG)
|
||||
haveGID = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if groupname != "" {
|
||||
g, err := user.LookupGroup(groupname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unknown group")
|
||||
}
|
||||
parsed, err := strconv.ParseUint(g.Gid, 10, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad gid")
|
||||
}
|
||||
gid = uint32(parsed)
|
||||
haveGID = true
|
||||
}
|
||||
|
||||
// If only group was provided, keep current uid.
|
||||
if !haveUID {
|
||||
uid = uint32(os.Getuid())
|
||||
}
|
||||
if !haveGID {
|
||||
gid = uint32(os.Getgid())
|
||||
}
|
||||
|
||||
return &syscall.Credential{Uid: uid, Gid: gid}, nil
|
||||
}
|
||||
|
||||
8
main.go
8
main.go
@@ -99,6 +99,14 @@ func main() {
|
||||
|
||||
rootCmd.AddCommand(certCmd)
|
||||
|
||||
rootCmd.AddCommand(&cobra.Command{
|
||||
Use: "executor",
|
||||
Short: "Privileged daemon",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return commands.StartExecutorCmd()
|
||||
},
|
||||
})
|
||||
|
||||
daemonCmd := &cobra.Command{
|
||||
Use: "daemon",
|
||||
Short: "Daemon management",
|
||||
|
||||
27
proto/hook.proto
Normal file
27
proto/hook.proto
Normal file
@@ -0,0 +1,27 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package hooks.v1;
|
||||
|
||||
option go_package = "/v1";
|
||||
|
||||
service HookService {
|
||||
rpc ExecuteHook(ExecuteHookRequest) returns (ExecuteHookResponse);
|
||||
}
|
||||
|
||||
message Hook {
|
||||
string name = 1;
|
||||
repeated string command = 2;
|
||||
string user = 3;
|
||||
string group = 4;
|
||||
string cwd = 5;
|
||||
int32 timeout_seconds = 6;
|
||||
map<string, string> env = 7;
|
||||
}
|
||||
|
||||
message ExecuteHookRequest {
|
||||
Hook hook = 1;
|
||||
}
|
||||
|
||||
message ExecuteHookResponse {
|
||||
string error = 1;
|
||||
}
|
||||
5
proto/symlink.proto
Normal file
5
proto/symlink.proto
Normal file
@@ -0,0 +1,5 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package hooks.v1;
|
||||
|
||||
option go_package = "/v1";
|
||||
280
proto/v1/hook.pb.go
Normal file
280
proto/v1/hook.pb.go
Normal file
@@ -0,0 +1,280 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.30.2
|
||||
// source: proto/hook.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Hook struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Command []string `protobuf:"bytes,2,rep,name=command,proto3" json:"command,omitempty"`
|
||||
User string `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"`
|
||||
Group string `protobuf:"bytes,4,opt,name=group,proto3" json:"group,omitempty"`
|
||||
Cwd string `protobuf:"bytes,5,opt,name=cwd,proto3" json:"cwd,omitempty"`
|
||||
TimeoutSeconds int32 `protobuf:"varint,6,opt,name=timeout_seconds,json=timeoutSeconds,proto3" json:"timeout_seconds,omitempty"`
|
||||
Env map[string]string `protobuf:"bytes,7,rep,name=env,proto3" json:"env,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Hook) Reset() {
|
||||
*x = Hook{}
|
||||
mi := &file_proto_hook_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Hook) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Hook) ProtoMessage() {}
|
||||
|
||||
func (x *Hook) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_hook_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Hook.ProtoReflect.Descriptor instead.
|
||||
func (*Hook) Descriptor() ([]byte, []int) {
|
||||
return file_proto_hook_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Hook) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Hook) GetCommand() []string {
|
||||
if x != nil {
|
||||
return x.Command
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Hook) GetUser() string {
|
||||
if x != nil {
|
||||
return x.User
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Hook) GetGroup() string {
|
||||
if x != nil {
|
||||
return x.Group
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Hook) GetCwd() string {
|
||||
if x != nil {
|
||||
return x.Cwd
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Hook) GetTimeoutSeconds() int32 {
|
||||
if x != nil {
|
||||
return x.TimeoutSeconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Hook) GetEnv() map[string]string {
|
||||
if x != nil {
|
||||
return x.Env
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExecuteHookRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Hook *Hook `protobuf:"bytes,1,opt,name=hook,proto3" json:"hook,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ExecuteHookRequest) Reset() {
|
||||
*x = ExecuteHookRequest{}
|
||||
mi := &file_proto_hook_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ExecuteHookRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExecuteHookRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExecuteHookRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_hook_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExecuteHookRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExecuteHookRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_hook_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ExecuteHookRequest) GetHook() *Hook {
|
||||
if x != nil {
|
||||
return x.Hook
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExecuteHookResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ExecuteHookResponse) Reset() {
|
||||
*x = ExecuteHookResponse{}
|
||||
mi := &file_proto_hook_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ExecuteHookResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExecuteHookResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExecuteHookResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_hook_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExecuteHookResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ExecuteHookResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_hook_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ExecuteHookResponse) GetError() string {
|
||||
if x != nil {
|
||||
return x.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_proto_hook_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_proto_hook_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x10proto/hook.proto\x12\bhooks.v1\"\xfc\x01\n" +
|
||||
"\x04Hook\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
|
||||
"\acommand\x18\x02 \x03(\tR\acommand\x12\x12\n" +
|
||||
"\x04user\x18\x03 \x01(\tR\x04user\x12\x14\n" +
|
||||
"\x05group\x18\x04 \x01(\tR\x05group\x12\x10\n" +
|
||||
"\x03cwd\x18\x05 \x01(\tR\x03cwd\x12'\n" +
|
||||
"\x0ftimeout_seconds\x18\x06 \x01(\x05R\x0etimeoutSeconds\x12)\n" +
|
||||
"\x03env\x18\a \x03(\v2\x17.hooks.v1.Hook.EnvEntryR\x03env\x1a6\n" +
|
||||
"\bEnvEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"8\n" +
|
||||
"\x12ExecuteHookRequest\x12\"\n" +
|
||||
"\x04hook\x18\x01 \x01(\v2\x0e.hooks.v1.HookR\x04hook\"+\n" +
|
||||
"\x13ExecuteHookResponse\x12\x14\n" +
|
||||
"\x05error\x18\x01 \x01(\tR\x05error2Y\n" +
|
||||
"\vHookService\x12J\n" +
|
||||
"\vExecuteHook\x12\x1c.hooks.v1.ExecuteHookRequest\x1a\x1d.hooks.v1.ExecuteHookResponseB\x05Z\x03/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_proto_hook_proto_rawDescOnce sync.Once
|
||||
file_proto_hook_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_proto_hook_proto_rawDescGZIP() []byte {
|
||||
file_proto_hook_proto_rawDescOnce.Do(func() {
|
||||
file_proto_hook_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_hook_proto_rawDesc), len(file_proto_hook_proto_rawDesc)))
|
||||
})
|
||||
return file_proto_hook_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_hook_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_proto_hook_proto_goTypes = []any{
|
||||
(*Hook)(nil), // 0: hooks.v1.Hook
|
||||
(*ExecuteHookRequest)(nil), // 1: hooks.v1.ExecuteHookRequest
|
||||
(*ExecuteHookResponse)(nil), // 2: hooks.v1.ExecuteHookResponse
|
||||
nil, // 3: hooks.v1.Hook.EnvEntry
|
||||
}
|
||||
var file_proto_hook_proto_depIdxs = []int32{
|
||||
3, // 0: hooks.v1.Hook.env:type_name -> hooks.v1.Hook.EnvEntry
|
||||
0, // 1: hooks.v1.ExecuteHookRequest.hook:type_name -> hooks.v1.Hook
|
||||
1, // 2: hooks.v1.HookService.ExecuteHook:input_type -> hooks.v1.ExecuteHookRequest
|
||||
2, // 3: hooks.v1.HookService.ExecuteHook:output_type -> hooks.v1.ExecuteHookResponse
|
||||
3, // [3:4] is the sub-list for method output_type
|
||||
2, // [2:3] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_hook_proto_init() }
|
||||
func file_proto_hook_proto_init() {
|
||||
if File_proto_hook_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_hook_proto_rawDesc), len(file_proto_hook_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_proto_hook_proto_goTypes,
|
||||
DependencyIndexes: file_proto_hook_proto_depIdxs,
|
||||
MessageInfos: file_proto_hook_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_hook_proto = out.File
|
||||
file_proto_hook_proto_goTypes = nil
|
||||
file_proto_hook_proto_depIdxs = nil
|
||||
}
|
||||
121
proto/v1/hook_grpc.pb.go
Normal file
121
proto/v1/hook_grpc.pb.go
Normal file
@@ -0,0 +1,121 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.0
|
||||
// - protoc v6.30.2
|
||||
// source: proto/hook.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
HookService_ExecuteHook_FullMethodName = "/hooks.v1.HookService/ExecuteHook"
|
||||
)
|
||||
|
||||
// HookServiceClient is the client API for HookService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type HookServiceClient interface {
|
||||
ExecuteHook(ctx context.Context, in *ExecuteHookRequest, opts ...grpc.CallOption) (*ExecuteHookResponse, error)
|
||||
}
|
||||
|
||||
type hookServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewHookServiceClient(cc grpc.ClientConnInterface) HookServiceClient {
|
||||
return &hookServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *hookServiceClient) ExecuteHook(ctx context.Context, in *ExecuteHookRequest, opts ...grpc.CallOption) (*ExecuteHookResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ExecuteHookResponse)
|
||||
err := c.cc.Invoke(ctx, HookService_ExecuteHook_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// HookServiceServer is the server API for HookService service.
|
||||
// All implementations must embed UnimplementedHookServiceServer
|
||||
// for forward compatibility.
|
||||
type HookServiceServer interface {
|
||||
ExecuteHook(context.Context, *ExecuteHookRequest) (*ExecuteHookResponse, error)
|
||||
mustEmbedUnimplementedHookServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedHookServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedHookServiceServer struct{}
|
||||
|
||||
func (UnimplementedHookServiceServer) ExecuteHook(context.Context, *ExecuteHookRequest) (*ExecuteHookResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ExecuteHook not implemented")
|
||||
}
|
||||
func (UnimplementedHookServiceServer) mustEmbedUnimplementedHookServiceServer() {}
|
||||
func (UnimplementedHookServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeHookServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to HookServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeHookServiceServer interface {
|
||||
mustEmbedUnimplementedHookServiceServer()
|
||||
}
|
||||
|
||||
func RegisterHookServiceServer(s grpc.ServiceRegistrar, srv HookServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedHookServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&HookService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _HookService_ExecuteHook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ExecuteHookRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HookServiceServer).ExecuteHook(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HookService_ExecuteHook_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HookServiceServer).ExecuteHook(ctx, req.(*ExecuteHookRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// HookService_ServiceDesc is the grpc.ServiceDesc for HookService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var HookService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "hooks.v1.HookService",
|
||||
HandlerType: (*HookServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ExecuteHook",
|
||||
Handler: _HookService_ExecuteHook_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "proto/hook.proto",
|
||||
}
|
||||
59
proto/v1/symlink.pb.go
Normal file
59
proto/v1/symlink.pb.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.30.2
|
||||
// source: proto/symlink.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
var File_proto_symlink_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_proto_symlink_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x13proto/symlink.proto\x12\bhooks.v1B\x05Z\x03/v1b\x06proto3"
|
||||
|
||||
var file_proto_symlink_proto_goTypes = []any{}
|
||||
var file_proto_symlink_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_symlink_proto_init() }
|
||||
func file_proto_symlink_proto_init() {
|
||||
if File_proto_symlink_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_symlink_proto_rawDesc), len(file_proto_symlink_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_symlink_proto_goTypes,
|
||||
DependencyIndexes: file_proto_symlink_proto_depIdxs,
|
||||
}.Build()
|
||||
File_proto_symlink_proto = out.File
|
||||
file_proto_symlink_proto_goTypes = nil
|
||||
file_proto_symlink_proto_depIdxs = nil
|
||||
}
|
||||
Reference in New Issue
Block a user