From 3643d4a4677db7807b5fa6dee956ab05951a2cd6 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 11 Sep 2022 14:52:21 +0200 Subject: [PATCH 01/10] Added storage --- cmd/kraken/kraken.go | 2 +- go.mod | 6 ++- go.sum | 3 ++ integration_test/main_test.go | 25 ++++++++++ integration_test/storage_test.go | 74 ++++++++++++++++++++++++++++ internal/server/server.go | 1 + internal/server/storage_server.go | 26 ++++++++++ internal/serverdeps/server_deps.go | 22 +++++++-- internal/services/actions/action.go | 2 + internal/services/storage/models.go | 7 +++ internal/services/storage/storage.go | 60 ++++++++++++++++++++++ roadmap.md | 4 +- 12 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 integration_test/main_test.go create mode 100644 integration_test/storage_test.go create mode 100644 internal/server/storage_server.go create mode 100644 internal/services/actions/action.go create mode 100644 internal/services/storage/models.go create mode 100644 internal/services/storage/storage.go diff --git a/cmd/kraken/kraken.go b/cmd/kraken/kraken.go index 56a0b2d..756aaf4 100644 --- a/cmd/kraken/kraken.go +++ b/cmd/kraken/kraken.go @@ -11,7 +11,7 @@ func main() { } func Execute() { - err := commands.CreateServerCmd().Execute() + err := commands.CreateServerCmd(nil).Execute() if err != nil { os.Exit(1) } diff --git a/go.mod b/go.mod index 239b0af..0b2c312 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,13 @@ require ( git.front.kjuulh.io/kjuulh/curre v1.2.2 github.com/gin-gonic/gin v1.8.1 github.com/spf13/cobra v1.5.0 + github.com/stretchr/testify v1.8.0 go.uber.org/zap v1.23.0 + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect @@ -22,14 +25,15 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ugorji/go/codec v1.2.7 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9b28f4b..8460cab 100644 --- a/go.sum +++ b/go.sum @@ -59,11 +59,13 @@ github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= @@ -105,3 +107,4 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/integration_test/main_test.go b/integration_test/main_test.go new file mode 100644 index 0000000..df419b6 --- /dev/null +++ b/integration_test/main_test.go @@ -0,0 +1,25 @@ +//go:build integration +// +build integration + +package integrationtest_test + +import ( + "os" + "testing" + + "git.front.kjuulh.io/kjuulh/kraken/internal/server" + "go.uber.org/zap" +) + +func MainTest(t *testing.M) { + logger, err := zap.NewDevelopment() + if err != nil { + panic(err) + } + err = server.Start(logger) + if err != nil { + panic(err) + } + + os.Exit(t.Run()) +} diff --git a/integration_test/storage_test.go b/integration_test/storage_test.go new file mode 100644 index 0000000..40a7956 --- /dev/null +++ b/integration_test/storage_test.go @@ -0,0 +1,74 @@ +//go:build integration +// +build integration + +package integrationtest_test + +import ( + "context" + "os" + "path" + "testing" + + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "github.com/stretchr/testify/require" +) + +func TestInitializeStorage(t *testing.T) { + t.Parallel() + storage, cfg := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + if _, err := os.Stat(path.Join(cfg.Path, "storage")); os.IsNotExist(err) { + require.NoError(t, err, "could not create storage directory") + } +} + +func TestCleanupStorage(t *testing.T) { + t.Parallel() + storage, _ := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + err = storage.CleanupStorage(context.Background()) + require.NoError(t, err) +} + +func TestCreateArea(t *testing.T) { + t.Parallel() + storage, cfg := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + + area, err := storage.CreateArea(context.Background()) + require.NoError(t, err) + require.NotNil(t, area) + require.NotEmpty(t, area.Path) + require.Contains(t, area.Path, cfg.Path) +} + +func TestRemoveArea(t *testing.T) { + t.Parallel() + storage, _ := prepareService(t) + err := storage.InitializeStorage(context.Background()) + require.NoError(t, err) + area, err := storage.CreateArea(context.Background()) + require.NoError(t, err) + + err = storage.RemoveArea(context.Background(), area) + require.NoError(t, err) + + if _, err := os.Stat(area.Path); os.IsNotExist(err) { + require.Error(t, err, "directory could not be removed") + return + } + t.Fatal("directory could not be removed") +} + +func prepareService(t *testing.T) (*storage.Service, *storage.StorageConfig) { + cfg := &storage.StorageConfig{ + Path: t.TempDir(), + } + + return storage.NewService(cfg), cfg +} diff --git a/internal/server/server.go b/internal/server/server.go index a983253..39fd300 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -15,5 +15,6 @@ func Start(logger *zap.Logger) error { return curre.NewManager(). Register(NewGinHttpServer(deps)). + Register(NewStorageServer(logger.With(zap.String("app", "storageServer")), deps)). Run(ctx) } diff --git a/internal/server/storage_server.go b/internal/server/storage_server.go new file mode 100644 index 0000000..cb79b1f --- /dev/null +++ b/internal/server/storage_server.go @@ -0,0 +1,26 @@ +package server + +import ( + "context" + + "git.front.kjuulh.io/kjuulh/curre" + "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "go.uber.org/zap" +) + +func NewStorageServer(logger *zap.Logger, deps *serverdeps.ServerDeps) curre.Component { + storage := deps.GetStorageService() + return curre.NewFunctionalComponent(&curre.FunctionalComponent{ + InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + logger.Debug("Initializing storage") + return storage.InitializeStorage(ctx) + }, + StartFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + return nil + }, + StopFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + logger.Debug("Cleaning up storage") + return storage.CleanupStorage(ctx) + }, + }) +} diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index 0ca2c40..8673432 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -1,13 +1,29 @@ package serverdeps -import "go.uber.org/zap" +import ( + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "go.uber.org/zap" +) type ServerDeps struct { - logger *zap.Logger + logger *zap.Logger + storageConfig *storage.StorageConfig } func NewServerDeps(logger *zap.Logger) *ServerDeps { - return &ServerDeps{ + deps := &ServerDeps{ logger: logger.With(zap.String("app", "serverdeps")), } + + if storageCfg, err := storage.NewDefaultStorageConfig(); err != nil { + panic(err) + } else { + deps.storageConfig = storageCfg + } + + return deps +} + +func (deps *ServerDeps) GetStorageService() *storage.Service { + return storage.NewService(deps.storageConfig) } diff --git a/internal/services/actions/action.go b/internal/services/actions/action.go new file mode 100644 index 0000000..9d39eb6 --- /dev/null +++ b/internal/services/actions/action.go @@ -0,0 +1,2 @@ +package action + diff --git a/internal/services/storage/models.go b/internal/services/storage/models.go new file mode 100644 index 0000000..eac33dc --- /dev/null +++ b/internal/services/storage/models.go @@ -0,0 +1,7 @@ +package storage + +type ( + Area struct { + Path string + } +) diff --git a/internal/services/storage/storage.go b/internal/services/storage/storage.go new file mode 100644 index 0000000..7ef0ab5 --- /dev/null +++ b/internal/services/storage/storage.go @@ -0,0 +1,60 @@ +package storage + +import ( + "os" + "path" + + "golang.org/x/net/context" +) + +// The idea behind storage is that we have file dir, with a git repo. +// This file repo can now take certain actions + +type StorageConfig struct { + Path string +} + +func NewDefaultStorageConfig() (*StorageConfig, error) { + tempDir, err := os.MkdirTemp(os.TempDir(), "") + if err != nil { + return nil, err + } + return &StorageConfig{ + Path: path.Join(tempDir, "kraken"), + }, nil +} + +type Service struct { + cfg *StorageConfig +} + +func NewService(cfg *StorageConfig) *Service { + return &Service{cfg: cfg} +} + +func (s *Service) getStoragePath(ctx context.Context) string { + return path.Join(s.cfg.Path, "storage") +} + +func (s *Service) InitializeStorage(ctx context.Context) error { + return os.MkdirAll(s.getStoragePath(ctx), 0755) +} + +func (s *Service) CleanupStorage(ctx context.Context) error { + return os.RemoveAll(s.getStoragePath(ctx)) +} + +func (s *Service) CreateArea(ctx context.Context) (*Area, error) { + dir, err := os.MkdirTemp(s.getStoragePath(ctx), "*") + if err != nil { + return nil, err + } + + return &Area{ + Path: dir, + }, nil +} + +func (s *Service) RemoveArea(ctx context.Context, area *Area) error { + return os.RemoveAll(area.Path) +} diff --git a/roadmap.md b/roadmap.md index facf6d7..cc57dcd 100644 --- a/roadmap.md +++ b/roadmap.md @@ -2,7 +2,9 @@ ## POC: -- [ ] Create test action. +- [x] Create storage mechanism +- [ ] Pull repository into storage +- [ ] Create test action to run on repository - [ ] List git repositories on git.front.kjuulh.io. - [ ] Run action on each repo in list (hard-coded) using ssh and gpg. - [ ] Create PR -- 2.45.2 From 226e47e5f4673931d4b791405df0d94bcf7beef8 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 11 Sep 2022 22:56:54 +0200 Subject: [PATCH 02/10] with pull into storage --- cmd/kraken/commands/process.go | 48 ++++++++++ cmd/kraken/commands/root.go | 14 +-- cmd/kraken/kraken.go | 4 +- go.mod | 26 +++++- go.sum | 130 +++++++++++++++++++++++++-- internal/commands/process_repos.go | 86 ++++++++++++++++++ internal/server/http_server.go | 51 ++++++----- internal/server/server.go | 2 +- internal/server/storage_server.go | 6 +- internal/serverdeps/server_deps.go | 17 +++- internal/services/actions/action.go | 4 +- internal/services/jobs/models.go | 4 + internal/services/providers/git.go | 118 ++++++++++++++++++++++++ internal/services/storage/storage.go | 25 +++++- roadmap.md | 3 +- 15 files changed, 485 insertions(+), 53 deletions(-) create mode 100644 cmd/kraken/commands/process.go create mode 100644 internal/commands/process_repos.go create mode 100644 internal/services/jobs/models.go create mode 100644 internal/services/providers/git.go diff --git a/cmd/kraken/commands/process.go b/cmd/kraken/commands/process.go new file mode 100644 index 0000000..1097089 --- /dev/null +++ b/cmd/kraken/commands/process.go @@ -0,0 +1,48 @@ +package commands + +import ( + "bytes" + "encoding/json" + "net/http" + + "github.com/spf13/cobra" +) + +func CreateKrakenProcessCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "process", + Run: func(cmd *cobra.Command, args []string) { + client := http.Client{} + + var buf bytes.Buffer + err := json.NewEncoder(&buf). + Encode(struct { + RepositoryUrls []string `json:"repositoryUrls"` + }{ + RepositoryUrls: []string{"git@git.front.kjuulh.io:kjuulh/kraken.git"}}) + if err != nil { + panic(err) + } + + req, err := http.NewRequestWithContext( + cmd.Context(), + http.MethodPost, + "http://localhost:3000/commands/processRepos", + &buf, + ) + if err != nil { + panic(err) + } + + resp, err := client.Do(req) + if err != nil { + panic(err) + } + if resp.StatusCode >= 300 { + panic(resp.Status) + } + }, + } + + return cmd +} diff --git a/cmd/kraken/commands/root.go b/cmd/kraken/commands/root.go index 315a5c1..5fc73bd 100644 --- a/cmd/kraken/commands/root.go +++ b/cmd/kraken/commands/root.go @@ -4,19 +4,11 @@ import "github.com/spf13/cobra" func CreateKrakenCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "krakenserver", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - // Uncomment the following line if your bare application - // has an action associated with it: + Use: "kraken", // Run: func(cmd *cobra.Command, args []string) { }, } - cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + cmd.AddCommand(CreateKrakenProcessCmd()) return cmd } diff --git a/cmd/kraken/kraken.go b/cmd/kraken/kraken.go index 756aaf4..0da4212 100644 --- a/cmd/kraken/kraken.go +++ b/cmd/kraken/kraken.go @@ -3,7 +3,7 @@ package main import ( "os" - "git.front.kjuulh.io/kjuulh/kraken/cmd/server/commands" + "git.front.kjuulh.io/kjuulh/kraken/cmd/kraken/commands" ) func main() { @@ -11,7 +11,7 @@ func main() { } func Execute() { - err := commands.CreateServerCmd(nil).Execute() + err := commands.CreateKrakenCmd().Execute() if err != nil { os.Exit(1) } diff --git a/go.mod b/go.mod index 0b2c312..0ff6c24 100644 --- a/go.mod +++ b/go.mod @@ -5,35 +5,53 @@ go 1.19 require ( git.front.kjuulh.io/kjuulh/curre v1.2.2 github.com/gin-gonic/gin v1.8.1 + github.com/go-git/go-git v4.7.0+incompatible + github.com/go-git/go-git/v5 v5.4.2 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 go.uber.org/zap v1.23.0 - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 + golang.org/x/net v0.0.0-20220909164309-bea034e7d591 ) require ( + github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.7 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sergi/go-diff v1.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/src-d/gcfg v1.4.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect + github.com/xanzy/ssh-agent v0.3.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect - golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect + golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect + golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/src-d/go-git.v4 v4.13.1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8460cab..5156f58 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,47 @@ git.front.kjuulh.io/kjuulh/curre v1.2.2 h1:0OwWIfekrMykdQg9bdmG80I+Mjc2k4i+sy903phuDWs= git.front.kjuulh.io/kjuulh/curre v1.2.2/go.mod h1:m7WpSehONLqPh/XF3F0BI0UOpLOfGuDmDEFI1XsM6fE= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA= +github.com/go-git/go-git v4.7.0+incompatible/go.mod h1:6+421e08gnZWn30y26Vchf7efgYLe4dl5OQbBSUXShE= +github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= +github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -21,46 +53,81 @@ github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXS github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -69,6 +136,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= +github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -77,21 +148,55 @@ go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI= -golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho= +golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= @@ -99,9 +204,22 @@ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscL google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/commands/process_repos.go b/internal/commands/process_repos.go new file mode 100644 index 0000000..85ed345 --- /dev/null +++ b/internal/commands/process_repos.go @@ -0,0 +1,86 @@ +package commands + +import ( + "context" + "sync" + "time" + + "git.front.kjuulh.io/kjuulh/kraken/internal/services/actions" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/providers" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "go.uber.org/zap" +) + +type ( + ProcessRepos struct { + logger *zap.Logger + storage *storage.Service + git *providers.Git + } + + ProcessReposDeps interface { + GetStorageService() *storage.Service + GetGitProvider() *providers.Git + } +) + +func NewProcessRepos(logger *zap.Logger, deps ProcessReposDeps) *ProcessRepos { + return &ProcessRepos{ + logger: logger, + storage: deps.GetStorageService(), + git: deps.GetGitProvider(), + } +} + +func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string, action *actions.Action) error { + // Clone repos + wg := sync.WaitGroup{} + wg.Add(len(repositoryUrls)) + errChan := make(chan error, 1) + + for _, repoUrl := range repositoryUrls { + go func(ctx context.Context, repoUrl string) { + defer func() { + wg.Done() + }() + pr.logger.Debug("Creating area", zap.String("repoUrl", repoUrl)) + area, err := pr.storage.CreateArea(ctx) + if err != nil { + pr.logger.Error("failed to allocate area", zap.Error(err)) + errChan <- err + return + } + + defer func(ctx context.Context) { + pr.logger.Debug("Removing area", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) + err = pr.storage.RemoveArea(ctx, area) + if err != nil { + errChan <- err + return + } + + }(ctx) + + pr.logger.Debug("Cloning repo", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) + ctx, _ = context.WithTimeout(ctx, time.Second*5) + _, err = pr.git.Clone(ctx, area, repoUrl) + if err != nil { + pr.logger.Error("could not clone repo", zap.Error(err)) + errChan <- err + return + } + + pr.logger.Debug("processing done", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) + }(ctx, repoUrl) + } + + wg.Wait() + close(errChan) + pr.logger.Debug("finished processing all repos") + + for err := range errChan { + return err + } + + return nil +} diff --git a/internal/server/http_server.go b/internal/server/http_server.go index ecd7e46..18f66a6 100644 --- a/internal/server/http_server.go +++ b/internal/server/http_server.go @@ -4,32 +4,18 @@ import ( "context" "errors" "net/http" + "time" "git.front.kjuulh.io/kjuulh/curre" + "git.front.kjuulh.io/kjuulh/kraken/internal/commands" "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/jobs" "github.com/gin-gonic/gin" + "github.com/google/uuid" + "go.uber.org/zap" ) -func NewHttpServer(deps *serverdeps.ServerDeps) curre.Component { - return curre.NewFunctionalComponent(&curre.FunctionalComponent{ - StartFunc: func(_ *curre.FunctionalComponent, _ context.Context) error { - handler := http.NewServeMux() - handler.HandleFunc( - "/health/ready", - func(w http.ResponseWriter, _ *http.Request) { - w.Write([]byte("ready")) - w.WriteHeader(http.StatusOK) - }) - - http.ListenAndServe("127.0.0.1:3000", handler) - - return nil - }, - }, - ) -} - -func NewGinHttpServer(_ *serverdeps.ServerDeps) curre.Component { +func NewGinHttpServer(logger *zap.Logger, deps *serverdeps.ServerDeps) curre.Component { var app *gin.Engine var server *http.Server @@ -45,6 +31,30 @@ func NewGinHttpServer(_ *serverdeps.ServerDeps) curre.Component { }) }) + commandRoute := app.Group("commands") + commandRoute.POST("processRepos", func(c *gin.Context) { + type processReposRequest struct { + RepositoryUrls []string `json:"repositoryUrls"` + } + var request processReposRequest + err := c.BindJSON(&request) + if err != nil { + logger.Info("could not bind request", zap.String("request", "processRepo"), zap.Error(err)) + c.AbortWithStatus(http.StatusBadRequest) + return + } + + jobId := uuid.New().String() + + go func(repositoryUrls []string, jobId string) { + ctx := context.WithValue(context.Background(), jobs.JobId{}, jobId) + processRepos := commands.NewProcessRepos(logger, deps) + err = processRepos.Process(ctx, repositoryUrls, nil) + }(request.RepositoryUrls, jobId) + + c.Status(http.StatusAccepted) + }) + server = &http.Server{ Addr: "127.0.0.1:3000", Handler: app, @@ -62,6 +72,7 @@ func NewGinHttpServer(_ *serverdeps.ServerDeps) curre.Component { return nil }, StopFunc: func(_ *curre.FunctionalComponent, ctx context.Context) error { + ctx, _ = context.WithTimeout(ctx, time.Second*10) if server != nil { server.Shutdown(ctx) } diff --git a/internal/server/server.go b/internal/server/server.go index 39fd300..e968028 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -14,7 +14,7 @@ func Start(logger *zap.Logger) error { deps := serverdeps.NewServerDeps(logger) return curre.NewManager(). - Register(NewGinHttpServer(deps)). + Register(NewGinHttpServer(logger.With(zap.String("app", "ginHttpServer")), deps)). Register(NewStorageServer(logger.With(zap.String("app", "storageServer")), deps)). Run(ctx) } diff --git a/internal/server/storage_server.go b/internal/server/storage_server.go index cb79b1f..5be0a36 100644 --- a/internal/server/storage_server.go +++ b/internal/server/storage_server.go @@ -2,6 +2,7 @@ package server import ( "context" + "time" "git.front.kjuulh.io/kjuulh/curre" "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" @@ -11,15 +12,16 @@ import ( func NewStorageServer(logger *zap.Logger, deps *serverdeps.ServerDeps) curre.Component { storage := deps.GetStorageService() return curre.NewFunctionalComponent(&curre.FunctionalComponent{ - InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + InitFunc: func(_ *curre.FunctionalComponent, ctx context.Context) error { logger.Debug("Initializing storage") return storage.InitializeStorage(ctx) }, StartFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { return nil }, - StopFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + StopFunc: func(_ *curre.FunctionalComponent, ctx context.Context) error { logger.Debug("Cleaning up storage") + ctx, _ = context.WithTimeout(ctx, time.Second*10) return storage.CleanupStorage(ctx) }, }) diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index 8673432..bec910b 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -1,6 +1,7 @@ package serverdeps import ( + "git.front.kjuulh.io/kjuulh/kraken/internal/services/providers" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" "go.uber.org/zap" ) @@ -8,6 +9,7 @@ import ( type ServerDeps struct { logger *zap.Logger storageConfig *storage.StorageConfig + gitCfg *providers.GitConfig } func NewServerDeps(logger *zap.Logger) *ServerDeps { @@ -21,9 +23,22 @@ func NewServerDeps(logger *zap.Logger) *ServerDeps { deps.storageConfig = storageCfg } + deps.gitCfg = &providers.GitConfig{ + AuthOption: providers.GIT_AUTH_SSH, + User: "git", + Password: "", + AccessToken: "", + SshPublicKeyFilePath: "/Users/kah/.ssh/id_ed25519", + SshPrivateKeyPassword: "", + } + return deps } func (deps *ServerDeps) GetStorageService() *storage.Service { - return storage.NewService(deps.storageConfig) + return storage.NewService(deps.logger.With(zap.String("app", "storage")), deps.storageConfig) +} + +func (deps *ServerDeps) GetGitProvider() *providers.Git { + return providers.NewGit(deps.logger.With(zap.String("app", "gitProvider")), deps.gitCfg) } diff --git a/internal/services/actions/action.go b/internal/services/actions/action.go index 9d39eb6..685f838 100644 --- a/internal/services/actions/action.go +++ b/internal/services/actions/action.go @@ -1,2 +1,4 @@ -package action +package actions +type Action struct { +} diff --git a/internal/services/jobs/models.go b/internal/services/jobs/models.go new file mode 100644 index 0000000..1dea285 --- /dev/null +++ b/internal/services/jobs/models.go @@ -0,0 +1,4 @@ +package jobs + +type JobId struct { +} diff --git a/internal/services/providers/git.go b/internal/services/providers/git.go new file mode 100644 index 0000000..02706dc --- /dev/null +++ b/internal/services/providers/git.go @@ -0,0 +1,118 @@ +package providers + +import ( + "context" + + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "go.uber.org/zap" + "go.uber.org/zap/zapio" +) + +// Git is a native git provider, it can clone, pull +// , push and as in abstraction on native git operations +type Git struct { + logger *zap.Logger + gitConfig *GitConfig +} + +type GitRepo struct { + repo *git.Repository +} + +type GitAuth string + +const ( + GIT_AUTH_SSH GitAuth = "ssh" + GIT_AUTH_USERNAME_PASSWORD GitAuth = "username_password" + GIT_AUTH_ACCESS_TOKEN GitAuth = "access_token" + GIT_AUTH_ANONYMOUS GitAuth = "anonymous" + GIT_AUTH_SSH_AGENT GitAuth = "ssh_agent" +) + +type GitConfig struct { + AuthOption GitAuth + User string + Password string + AccessToken string + SshPublicKeyFilePath string + SshPrivateKeyPassword string +} + +func NewGit(logger *zap.Logger, gitConfig *GitConfig) *Git { + return &Git{logger: logger, gitConfig: gitConfig} +} + +func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl string) (*GitRepo, error) { + g.logger.Debug( + "cloning repository", + zap.String("repoUrl", repoUrl), + zap.String("path", storageArea.Path), + ) + + auth, err := g.GetAuth() + if err != nil { + return nil, err + } + + cloneOptions := git.CloneOptions{ + URL: repoUrl, + Auth: auth, + RemoteName: "origin", + ReferenceName: "refs/heads/main", + SingleBranch: true, + NoCheckout: false, + Depth: 1, + RecurseSubmodules: 1, + Progress: &zapio.Writer{ + Log: g.logger.With(zap.String("process", "go-git")), + Level: zap.DebugLevel, + }, + Tags: 0, + InsecureSkipTLS: false, + CABundle: []byte{}, + } + + repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions) + if err != nil { + return nil, err + } + + g.logger.Debug("done cloning repo") + + return &GitRepo{repo: repo}, nil +} + +func (g *Git) GetAuth() (transport.AuthMethod, error) { + switch g.gitConfig.AuthOption { + case GIT_AUTH_SSH: + sshKey, err := ssh.NewPublicKeysFromFile( + g.gitConfig.User, + g.gitConfig.SshPublicKeyFilePath, + g.gitConfig.SshPrivateKeyPassword, + ) + if err != nil { + return nil, err + } + return sshKey, nil + case GIT_AUTH_USERNAME_PASSWORD: + return &http.BasicAuth{ + Username: g.gitConfig.User, + Password: g.gitConfig.Password, + }, nil + case GIT_AUTH_ACCESS_TOKEN: + return &http.BasicAuth{ + Username: "required-username", + Password: g.gitConfig.AccessToken, + }, nil + case GIT_AUTH_ANONYMOUS: + return nil, nil + case GIT_AUTH_SSH_AGENT: + return ssh.NewSSHAgentAuth(g.gitConfig.User) + default: + return nil, nil + } +} diff --git a/internal/services/storage/storage.go b/internal/services/storage/storage.go index 7ef0ab5..01a2625 100644 --- a/internal/services/storage/storage.go +++ b/internal/services/storage/storage.go @@ -1,9 +1,11 @@ package storage import ( + "errors" "os" "path" + "go.uber.org/zap" "golang.org/x/net/context" ) @@ -25,11 +27,12 @@ func NewDefaultStorageConfig() (*StorageConfig, error) { } type Service struct { - cfg *StorageConfig + logger *zap.Logger + cfg *StorageConfig } -func NewService(cfg *StorageConfig) *Service { - return &Service{cfg: cfg} +func NewService(logger *zap.Logger, cfg *StorageConfig) *Service { + return &Service{logger: logger, cfg: cfg} } func (s *Service) getStoragePath(ctx context.Context) string { @@ -41,7 +44,21 @@ func (s *Service) InitializeStorage(ctx context.Context) error { } func (s *Service) CleanupStorage(ctx context.Context) error { - return os.RemoveAll(s.getStoragePath(ctx)) + doneRemovingChan := make(chan struct{}, 1) + go func(ctx context.Context) { + s.logger.Debug("Removing all temp storage") + os.RemoveAll(s.getStoragePath(ctx)) + doneRemovingChan <- struct{}{} + }(ctx) + + select { + case <-ctx.Done(): + return errors.New("could not cleanup storage aborting") + case <-doneRemovingChan: + return nil + } + + return nil } func (s *Service) CreateArea(ctx context.Context) (*Area, error) { diff --git a/roadmap.md b/roadmap.md index cc57dcd..f24be08 100644 --- a/roadmap.md +++ b/roadmap.md @@ -2,8 +2,9 @@ ## POC: +- [ ] Add cuddle - [x] Create storage mechanism -- [ ] Pull repository into storage +- [x] Pull repository into storage - [ ] Create test action to run on repository - [ ] List git repositories on git.front.kjuulh.io. - [ ] Run action on each repo in list (hard-coded) using ssh and gpg. -- 2.45.2 From 3f443f52fd4183531abaf4dac01ecf19581906e5 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 11 Sep 2022 22:57:37 +0200 Subject: [PATCH 03/10] with pr --- roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roadmap.md b/roadmap.md index f24be08..1c5501a 100644 --- a/roadmap.md +++ b/roadmap.md @@ -8,7 +8,7 @@ - [ ] Create test action to run on repository - [ ] List git repositories on git.front.kjuulh.io. - [ ] Run action on each repo in list (hard-coded) using ssh and gpg. -- [ ] Create PR +- [x] Create PR ### Not in scope -- 2.45.2 From f78d84dc8f89097fe52ada61562627796c773b47 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 09:52:44 +0200 Subject: [PATCH 04/10] gin logging --- go.mod | 6 +-- go.sum | 60 +++++++++++++++++------------ internal/api/health.go | 16 ++++++++ internal/api/process_command.go | 39 +++++++++++++++++++ internal/api/root.go | 12 ++++++ internal/commands/process_repos.go | 27 +++++++++++-- internal/server/http_server.go | 40 +++---------------- internal/server/server.go | 4 +- internal/serverdeps/server_deps.go | 11 ++++-- internal/services/actions/action.go | 39 +++++++++++++++++++ 10 files changed, 183 insertions(+), 71 deletions(-) create mode 100644 internal/api/health.go create mode 100644 internal/api/process_command.go create mode 100644 internal/api/root.go diff --git a/go.mod b/go.mod index 0ff6c24..f1d8882 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.19 require ( git.front.kjuulh.io/kjuulh/curre v1.2.2 github.com/gin-gonic/gin v1.8.1 - github.com/go-git/go-git v4.7.0+incompatible github.com/go-git/go-git/v5 v5.4.2 + github.com/google/uuid v1.3.0 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 go.uber.org/zap v1.23.0 @@ -20,13 +20,13 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/zap v0.0.2 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.7 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect @@ -41,7 +41,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/src-d/gcfg v1.4.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect github.com/xanzy/ssh-agent v0.3.2 // indirect go.uber.org/atomic v1.10.0 // indirect @@ -50,7 +49,6 @@ require ( golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/src-d/go-git.v4 v4.13.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 5156f58..f5d26a9 100644 --- a/go.sum +++ b/go.sum @@ -8,15 +8,13 @@ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C6 github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -27,6 +25,9 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/zap v0.0.2 h1:VnIucI+kUsxgzmcrX0gMk19a2I12KirTxi+ufuT2xZk= +github.com/gin-contrib/zap v0.0.2/go.mod h1:2vZj8gTuOYOfottCirxZr9gNM/Q1yk2iSVn15SUVG5A= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= @@ -36,22 +37,24 @@ github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4u github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA= -github.com/go-git/go-git v4.7.0+incompatible/go.mod h1:6+421e08gnZWn30y26Vchf7efgYLe4dl5OQbBSUXShE= github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= @@ -65,11 +68,10 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= @@ -79,24 +81,25 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -109,7 +112,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -119,11 +121,8 @@ github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= -github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -133,54 +132,65 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -196,9 +206,14 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= @@ -209,16 +224,11 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= -gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= -gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= -gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= -gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/internal/api/health.go b/internal/api/health.go new file mode 100644 index 0000000..3373220 --- /dev/null +++ b/internal/api/health.go @@ -0,0 +1,16 @@ +package api + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func HealthRoute(app *gin.Engine) { + healthRoute := app.Group("/health") + healthRoute.GET("/ready", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "healthy", + }) + }) +} diff --git a/internal/api/process_command.go b/internal/api/process_command.go new file mode 100644 index 0000000..589dd81 --- /dev/null +++ b/internal/api/process_command.go @@ -0,0 +1,39 @@ +package api + +import ( + "context" + "net/http" + + "git.front.kjuulh.io/kjuulh/kraken/internal/commands" + "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/jobs" + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "go.uber.org/zap" +) + +func CommandRoute(logger *zap.Logger, app *gin.Engine, deps *serverdeps.ServerDeps) { + commandRoute := app.Group("commands") + commandRoute.POST("processRepos", func(c *gin.Context) { + type processReposRequest struct { + RepositoryUrls []string `json:"repositoryUrls"` + } + var request processReposRequest + err := c.BindJSON(&request) + if err != nil { + logger.Info("could not bind request", zap.String("request", "processRepo"), zap.Error(err)) + c.AbortWithStatus(http.StatusBadRequest) + return + } + + jobId := uuid.New().String() + + go func(repositoryUrls []string, jobId string) { + ctx := context.WithValue(context.Background(), jobs.JobId{}, jobId) + processRepos := commands.NewProcessRepos(logger, deps) + err = processRepos.Process(ctx, repositoryUrls) + }(request.RepositoryUrls, jobId) + + c.Status(http.StatusAccepted) + }) +} diff --git a/internal/api/root.go b/internal/api/root.go new file mode 100644 index 0000000..7f814ac --- /dev/null +++ b/internal/api/root.go @@ -0,0 +1,12 @@ +package api + +import ( + "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +func BuildApi(logger *zap.Logger, app *gin.Engine, deps *serverdeps.ServerDeps) { + HealthRoute(app) + CommandRoute(logger, app, deps) +} diff --git a/internal/commands/process_repos.go b/internal/commands/process_repos.go index 85ed345..ff868fb 100644 --- a/internal/commands/process_repos.go +++ b/internal/commands/process_repos.go @@ -16,11 +16,13 @@ type ( logger *zap.Logger storage *storage.Service git *providers.Git + action *actions.Action } ProcessReposDeps interface { GetStorageService() *storage.Service GetGitProvider() *providers.Git + GetAction() *actions.Action } ) @@ -29,10 +31,11 @@ func NewProcessRepos(logger *zap.Logger, deps ProcessReposDeps) *ProcessRepos { logger: logger, storage: deps.GetStorageService(), git: deps.GetGitProvider(), + action: deps.GetAction(), } } -func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string, action *actions.Action) error { +func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) error { // Clone repos wg := sync.WaitGroup{} wg.Add(len(repositoryUrls)) @@ -62,14 +65,32 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string, ac }(ctx) pr.logger.Debug("Cloning repo", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) - ctx, _ = context.WithTimeout(ctx, time.Second*5) - _, err = pr.git.Clone(ctx, area, repoUrl) + cloneCtx, _ := context.WithTimeout(ctx, time.Second*5) + _, err = pr.git.Clone(cloneCtx, area, repoUrl) if err != nil { pr.logger.Error("could not clone repo", zap.Error(err)) errChan <- err return } + err = pr.action.Run( + ctx, + area, + func(ctx context.Context, area *storage.Area) (bool, error) { + pr.logger.Debug("checking predicate", zap.String("area", area.Path)) + return true, nil + }, + func(ctx context.Context, area *storage.Area) error { + pr.logger.Debug("running action", zap.String("area", area.Path)) + return nil + }, false) + + if err != nil { + pr.logger.Error("could not run action", zap.Error(err)) + errChan <- err + return + } + pr.logger.Debug("processing done", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) }(ctx, repoUrl) } diff --git a/internal/server/http_server.go b/internal/server/http_server.go index 18f66a6..3daa290 100644 --- a/internal/server/http_server.go +++ b/internal/server/http_server.go @@ -7,11 +7,10 @@ import ( "time" "git.front.kjuulh.io/kjuulh/curre" - "git.front.kjuulh.io/kjuulh/kraken/internal/commands" + "git.front.kjuulh.io/kjuulh/kraken/internal/api" "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" - "git.front.kjuulh.io/kjuulh/kraken/internal/services/jobs" + ginzap "github.com/gin-contrib/zap" "github.com/gin-gonic/gin" - "github.com/google/uuid" "go.uber.org/zap" ) @@ -21,39 +20,12 @@ func NewGinHttpServer(logger *zap.Logger, deps *serverdeps.ServerDeps) curre.Com return curre.NewFunctionalComponent(&curre.FunctionalComponent{ InitFunc: func(_ *curre.FunctionalComponent, _ context.Context) error { - app = gin.Default() + app = gin.New() app.UseH2C = true + app.Use(ginzap.Ginzap(logger, time.RFC3339, true)) + app.Use(ginzap.RecoveryWithZap(logger, true)) - healthRoute := app.Group("/health") - healthRoute.GET("/ready", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "message": "healthy", - }) - }) - - commandRoute := app.Group("commands") - commandRoute.POST("processRepos", func(c *gin.Context) { - type processReposRequest struct { - RepositoryUrls []string `json:"repositoryUrls"` - } - var request processReposRequest - err := c.BindJSON(&request) - if err != nil { - logger.Info("could not bind request", zap.String("request", "processRepo"), zap.Error(err)) - c.AbortWithStatus(http.StatusBadRequest) - return - } - - jobId := uuid.New().String() - - go func(repositoryUrls []string, jobId string) { - ctx := context.WithValue(context.Background(), jobs.JobId{}, jobId) - processRepos := commands.NewProcessRepos(logger, deps) - err = processRepos.Process(ctx, repositoryUrls, nil) - }(request.RepositoryUrls, jobId) - - c.Status(http.StatusAccepted) - }) + api.BuildApi(logger, app, deps) server = &http.Server{ Addr: "127.0.0.1:3000", diff --git a/internal/server/server.go b/internal/server/server.go index e968028..f9683ae 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -14,7 +14,7 @@ func Start(logger *zap.Logger) error { deps := serverdeps.NewServerDeps(logger) return curre.NewManager(). - Register(NewGinHttpServer(logger.With(zap.String("app", "ginHttpServer")), deps)). - Register(NewStorageServer(logger.With(zap.String("app", "storageServer")), deps)). + Register(NewGinHttpServer(logger.With(zap.Namespace("ginHttpServer")), deps)). + Register(NewStorageServer(logger.With(zap.Namespace("storageServer")), deps)). Run(ctx) } diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index bec910b..910e404 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -1,6 +1,7 @@ package serverdeps import ( + "git.front.kjuulh.io/kjuulh/kraken/internal/services/actions" "git.front.kjuulh.io/kjuulh/kraken/internal/services/providers" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" "go.uber.org/zap" @@ -14,7 +15,7 @@ type ServerDeps struct { func NewServerDeps(logger *zap.Logger) *ServerDeps { deps := &ServerDeps{ - logger: logger.With(zap.String("app", "serverdeps")), + logger: logger.With(zap.Namespace("serverdeps")), } if storageCfg, err := storage.NewDefaultStorageConfig(); err != nil { @@ -36,9 +37,13 @@ func NewServerDeps(logger *zap.Logger) *ServerDeps { } func (deps *ServerDeps) GetStorageService() *storage.Service { - return storage.NewService(deps.logger.With(zap.String("app", "storage")), deps.storageConfig) + return storage.NewService(deps.logger.With(zap.Namespace("storage")), deps.storageConfig) } func (deps *ServerDeps) GetGitProvider() *providers.Git { - return providers.NewGit(deps.logger.With(zap.String("app", "gitProvider")), deps.gitCfg) + return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg) +} + +func (deps *ServerDeps) GetAction() *actions.Action { + return actions.NewAction(deps.logger.With(zap.Namespace("action"))) } diff --git a/internal/services/actions/action.go b/internal/services/actions/action.go index 685f838..5262569 100644 --- a/internal/services/actions/action.go +++ b/internal/services/actions/action.go @@ -1,4 +1,43 @@ package actions +import ( + "context" + + "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "go.uber.org/zap" +) + +type Predicate func(ctx context.Context, area *storage.Area) (bool, error) +type ActionFunc func(ctx context.Context, area *storage.Area) error + type Action struct { + logger *zap.Logger +} + +func NewAction(logger *zap.Logger) *Action { + return &Action{logger: logger} +} + +func (a *Action) Run(ctx context.Context, area *storage.Area, predicate Predicate, action ActionFunc, dryrun bool) error { + matches, err := predicate(ctx, area) + if err != nil { + return err + } + + if !matches { + a.logger.Debug("repo doesn't match, skipping", zap.String("path", area.Path)) + return nil + } + + if dryrun { + a.logger.Panic("dryrun selected, but not implemented yet") + return nil + } + + err = action(ctx, area) + if err != nil { + return err + } + + return nil } -- 2.45.2 From 0212ce9df4ee8dae2afe2363effe443510001ffa Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 12:35:10 +0200 Subject: [PATCH 05/10] with commit --- internal/commands/process_repos.go | 40 ++++++++++++++++++++--- internal/services/providers/git.go | 51 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/internal/commands/process_repos.go b/internal/commands/process_repos.go index ff868fb..0e02efc 100644 --- a/internal/commands/process_repos.go +++ b/internal/commands/process_repos.go @@ -2,6 +2,11 @@ package commands import ( "context" + "fmt" + "io/fs" + "os" + "path" + "path/filepath" "sync" "time" @@ -66,7 +71,7 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er pr.logger.Debug("Cloning repo", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) cloneCtx, _ := context.WithTimeout(ctx, time.Second*5) - _, err = pr.git.Clone(cloneCtx, area, repoUrl) + repo, err := pr.git.Clone(cloneCtx, area, repoUrl) if err != nil { pr.logger.Error("could not clone repo", zap.Error(err)) errChan <- err @@ -76,12 +81,39 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er err = pr.action.Run( ctx, area, - func(ctx context.Context, area *storage.Area) (bool, error) { + func(_ context.Context, area *storage.Area) (bool, error) { pr.logger.Debug("checking predicate", zap.String("area", area.Path)) - return true, nil + contains := false + filepath.WalkDir(area.Path, func(path string, d fs.DirEntry, err error) error { + if d.Name() == "roadmap.md" { + contains = true + } + return nil + }) + return contains, nil }, - func(ctx context.Context, area *storage.Area) error { + func(_ context.Context, area *storage.Area) error { pr.logger.Debug("running action", zap.String("area", area.Path)) + readme := path.Join(area.Path, "README.md") + file, err := os.Create(readme) + if err != nil { + return fmt.Errorf("could not create readme: %w", err) + } + _, err = file.WriteString("# Readme") + if err != nil { + return fmt.Errorf("could not write readme: %w", err) + } + + _, err = pr.git.Add(ctx, area, repo) + if err != nil { + return fmt.Errorf("could not add file: %w", err) + } + + _, err = pr.git.Commit(ctx, repo) + if err != nil { + return fmt.Errorf("could not get diff: %w", err) + } + return nil }, false) diff --git a/internal/services/providers/git.go b/internal/services/providers/git.go index 02706dc..48539ca 100644 --- a/internal/services/providers/git.go +++ b/internal/services/providers/git.go @@ -2,9 +2,11 @@ package providers import ( "context" + "time" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/ssh" @@ -86,6 +88,55 @@ func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl stri return &GitRepo{repo: repo}, nil } +func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRepo) (*git.Worktree, error) { + worktree, err := gitRepo.repo.Worktree() + if err != nil { + return nil, err + } + + err = worktree.AddWithOptions(&git.AddOptions{ + All: true, + }) + if err != nil { + return nil, err + } + + status, err := worktree.Status() + if err != nil { + return nil, err + } + + g.logger.Info("git status", zap.String("status", status.String())) + + return worktree, nil +} + +func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error { + worktree, err := gitRepo.repo.Worktree() + if err != nil { + return err + } + + _, err = worktree.Commit("some-commit", &git.CommitOptions{ + All: true, + Author: &object.Signature{ + Name: "kraken", + Email: "kraken@kasperhermansen.com", + When: time.Now(), + }, + Committer: &object.Signature{ + Name: "kraken", + Email: "kraken@kasperhermansen.com", + When: time.Now(), + }, + }) + if err != nil { + return err + } + + return nil +} + func (g *Git) GetAuth() (transport.AuthMethod, error) { switch g.gitConfig.AuthOption { case GIT_AUTH_SSH: -- 2.45.2 From 30db2020e86b91bcbedf88762fa4f2ae044a58b1 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 12:36:00 +0200 Subject: [PATCH 06/10] with test action --- roadmap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roadmap.md b/roadmap.md index 1c5501a..caad636 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,16 +5,16 @@ - [ ] Add cuddle - [x] Create storage mechanism - [x] Pull repository into storage -- [ ] Create test action to run on repository +- [x] Create test action to run on repository - [ ] List git repositories on git.front.kjuulh.io. - [ ] Run action on each repo in list (hard-coded) using ssh and gpg. -- [x] Create PR ### Not in scope - [ ] Pooled runners - [ ] CLI with options - [ ] Server app +- [ ] Git hosting providers ## Version 0.1 -- 2.45.2 From b5aaaa0195aa796a5ca6dacb548442e932cefbd8 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 12:41:57 +0200 Subject: [PATCH 07/10] fix roadmap items --- roadmap.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/roadmap.md b/roadmap.md index caad636..b8cab48 100644 --- a/roadmap.md +++ b/roadmap.md @@ -6,8 +6,7 @@ - [x] Create storage mechanism - [x] Pull repository into storage - [x] Create test action to run on repository -- [ ] List git repositories on git.front.kjuulh.io. -- [ ] Run action on each repo in list (hard-coded) using ssh and gpg. +- [ ] Sign commit using gpg ### Not in scope -- 2.45.2 From 56bfba5c179655ef0360fa30a636af201f0b2105 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 14:38:15 +0200 Subject: [PATCH 08/10] add signing key --- example/testkey.private.pgp | 17 ++++++++ go.mod | 9 ++++- go.sum | 29 ++++++++++++- internal/commands/process_repos.go | 2 +- internal/server/server.go | 2 + internal/serverdeps/server_deps.go | 16 +++++++- internal/services/providers/git.go | 16 +++----- internal/services/signer/openpgp.go | 63 +++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 example/testkey.private.pgp create mode 100644 internal/services/signer/openpgp.go diff --git a/example/testkey.private.pgp b/example/testkey.private.pgp new file mode 100644 index 0000000..b31f2d7 --- /dev/null +++ b/example/testkey.private.pgp @@ -0,0 +1,17 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lIYEYx8kxRYJKwYBBAHaRw8BAQdAwlYhGGWpLSSxZoHUmzvl6iJeZgtfKu/8/cjt +LLQ8Swf+BwMCGPF3fdZbweT7+Y/bMMnelXmhYsTgEk30h+FeXOnGy/ZvJgnqoBed +eRPRO5VDN4xq30D8zp04em8tgPXXS50yXvf7PUIKcx4u0IDteTC/Q7QjS3Jha2Vu +IDxrcmFrZW5Aa2FzcGVyaGVybWFuc2VuLmNvbT6IkwQTFgoAOxYhBKh3AMKI2yc/ +qX90YXHawJCw+EZkBQJjHyTFAhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheA +AAoJEHHawJCw+EZkJMQA/AgeMkam18RasuPcl9kiiFkE2EA2TvO25IieZesbCEf5 +APwLjuXkMNYrPSAGPk0VZY7Eq8hWQd3qh9GHV9vDEUvND5yLBGMfJMUSCisGAQQB +l1UBBQEBB0D4pGbjQW+s2aYO3DZX7M0yyq4JkZ+Wana3v2BuAXXYEwMBCAf+BwMC +7hV7XuPdNrP7q1BylZe5GKz0TP0LSRbVjPgnetTyDqOaWEtdRzc996rBR0WcvUJO +xN7oRR8XNMp1v6Up2LcvUs6XDpJ4f1MBGh3npytF7oh4BBgWCgAgFiEEqHcAwojb +Jz+pf3RhcdrAkLD4RmQFAmMfJMUCGwwACgkQcdrAkLD4RmTvQgEAqGhqQuiZQskW +Zbr27HBpQIukcIOVFle+wNXNyhKTJlkBAKoM/wTrQNIyS2gnGPQ1IE/AtDhMvwsV +hCIzhb/ybLMH +=9Nw9 +-----END PGP PRIVATE KEY BLOCK----- diff --git a/go.mod b/go.mod index f1d8882..cd1b597 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,9 @@ go 1.19 require ( git.front.kjuulh.io/kjuulh/curre v1.2.2 + github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe + github.com/ProtonMail/gopenpgp/v2 v2.4.10 + github.com/gin-contrib/zap v0.0.2 github.com/gin-gonic/gin v1.8.1 github.com/go-git/go-git/v5 v5.4.2 github.com/google/uuid v1.3.0 @@ -15,12 +18,12 @@ require ( require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect + github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f // indirect github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/cloudflare/circl v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-contrib/zap v0.0.2 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-playground/locales v0.14.0 // indirect @@ -38,8 +41,10 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect + github.com/sirupsen/logrus v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ugorji/go/codec v1.2.7 // indirect github.com/xanzy/ssh-agent v0.3.2 // indirect diff --git a/go.sum b/go.sum index f5d26a9..03a8012 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,17 @@ git.front.kjuulh.io/kjuulh/curre v1.2.2 h1:0OwWIfekrMykdQg9bdmG80I+Mjc2k4i+sy903phuDWs= git.front.kjuulh.io/kjuulh/curre v1.2.2/go.mod h1:m7WpSehONLqPh/XF3F0BI0UOpLOfGuDmDEFI1XsM6fE= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe h1:R2HeCk7SG/XpoYZlEeI1v7sId7w2AMWwzOaVqXn45FE= +github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko= +github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4= +github.com/ProtonMail/gopenpgp/v2 v2.4.10 h1:EYgkxzwmQvsa6kxxkgP1AwzkFqKHscF2UINxaSn6rdI= +github.com/ProtonMail/gopenpgp/v2 v2.4.10/go.mod h1:CTRA7/toc/4DxDy5Du4hPDnIZnJvXSeQ8LsRTOUJoyc= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= @@ -14,6 +20,9 @@ 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/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -116,6 +125,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= @@ -154,15 +165,25 @@ go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -178,6 +199,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -194,6 +216,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -207,12 +230,14 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= diff --git a/internal/commands/process_repos.go b/internal/commands/process_repos.go index 0e02efc..f2bcb83 100644 --- a/internal/commands/process_repos.go +++ b/internal/commands/process_repos.go @@ -109,7 +109,7 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er return fmt.Errorf("could not add file: %w", err) } - _, err = pr.git.Commit(ctx, repo) + err = pr.git.Commit(ctx, repo) if err != nil { return fmt.Errorf("could not get diff: %w", err) } diff --git a/internal/server/server.go b/internal/server/server.go index f9683ae..a71cbd7 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -5,6 +5,7 @@ import ( "git.front.kjuulh.io/kjuulh/curre" "git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/signer" "go.uber.org/zap" ) @@ -16,5 +17,6 @@ func Start(logger *zap.Logger) error { return curre.NewManager(). Register(NewGinHttpServer(logger.With(zap.Namespace("ginHttpServer")), deps)). Register(NewStorageServer(logger.With(zap.Namespace("storageServer")), deps)). + Register(signer.NewOpenPGPApp(deps.GetOpenPGP())). Run(ctx) } diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index 910e404..845d482 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -3,14 +3,18 @@ package serverdeps import ( "git.front.kjuulh.io/kjuulh/kraken/internal/services/actions" "git.front.kjuulh.io/kjuulh/kraken/internal/services/providers" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/signer" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" "go.uber.org/zap" ) type ServerDeps struct { - logger *zap.Logger + logger *zap.Logger + storageConfig *storage.StorageConfig gitCfg *providers.GitConfig + + openPGP *signer.OpenPGP } func NewServerDeps(logger *zap.Logger) *ServerDeps { @@ -33,6 +37,12 @@ func NewServerDeps(logger *zap.Logger) *ServerDeps { SshPrivateKeyPassword: "", } + openPGPConfig := &signer.OpenPgpConfig{ + PrivateKeyFilePath: "./examples/private.pgp", + PrivateKeyPassword: "somepassword", + } + deps.openPGP = signer.NewOpenPGP(logger.With(zap.Namespace("openpgp")), openPGPConfig) + return deps } @@ -47,3 +57,7 @@ func (deps *ServerDeps) GetGitProvider() *providers.Git { func (deps *ServerDeps) GetAction() *actions.Action { return actions.NewAction(deps.logger.With(zap.Namespace("action"))) } + +func (deps *ServerDeps) GetOpenPGP() *signer.OpenPGP { + return deps.openPGP +} diff --git a/internal/services/providers/git.go b/internal/services/providers/git.go index 48539ca..f15a64c 100644 --- a/internal/services/providers/git.go +++ b/internal/services/providers/git.go @@ -5,6 +5,7 @@ import ( "time" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" + "github.com/ProtonMail/go-crypto/openpgp" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/transport" @@ -118,17 +119,10 @@ func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error { } _, err = worktree.Commit("some-commit", &git.CommitOptions{ - All: true, - Author: &object.Signature{ - Name: "kraken", - Email: "kraken@kasperhermansen.com", - When: time.Now(), - }, - Committer: &object.Signature{ - Name: "kraken", - Email: "kraken@kasperhermansen.com", - When: time.Now(), - }, + All: true, + Author: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()}, + Committer: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()}, + SignKey: &openpgp.Entity{}, }) if err != nil { return err diff --git a/internal/services/signer/openpgp.go b/internal/services/signer/openpgp.go new file mode 100644 index 0000000..a548c55 --- /dev/null +++ b/internal/services/signer/openpgp.go @@ -0,0 +1,63 @@ +package signer + +import ( + "context" + "os" + + "git.front.kjuulh.io/kjuulh/curre" + "github.com/ProtonMail/gopenpgp/v2/crypto" + "go.uber.org/zap" +) + +type OpenPGP struct { + logger *zap.Logger + PrivateKeyRing *crypto.KeyRing + config *OpenPgpConfig +} + +type OpenPgpConfig struct { + PrivateKeyFilePath string + PrivateKeyPassword string +} + +func NewOpenPGP(logger *zap.Logger, config *OpenPgpConfig) *OpenPGP { + return &OpenPGP{ + logger: logger, + config: config, + } +} + +func NewOpenPGPApp(openPGP *OpenPGP) curre.Component { + return curre.NewFunctionalComponent(&curre.FunctionalComponent{ + InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + + content, err := os.ReadFile(openPGP.config.PrivateKeyFilePath) + if err != nil { + return err + } + privateKeyObj, err := crypto.NewKeyFromArmored(string(content)) + if err != nil { + return err + } + unlockedPrivateKeyRing, err := privateKeyObj.Unlock([]byte(openPGP.config.PrivateKeyPassword)) + if err != nil { + return err + } + privateKeyRing, err := crypto.NewKeyRing(unlockedPrivateKeyRing) + if err != nil { + return err + } + + openPGP.PrivateKeyRing = privateKeyRing + + return nil + }, + StartFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + return nil + }, + StopFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { + return nil + }, + }) + +} -- 2.45.2 From b1094294b598cd5f5076fa6e03bbddc7dc9eeaaf Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 22:05:06 +0200 Subject: [PATCH 09/10] with actual push --- internal/commands/process_repos.go | 15 +++- internal/serverdeps/server_deps.go | 5 +- internal/services/providers/git.go | 121 +++++++++++++++++++++++++--- internal/services/signer/openpgp.go | 58 ++++++++----- 4 files changed, 164 insertions(+), 35 deletions(-) diff --git a/internal/commands/process_repos.go b/internal/commands/process_repos.go index f2bcb83..5ea781c 100644 --- a/internal/commands/process_repos.go +++ b/internal/commands/process_repos.go @@ -78,6 +78,13 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er return } + err = pr.git.CreateBranch(ctx, repo) + if err != nil { + pr.logger.Error("could not create branch", zap.Error(err)) + errChan <- err + return + } + err = pr.action.Run( ctx, area, @@ -116,13 +123,19 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er return nil }, false) - if err != nil { pr.logger.Error("could not run action", zap.Error(err)) errChan <- err return } + err = pr.git.Push(ctx, repo) + if err != nil { + pr.logger.Error("could not push to repo", zap.Error(err)) + errChan <- err + return + } + pr.logger.Debug("processing done", zap.String("path", area.Path), zap.String("repoUrl", repoUrl)) }(ctx, repoUrl) } diff --git a/internal/serverdeps/server_deps.go b/internal/serverdeps/server_deps.go index 845d482..bfa6d39 100644 --- a/internal/serverdeps/server_deps.go +++ b/internal/serverdeps/server_deps.go @@ -38,8 +38,9 @@ func NewServerDeps(logger *zap.Logger) *ServerDeps { } openPGPConfig := &signer.OpenPgpConfig{ - PrivateKeyFilePath: "./examples/private.pgp", + PrivateKeyFilePath: "./example/testkey.private.pgp", PrivateKeyPassword: "somepassword", + PrivateKeyIdentity: "kraken@kasperhermansen.com", } deps.openPGP = signer.NewOpenPGP(logger.With(zap.Namespace("openpgp")), openPGPConfig) @@ -51,7 +52,7 @@ func (deps *ServerDeps) GetStorageService() *storage.Service { } func (deps *ServerDeps) GetGitProvider() *providers.Git { - return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg) + return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg, deps.openPGP) } func (deps *ServerDeps) GetAction() *actions.Action { diff --git a/internal/services/providers/git.go b/internal/services/providers/git.go index f15a64c..f4dee7f 100644 --- a/internal/services/providers/git.go +++ b/internal/services/providers/git.go @@ -2,11 +2,14 @@ package providers import ( "context" + "fmt" "time" + "git.front.kjuulh.io/kjuulh/kraken/internal/services/signer" "git.front.kjuulh.io/kjuulh/kraken/internal/services/storage" - "github.com/ProtonMail/go-crypto/openpgp" "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" @@ -20,6 +23,7 @@ import ( type Git struct { logger *zap.Logger gitConfig *GitConfig + openPGP *signer.OpenPGP } type GitRepo struct { @@ -45,8 +49,8 @@ type GitConfig struct { SshPrivateKeyPassword string } -func NewGit(logger *zap.Logger, gitConfig *GitConfig) *Git { - return &Git{logger: logger, gitConfig: gitConfig} +func NewGit(logger *zap.Logger, gitConfig *GitConfig, openPGP *signer.OpenPGP) *Git { + return &Git{logger: logger, gitConfig: gitConfig, openPGP: openPGP} } func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl string) (*GitRepo, error) { @@ -70,13 +74,10 @@ func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl stri NoCheckout: false, Depth: 1, RecurseSubmodules: 1, - Progress: &zapio.Writer{ - Log: g.logger.With(zap.String("process", "go-git")), - Level: zap.DebugLevel, - }, - Tags: 0, - InsecureSkipTLS: false, - CABundle: []byte{}, + Progress: g.getProgressWriter(), + Tags: 0, + InsecureSkipTLS: false, + CABundle: []byte{}, } repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions) @@ -89,6 +90,13 @@ func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl stri return &GitRepo{repo: repo}, nil } +func (g *Git) getProgressWriter() *zapio.Writer { + return &zapio.Writer{ + Log: g.logger.With(zap.String("process", "go-git")), + Level: zap.DebugLevel, + } +} + func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRepo) (*git.Worktree, error) { worktree, err := gitRepo.repo.Worktree() if err != nil { @@ -107,11 +115,71 @@ func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRe return nil, err } - g.logger.Info("git status", zap.String("status", status.String())) + g.logger.Debug("git status", zap.String("status", status.String())) return worktree, nil } +func (g *Git) CreateBranch(ctx context.Context, gitRepo *GitRepo) error { + worktree, err := gitRepo.repo.Worktree() + if err != nil { + return err + } + + refSpec := plumbing.NewBranchReferenceName("kraken-apply") + err = gitRepo.repo.CreateBranch(&config.Branch{ + Name: "kraken-apply", + Remote: "origin", + Merge: refSpec, + Rebase: "", + }) + if err != nil { + return fmt.Errorf("could not create branch: %w", err) + } + + err = worktree.Checkout(&git.CheckoutOptions{ + Branch: plumbing.ReferenceName(refSpec.String()), + Create: true, + Force: false, + Keep: false, + }) + if err != nil { + return fmt.Errorf("could not checkout branch: %w", err) + } + + remoteRef := plumbing.NewRemoteReferenceName("origin", "kraken-apply") + ref := plumbing.NewSymbolicReference(refSpec, remoteRef) + err = gitRepo.repo.Storer.SetReference(ref) + if err != nil { + return fmt.Errorf("could not set reference: %w", err) + } + + auth, err := g.GetAuth() + if err != nil { + return err + } + + err = worktree.PullContext(ctx, &git.PullOptions{ + RemoteName: "origin", + ReferenceName: "refs/heads/main", + SingleBranch: true, + Depth: 1, + Auth: auth, + RecurseSubmodules: 1, + Progress: g.getProgressWriter(), + Force: true, + InsecureSkipTLS: false, + CABundle: []byte{}, + }) + if err != nil { + return fmt.Errorf("could not pull from origin: %w", err) + } + + g.logger.Debug("done creating branches") + + return nil +} + func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error { worktree, err := gitRepo.repo.Worktree() if err != nil { @@ -122,12 +190,41 @@ func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error { All: true, Author: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()}, Committer: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()}, - SignKey: &openpgp.Entity{}, + SignKey: g.openPGP.SigningKey, }) if err != nil { return err } + g.logger.Debug("done commiting objects") + + return nil +} + +func (g *Git) Push(ctx context.Context, gitRepo *GitRepo) error { + auth, err := g.GetAuth() + if err != nil { + return err + } + + err = gitRepo.repo.PushContext(ctx, &git.PushOptions{ + RemoteName: "origin", + RefSpecs: []config.RefSpec{}, + Auth: auth, + Progress: g.getProgressWriter(), + Prune: false, + Force: false, + InsecureSkipTLS: false, + CABundle: []byte{}, + RequireRemoteRefs: []config.RefSpec{}, + }) + + if err != nil { + return err + } + + g.logger.Debug("done pushing branch") + return nil } diff --git a/internal/services/signer/openpgp.go b/internal/services/signer/openpgp.go index a548c55..0d53fc2 100644 --- a/internal/services/signer/openpgp.go +++ b/internal/services/signer/openpgp.go @@ -2,22 +2,25 @@ package signer import ( "context" + "errors" "os" + "strings" "git.front.kjuulh.io/kjuulh/curre" - "github.com/ProtonMail/gopenpgp/v2/crypto" + "github.com/ProtonMail/go-crypto/openpgp" "go.uber.org/zap" ) type OpenPGP struct { - logger *zap.Logger - PrivateKeyRing *crypto.KeyRing - config *OpenPgpConfig + logger *zap.Logger + SigningKey *openpgp.Entity + config *OpenPgpConfig } type OpenPgpConfig struct { PrivateKeyFilePath string PrivateKeyPassword string + PrivateKeyIdentity string } func NewOpenPGP(logger *zap.Logger, config *OpenPgpConfig) *OpenPGP { @@ -29,26 +32,14 @@ func NewOpenPGP(logger *zap.Logger, config *OpenPgpConfig) *OpenPGP { func NewOpenPGPApp(openPGP *OpenPGP) curre.Component { return curre.NewFunctionalComponent(&curre.FunctionalComponent{ - InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error { - - content, err := os.ReadFile(openPGP.config.PrivateKeyFilePath) - if err != nil { - return err - } - privateKeyObj, err := crypto.NewKeyFromArmored(string(content)) - if err != nil { - return err - } - unlockedPrivateKeyRing, err := privateKeyObj.Unlock([]byte(openPGP.config.PrivateKeyPassword)) - if err != nil { - return err - } - privateKeyRing, err := crypto.NewKeyRing(unlockedPrivateKeyRing) + InitFunc: func(_ *curre.FunctionalComponent, ctx context.Context) error { + keyring, err := buildKeyring(ctx, openPGP) if err != nil { + openPGP.logger.Panic("could not build keyring", zap.Error(err)) return err } - openPGP.PrivateKeyRing = privateKeyRing + openPGP.SigningKey = keyring return nil }, @@ -59,5 +50,32 @@ func NewOpenPGPApp(openPGP *OpenPGP) curre.Component { return nil }, }) +} + +func buildKeyring(_ context.Context, openPGP *OpenPGP) (*openpgp.Entity, error) { + content, err := os.ReadFile(openPGP.config.PrivateKeyFilePath) + if err != nil { + return nil, err + } + reader := strings.NewReader(string(content)) + + es, err := openpgp.ReadArmoredKeyRing(reader) + if err != nil { + return nil, err + } + + for _, key := range es { + for k := range key.Identities { + if strings.Contains(k, openPGP.config.PrivateKeyIdentity) { + err = key.PrivateKey.Decrypt([]byte(openPGP.config.PrivateKeyPassword)) + if err != nil { + return nil, err + } + return key, nil + } + } + } + + return nil, errors.New("could not find key matching identity") } -- 2.45.2 From 1fd031871101bc7fb4a7eb8d8dd302e1f2770de3 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 12 Sep 2022 22:06:39 +0200 Subject: [PATCH 10/10] Added roadmap item --- roadmap.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/roadmap.md b/roadmap.md index b8cab48..f072ef5 100644 --- a/roadmap.md +++ b/roadmap.md @@ -6,7 +6,8 @@ - [x] Create storage mechanism - [x] Pull repository into storage - [x] Create test action to run on repository -- [ ] Sign commit using gpg +- [x] Sign commit using gpg +- [x] Push commits to branch ### Not in scope -- 2.45.2