refactor: more implementation to refactor and deleted files
This commit is contained in:
parent
ba684bd149
commit
50e6b53091
17 changed files with 84 additions and 945 deletions
|
|
@ -1,23 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/generator"
|
||||
)
|
||||
|
||||
type TestGenerator struct{}
|
||||
|
||||
func (g *TestGenerator) GetName() string { return "test" }
|
||||
func (g *TestGenerator) GetVersion() string { return "v1.0.0" }
|
||||
func (g *TestGenerator) GetDescription() string {
|
||||
return "This is a plugin creating for running tests."
|
||||
}
|
||||
func (g *TestGenerator) Generate(config *config.Config, params generator.Params) (generator.FileMap, error) {
|
||||
return generator.ApplyTemplates(generator.Mappings{
|
||||
"plugin_name": g.GetName(),
|
||||
"plugin_version": g.GetVersion(),
|
||||
"plugin_description": g.GetDescription(),
|
||||
}, params.Templates)
|
||||
}
|
||||
|
||||
var Generator TestGenerator
|
||||
21
go.mod
21
go.mod
|
|
@ -4,39 +4,28 @@ go 1.21.5
|
|||
|
||||
require (
|
||||
github.com/OpenCHAMI/jwtauth/v5 v5.0.0-20240321222802-e6cb468a2a18
|
||||
github.com/go-chi/chi v1.5.5
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
github.com/lestrrat-go/jwx/v2 v2.1.1
|
||||
github.com/nikolalohinski/gonja/v2 v2.2.0
|
||||
github.com/openchami/chi-middleware/auth v0.0.0-20240812224658-b16b83c70700
|
||||
github.com/openchami/chi-middleware/log v0.0.0-20240812224658-b16b83c70700
|
||||
github.com/rodaine/table v1.2.0
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/text v0.1.0 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
github.com/lestrrat-go/httprc v1.0.6 // indirect
|
||||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tidwall/gjson v1.14.2 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
)
|
||||
|
|
|
|||
86
go.sum
86
go.sum
|
|
@ -1,39 +1,19 @@
|
|||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/OpenCHAMI/jwtauth/v5 v5.0.0-20240321222802-e6cb468a2a18 h1:oBPtXp9RVm9lk5zTmDLf+Vh21yDHpulBxUqGJQjwQCk=
|
||||
github.com/OpenCHAMI/jwtauth/v5 v5.0.0-20240321222802-e6cb468a2a18/go.mod h1:ggNHWgLfW/WRXcE8ZZC4S7UwHif16HVmyowOCWdNSN8=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
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/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
|
||||
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
|
||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
|
||||
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
|
||||
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
|
||||
|
|
@ -46,81 +26,35 @@ github.com/lestrrat-go/jwx/v2 v2.1.1 h1:Y2ltVl8J6izLYFs54BVcpXLv5msSW4o8eXwnzZLI
|
|||
github.com/lestrrat-go/jwx/v2 v2.1.1/go.mod h1:4LvZg7oxu6Q5VJwn7Mk/UwooNRnTHUpXBj2C4j3HNx0=
|
||||
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
|
||||
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/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/nikolalohinski/gonja/v2 v2.2.0 h1:tAs3BDHNjvPj48F2BL5t7iVhN32HhgeldAl3EmdsLh8=
|
||||
github.com/nikolalohinski/gonja/v2 v2.2.0/go.mod h1:l9DuWJvT/BddBr2SsmEimESD6msSqRw7u5HzI2Um+sc=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
|
||||
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
|
||||
github.com/openchami/chi-middleware/auth v0.0.0-20240812224658-b16b83c70700 h1:XADGipD2FZ9swuFUqeL7h63j3voiq9qA7P0aKsqgZKg=
|
||||
github.com/openchami/chi-middleware/auth v0.0.0-20240812224658-b16b83c70700/go.mod h1:kswb9kU5cZAFRAvf1dAUJRWbQyjDEb0qkxW4ncDdEXg=
|
||||
github.com/openchami/chi-middleware/log v0.0.0-20240812224658-b16b83c70700 h1:Gzt5f6RK39CHvY3SJudzBb/RK4tVh/S3CpJ0eQlbNdg=
|
||||
github.com/openchami/chi-middleware/log v0.0.0-20240812224658-b16b83c70700/go.mod h1:UuXvr2loD4MtvZeKr57W0WpBs+gm0KM1kdtcXrE8M6s=
|
||||
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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA=
|
||||
github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type Conman struct{}
|
||||
|
||||
func (g *Conman) GetName() string {
|
||||
return "conman"
|
||||
}
|
||||
|
||||
func (g *Conman) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Conman) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *Conman) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
var (
|
||||
smdClient = client.NewSmdClient(params.ClientOpts...)
|
||||
eps = []configurator.RedfishEndpoint{}
|
||||
err error = nil
|
||||
consoles = ""
|
||||
)
|
||||
|
||||
// fetch required data from SMD to create config
|
||||
eps, err = smdClient.FetchRedfishEndpoints(params.Verbose)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch redfish endpoints with client: %v", err)
|
||||
}
|
||||
|
||||
// format output to write to config file
|
||||
consoles = "# ========== DYNAMICALLY GENERATED BY OPENCHAMI CONFIGURATOR ==========\n"
|
||||
for _, ep := range eps {
|
||||
consoles += fmt.Sprintf("CONSOLE name=%s dev=ipmi:%s-bmc ipmiopts=U:%s,P:%s,W:solpayloadsize\n", ep.Name, ep.Name, ep.User, ep.Password)
|
||||
}
|
||||
consoles += "# ====================================================================="
|
||||
|
||||
// apply template substitutions and return output as byte array
|
||||
return ApplyTemplates(Mappings{
|
||||
"plugin_name": g.GetName(),
|
||||
"plugin_version": g.GetVersion(),
|
||||
"plugin_description": g.GetDescription(),
|
||||
"server_opts": "",
|
||||
"global_opts": "",
|
||||
"consoles": consoles,
|
||||
}, params.Templates)
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type CoreDhcp struct{}
|
||||
|
||||
func (g *CoreDhcp) GetName() string {
|
||||
return "coredhcp"
|
||||
}
|
||||
|
||||
func (g *CoreDhcp) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *CoreDhcp) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s' to generate config files. (WIP)", g.GetName())
|
||||
}
|
||||
|
||||
func (g *CoreDhcp) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
return nil, fmt.Errorf("plugin does not implement generation function")
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type DHCPd struct{}
|
||||
|
||||
func (g *DHCPd) GetName() string {
|
||||
return "dhcpd"
|
||||
}
|
||||
|
||||
func (g *DHCPd) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *DHCPd) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *DHCPd) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
var (
|
||||
smdClient = client.NewSmdClient(params.ClientOpts...)
|
||||
eths = []configurator.EthernetInterface{}
|
||||
computeNodes = ""
|
||||
err error = nil
|
||||
)
|
||||
|
||||
//
|
||||
eths, err = smdClient.FetchEthernetInterfaces(params.Verbose)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch ethernet interfaces with client: %w", err)
|
||||
}
|
||||
|
||||
// check if we have the required params first
|
||||
if eths == nil {
|
||||
return nil, fmt.Errorf("invalid ethernet interfaces (variable is nil)")
|
||||
}
|
||||
if len(eths) <= 0 {
|
||||
return nil, fmt.Errorf("no ethernet interfaces found")
|
||||
}
|
||||
|
||||
// format output to write to config file
|
||||
computeNodes = "# ========== DYNAMICALLY GENERATED BY OPENCHAMI CONFIGURATOR ==========\n"
|
||||
for _, eth := range eths {
|
||||
if len(eth.IpAddresses) == 0 {
|
||||
continue
|
||||
}
|
||||
computeNodes += fmt.Sprintf("host %s { hardware ethernet %s; fixed-address %s} ", eth.ComponentId, eth.MacAddress, eth.IpAddresses[0])
|
||||
}
|
||||
computeNodes += "# ====================================================================="
|
||||
return ApplyTemplates(Mappings{
|
||||
"plugin_name": g.GetName(),
|
||||
"plugin_version": g.GetVersion(),
|
||||
"plugin_description": g.GetDescription(),
|
||||
"compute_nodes": computeNodes,
|
||||
"node_entries": "",
|
||||
}, params.Templates)
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type DNSMasq struct{}
|
||||
|
||||
func (g *DNSMasq) GetName() string {
|
||||
return "dnsmasq"
|
||||
}
|
||||
|
||||
func (g *DNSMasq) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *DNSMasq) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *DNSMasq) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
// make sure we have a valid config first
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("invalid config (config is nil)")
|
||||
}
|
||||
|
||||
// set all the defaults for variables
|
||||
var (
|
||||
smdClient = client.NewSmdClient(params.ClientOpts...)
|
||||
eths = []configurator.EthernetInterface{}
|
||||
err error = nil
|
||||
)
|
||||
|
||||
// if we have a client, try making the request for the ethernet interfaces
|
||||
eths, err = smdClient.FetchEthernetInterfaces(params.Verbose)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch ethernet interfaces with client: %v", err)
|
||||
}
|
||||
|
||||
// check if we have the required params first
|
||||
if eths == nil {
|
||||
return nil, fmt.Errorf("invalid ethernet interfaces (variable is nil)")
|
||||
}
|
||||
if len(eths) <= 0 {
|
||||
return nil, fmt.Errorf("no ethernet interfaces found")
|
||||
}
|
||||
|
||||
// format output to write to config file
|
||||
output := "# ========== DYNAMICALLY GENERATED BY OPENCHAMI CONFIGURATOR ==========\n"
|
||||
for _, eth := range eths {
|
||||
if eth.Type == "NodeBMC" {
|
||||
output += "dhcp-host=" + eth.MacAddress + "," + eth.ComponentId + "," + eth.IpAddresses[0].IpAddress + "\n"
|
||||
} else {
|
||||
output += "dhcp-host=" + eth.MacAddress + "," + eth.ComponentId + "," + eth.IpAddresses[0].IpAddress + "\n"
|
||||
}
|
||||
}
|
||||
output += "# ====================================================================="
|
||||
|
||||
// apply template substitutions and return output as byte array
|
||||
return ApplyTemplates(Mappings{
|
||||
"plugin_name": g.GetName(),
|
||||
"plugin_version": g.GetVersion(),
|
||||
"plugin_description": g.GetDescription(),
|
||||
"dhcp_hosts": output,
|
||||
}, params.Templates)
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type Example struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (g *Example) GetName() string {
|
||||
return "example"
|
||||
}
|
||||
|
||||
func (g *Example) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Example) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *Example) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
g.Message = `
|
||||
This is an example generator plugin. See the file in 'internal/generator/plugins/example/example.go' on
|
||||
information about constructing plugins and plugin requirements.`
|
||||
return FileMap{"example": []byte(g.Message)}, nil
|
||||
}
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"plugin"
|
||||
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type (
|
||||
Mappings map[string]any
|
||||
FileMap map[string][]byte
|
||||
FileList [][]byte
|
||||
|
||||
// Generator interface used to define how files are created. Plugins can
|
||||
// be created entirely independent of the main driver program.
|
||||
Generator interface {
|
||||
GetName() string
|
||||
GetVersion() string
|
||||
GetDescription() string
|
||||
Generate(config *config.Config, params Params) (FileMap, error)
|
||||
}
|
||||
)
|
||||
|
||||
var DefaultGenerators = createDefaultGenerators()
|
||||
|
||||
func createDefaultGenerators() map[string]Generator {
|
||||
var (
|
||||
generatorMap = map[string]Generator{}
|
||||
generators = []Generator{
|
||||
&Conman{}, &DHCPd{}, &DNSMasq{}, &Warewulf{}, &Example{}, &CoreDhcp{},
|
||||
}
|
||||
)
|
||||
for _, g := range generators {
|
||||
generatorMap[g.GetName()] = g
|
||||
}
|
||||
return generatorMap
|
||||
}
|
||||
|
||||
// Converts the file outputs from map[string][]byte to map[string]string.
|
||||
func ConvertContentsToString(f FileMap) map[string]string {
|
||||
n := make(map[string]string, len(f))
|
||||
for k, v := range f {
|
||||
n[k] = string(v)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Loads files without applying any Jinja 2 templating.
|
||||
func LoadFiles(paths ...string) (FileMap, error) {
|
||||
var outputs = FileMap{}
|
||||
for _, path := range paths {
|
||||
expandedPaths, err := filepath.Glob(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to glob path: %w", err)
|
||||
}
|
||||
for _, expandedPath := range expandedPaths {
|
||||
info, err := os.Stat(expandedPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil, fmt.Errorf("failed to stat file or directory: %w", err)
|
||||
}
|
||||
// skip any directories found
|
||||
if info.IsDir() {
|
||||
continue
|
||||
}
|
||||
b, err := os.ReadFile(expandedPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file: %w", err)
|
||||
}
|
||||
|
||||
outputs[expandedPath] = b
|
||||
}
|
||||
}
|
||||
|
||||
return outputs, nil
|
||||
}
|
||||
|
||||
// Loads a single generator plugin given a single file path.
|
||||
func LoadPlugin(path string) (Generator, error) {
|
||||
// skip loading plugin if path is a directory with no error
|
||||
if isDir, err := util.IsDirectory(path); err == nil && isDir {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, fmt.Errorf("failed to test if plugin path is directory: %w", err)
|
||||
}
|
||||
|
||||
// try and open the plugin
|
||||
p, err := plugin.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open plugin: %w", err)
|
||||
}
|
||||
|
||||
// load the "Generator" symbol from plugin
|
||||
symbol, err := p.Lookup("Generator")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to look up symbol at path '%s': %w", path, err)
|
||||
}
|
||||
|
||||
// assert that the plugin loaded has a valid generator
|
||||
gen, ok := symbol.(Generator)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to load the correct symbol type at path '%s'", path)
|
||||
}
|
||||
return gen, nil
|
||||
}
|
||||
|
||||
// Loads all generator plugins in a given directory.
|
||||
//
|
||||
// Returns a map of generators. Each generator can be accessed by the name
|
||||
// returned by the generator.GetName() implemented.
|
||||
func LoadPlugins(dirpath string, opts ...Option) (map[string]Generator, error) {
|
||||
// check if verbose option is supplied
|
||||
var (
|
||||
generators = make(map[string]Generator)
|
||||
params = ToParams(opts...)
|
||||
)
|
||||
|
||||
//
|
||||
err := filepath.Walk(dirpath, func(path string, info fs.FileInfo, err error) error {
|
||||
// skip trying to load generator plugin if directory or error
|
||||
if info.IsDir() || err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// only try loading if file has .so extension
|
||||
if filepath.Ext(path) != ".so" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// load the generator plugin from current path
|
||||
gen, err := LoadPlugin(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load generator in directory '%s': %w", path, err)
|
||||
}
|
||||
|
||||
// show the plugins found if verbose flag is set
|
||||
if params.Verbose {
|
||||
log.Info().Str("plugin_name", gen.GetName()).Msg("found plugin")
|
||||
}
|
||||
|
||||
// map each generator plugin by name for lookup
|
||||
generators[gen.GetName()] = gen
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to walk directory: %w", err)
|
||||
}
|
||||
|
||||
return generators, nil
|
||||
}
|
||||
|
||||
// Generate() is the main function to generate a collection of files and returns them as a map.
|
||||
// This function only expects a path to a plugin and paths to a collection of templates to
|
||||
// be used. This function will only load the plugin on-demand and fetch resources as needed.
|
||||
//
|
||||
// This function requires that a target and plugin path be set at minimum.
|
||||
func Generate(config *config.Config, plugin string, params Params) (FileMap, error) {
|
||||
var (
|
||||
gen Generator
|
||||
ok bool
|
||||
err error
|
||||
)
|
||||
|
||||
// check if generator is built-in first before loading external plugin
|
||||
log.Debug().Any("generators", DefaultGenerators).Msg("available generators")
|
||||
gen, ok = DefaultGenerators[plugin]
|
||||
if !ok {
|
||||
// only load the plugin needed for this target if we don't find default
|
||||
log.Error().Str("plugin", plugin).Msg("could not find target in default generators")
|
||||
gen, err = LoadPlugin(plugin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load plugin from file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return gen.Generate(config, params)
|
||||
}
|
||||
|
||||
// Main function to generate a collection of files as a map with the path as the key and
|
||||
// the contents of the file as the value. This function currently expects a list of plugin
|
||||
// paths to load all plugins within a directory. Then, each plugin's generator.GenerateWithTarget()
|
||||
// function is called for each target specified.
|
||||
//
|
||||
// This function is the corresponding implementation for the "generate" CLI subcommand.
|
||||
// It is also call when running the configurator as a service with the "/generate" route.
|
||||
//
|
||||
// TODO: Separate loading plugins so we can load them once when running as a service.
|
||||
func GenerateWithTarget(config *config.Config, target string) (FileMap, error) {
|
||||
// load generator plugins to generate configs or to print
|
||||
var (
|
||||
opts []client.Option
|
||||
targetInfo configurator.Target
|
||||
generator Generator
|
||||
params Params
|
||||
err error
|
||||
ok bool
|
||||
)
|
||||
|
||||
// check if a target is supplied
|
||||
if target == "" {
|
||||
return nil, fmt.Errorf("must specify a target")
|
||||
}
|
||||
|
||||
// load target information from config
|
||||
targetInfo, ok = config.Targets[target]
|
||||
if !ok {
|
||||
log.Warn().Str("target", target).Msg("target not found in config")
|
||||
}
|
||||
|
||||
// if no plugin supplied in config target, then using the target supplied
|
||||
if targetInfo.Plugin == "" {
|
||||
targetInfo.Plugin = target
|
||||
}
|
||||
|
||||
// check if generator is built-in first before loading
|
||||
generator, ok = DefaultGenerators[target]
|
||||
if !ok {
|
||||
// only load the plugin needed for this target if we don't find default
|
||||
log.Warn().Str("target", target).Msg("could not find target in default generators")
|
||||
generator, err = LoadPlugin(targetInfo.Plugin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load plugin: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// check if there's at least one template available
|
||||
if len(targetInfo.TemplatePaths) <= 0 {
|
||||
return nil, fmt.Errorf("expects at least one template to be available")
|
||||
}
|
||||
|
||||
// prepare params to pass into generator
|
||||
params.Templates = map[string]Template{}
|
||||
for _, templatePath := range targetInfo.TemplatePaths {
|
||||
template := Template{}
|
||||
template.LoadFromFile(templatePath)
|
||||
params.Templates[templatePath] = template
|
||||
}
|
||||
|
||||
// set the client options
|
||||
if config.AccessToken != "" {
|
||||
params.ClientOpts = append(opts, client.WithAccessToken(config.AccessToken))
|
||||
}
|
||||
if config.CertPath != "" {
|
||||
params.ClientOpts = append(opts, client.WithCertPoolFile(config.CertPath))
|
||||
}
|
||||
|
||||
// load files that are not to be copied
|
||||
params.Files, err = LoadFiles(targetInfo.FilePaths...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load files to copy: %v", err)
|
||||
}
|
||||
|
||||
// run the generator plugin from target passed
|
||||
return generator.Generate(config, params)
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type Hostfile struct{}
|
||||
|
||||
func (g *Hostfile) GetName() string {
|
||||
return "hostfile"
|
||||
}
|
||||
|
||||
func (g *Hostfile) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Hostfile) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *Hostfile) Generate(config *config.Config, opts ...Option) (FileMap, error) {
|
||||
return nil, fmt.Errorf("plugin does not implement generation function")
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
)
|
||||
|
||||
type (
|
||||
// Params used by the generator
|
||||
Params struct {
|
||||
Templates map[string]Template
|
||||
Files map[string][]byte
|
||||
ClientOpts []client.Option
|
||||
Verbose bool
|
||||
}
|
||||
Option func(Params)
|
||||
)
|
||||
|
||||
func ToParams(opts ...Option) Params {
|
||||
params := Params{}
|
||||
for _, opt := range opts {
|
||||
opt(params)
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func WithClientOpts(opts ...client.Option) Option {
|
||||
return func(p Params) {
|
||||
p.ClientOpts = opts
|
||||
}
|
||||
}
|
||||
|
||||
func WithTemplates(templates map[string]Template) Option {
|
||||
return func(p Params) {
|
||||
p.Templates = templates
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to get the target in generator.Generate() plugin implementations.
|
||||
func GetTarget(config *config.Config, key string) configurator.Target {
|
||||
return config.Targets[key]
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type Powerman struct{}
|
||||
|
||||
func (g *Powerman) GetName() string {
|
||||
return "powerman"
|
||||
}
|
||||
|
||||
func (g *Powerman) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Powerman) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *Powerman) Generate(config *config.Config, opts ...Option) (FileMap, error) {
|
||||
return nil, fmt.Errorf("plugin does not implement generation function")
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
)
|
||||
|
||||
type Syslog struct{}
|
||||
|
||||
func (g *Syslog) GetName() string {
|
||||
return "syslog"
|
||||
}
|
||||
|
||||
func (g *Syslog) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Syslog) GetDescription() string {
|
||||
return fmt.Sprintf("Configurator generator plugin for '%s'.", g.GetName())
|
||||
}
|
||||
|
||||
func (g *Syslog) Generate(config *config.Config, opts ...Option) (FileMap, error) {
|
||||
return nil, fmt.Errorf("plugin does not implement generation function")
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
"github.com/nikolalohinski/gonja/v2"
|
||||
"github.com/nikolalohinski/gonja/v2/exec"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type Template struct {
|
||||
Contents []byte `json:"contents"`
|
||||
}
|
||||
|
||||
func (t *Template) LoadFromFile(path string) error {
|
||||
// skip loading template if path is a directory with no error
|
||||
if isDir, err := util.IsDirectory(path); err == nil && isDir {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to test if template path is directory: %w", err)
|
||||
}
|
||||
|
||||
// try and read the contents of the file
|
||||
// NOTE: we don't care if this is actually a Jinja template
|
||||
// or not...at least for now.
|
||||
contents, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read file: %v", err)
|
||||
}
|
||||
t.Contents = contents
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Template) IsEmpty() bool {
|
||||
return len(t.Contents) <= 0
|
||||
}
|
||||
|
||||
// Wrapper function to slightly abstract away some of the nuances with using gonja
|
||||
// into a single function call. This function is *mostly* for convenience and
|
||||
// simplication. If no paths are supplied, then no templates will be applied and
|
||||
// there will be no output.
|
||||
//
|
||||
// The "FileList" returns a slice of byte arrays in the same order as the argument
|
||||
// list supplied, but with the Jinja templating applied.
|
||||
func ApplyTemplates(mappings Mappings, templates map[string]Template) (FileMap, error) {
|
||||
var (
|
||||
data = exec.NewContext(mappings)
|
||||
outputs = FileMap{}
|
||||
)
|
||||
|
||||
for path, template := range templates {
|
||||
// load jinja template from file
|
||||
t, err := gonja.FromBytes(template.Contents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read template from file: %w", err)
|
||||
}
|
||||
|
||||
// execute/render jinja template
|
||||
b := bytes.Buffer{}
|
||||
if err = t.Execute(&b, data); err != nil {
|
||||
return nil, fmt.Errorf("failed to execute: %w", err)
|
||||
}
|
||||
outputs[path] = b.Bytes()
|
||||
}
|
||||
|
||||
log.Debug().Any("templates", templates).Any("outputs", outputs).Any("mappings", mappings).Msg("apply templates")
|
||||
|
||||
return outputs, nil
|
||||
}
|
||||
|
||||
// Wrapper function similiar to "ApplyTemplates" but takes file paths as arguments.
|
||||
// This function will load templates from a file instead of using file contents.
|
||||
func ApplyTemplateFromFiles(mappings Mappings, paths ...string) (FileMap, error) {
|
||||
var (
|
||||
data = exec.NewContext(mappings)
|
||||
outputs = FileMap{}
|
||||
)
|
||||
|
||||
for _, path := range paths {
|
||||
// load jinja template from file
|
||||
t, err := gonja.FromFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read template from file: %w", err)
|
||||
}
|
||||
|
||||
// execute/render jinja template
|
||||
b := bytes.Buffer{}
|
||||
if err = t.Execute(&b, data); err != nil {
|
||||
return nil, fmt.Errorf("failed to execute: %w", err)
|
||||
}
|
||||
outputs[path] = b.Bytes()
|
||||
}
|
||||
|
||||
return outputs, nil
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
package generator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"strings"
|
||||
|
||||
"git.towk2.me/towk/configurator/pkg/client"
|
||||
"git.towk2.me/towk/configurator/pkg/config"
|
||||
"git.towk2.me/towk/configurator/pkg/util"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type Warewulf struct{}
|
||||
|
||||
func (g *Warewulf) GetName() string {
|
||||
return "warewulf"
|
||||
}
|
||||
|
||||
func (g *Warewulf) GetVersion() string {
|
||||
return util.GitCommit()
|
||||
}
|
||||
|
||||
func (g *Warewulf) GetDescription() string {
|
||||
return "Configurator generator plugin for 'warewulf' config files."
|
||||
}
|
||||
|
||||
func (g *Warewulf) Generate(config *config.Config, params Params) (FileMap, error) {
|
||||
var (
|
||||
smdClient = client.NewSmdClient(params.ClientOpts...)
|
||||
outputs = make(FileMap, len(params.Templates))
|
||||
nodeEntries = ""
|
||||
paths = []string{}
|
||||
)
|
||||
|
||||
// if we have a client, try making the request for the ethernet interfaces
|
||||
eths, err := smdClient.FetchEthernetInterfaces(params.Verbose)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch ethernet interfaces with client: %v", err)
|
||||
}
|
||||
|
||||
// check if we have the required params first
|
||||
if eths == nil {
|
||||
return nil, fmt.Errorf("invalid ethernet interfaces (variable is nil)")
|
||||
}
|
||||
if len(eths) <= 0 {
|
||||
return nil, fmt.Errorf("no ethernet interfaces found")
|
||||
}
|
||||
|
||||
// fetch redfish endpoints and handle errors
|
||||
eps, err := smdClient.FetchRedfishEndpoints(params.Verbose)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch redfish endpoints: %v", err)
|
||||
}
|
||||
if len(eps) <= 0 {
|
||||
return nil, fmt.Errorf("no redfish endpoints found")
|
||||
}
|
||||
|
||||
templates, err := ApplyTemplates(Mappings{
|
||||
"node_entries": nodeEntries,
|
||||
}, params.Templates)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load templates: %v", err)
|
||||
}
|
||||
|
||||
maps.Copy(outputs, params.Files)
|
||||
maps.Copy(outputs, templates)
|
||||
|
||||
// print message if verbose param is found
|
||||
if params.Verbose {
|
||||
for path, _ := range outputs {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
}
|
||||
log.Info().Str("paths", strings.Join(paths, ":")).Msg("templates and files loaded: \n")
|
||||
|
||||
return outputs, err
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
|
||||
type Profile struct {
|
||||
|
|
@ -43,7 +44,7 @@ func (s *Service) GetProfiles() http.HandlerFunc {
|
|||
|
||||
// read file contents
|
||||
var profile *Profile
|
||||
profile, err = LoadProfile(path)
|
||||
profile, err = LoadProfileFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -91,7 +92,7 @@ func (s *Service) GetProfile() http.HandlerFunc {
|
|||
err error
|
||||
)
|
||||
|
||||
profile, err = LoadProfile(path)
|
||||
profile, err = LoadProfileFromFile(path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
|
@ -114,8 +115,8 @@ func (s *Service) GetProfile() http.HandlerFunc {
|
|||
func (s *Service) CreateProfile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
type input struct {
|
||||
path string `json:"path"`
|
||||
profile *Profile `json:"profile"`
|
||||
Path string `json:"path"`
|
||||
Profile *Profile `json:"profile"`
|
||||
}
|
||||
var (
|
||||
body, contents []byte
|
||||
|
|
@ -137,37 +138,85 @@ func (s *Service) CreateProfile() http.HandlerFunc {
|
|||
}
|
||||
|
||||
// serialize just the profile part
|
||||
contents, err = json.Marshal(in.profile)
|
||||
contents, err = json.Marshal(in.Profile)
|
||||
if err != nil {
|
||||
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// create a new profile on disk
|
||||
err = os.WriteFile(in.path, contents, os.ModePerm)
|
||||
err = os.WriteFile(in.Path, contents, os.ModePerm)
|
||||
if err != nil {
|
||||
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreateProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
func (s *Service) SetProfileData() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
body, contents []byte
|
||||
newContents string
|
||||
profile *Profile
|
||||
path string
|
||||
err error
|
||||
)
|
||||
|
||||
body, err = io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &profile)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// make sure the request data sets an ID
|
||||
if profile.ID == "" {
|
||||
http.Error(w, "ID must be set to a non-empty value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// read the contents the file with profile ID
|
||||
path = s.BuildProfilePath(profile.ID)
|
||||
contents, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// modify the data of the profile's contents
|
||||
newContents, err = sjson.Set(string(contents), "data", profile.Data)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// write only the data to the file with ID
|
||||
err = os.WriteFile(path, []byte(newContents), os.ModePerm)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) DeleteProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
func (s *Service) DeleteProfileData() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) GetProfileData() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) GetProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) CreateProfilePath() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,10 +62,9 @@ func (s *Service) Serve() error {
|
|||
// router.Post("/profiles", s.CreateProfiles())
|
||||
router.Get("/profile/{id}", s.GetProfile())
|
||||
router.Post("/profile/{id}", s.CreateProfile())
|
||||
router.Post("/profile/{id}/data/{varname}", s.CreateProfileVar())
|
||||
router.Delete("/profile/{id}/data/{varname}", s.DeleteProfileVar())
|
||||
router.Get("/profile/{id}/data", s.GetProfileData())
|
||||
router.Get("/profile/{id}/data/{varname}", s.GetProfileVar())
|
||||
router.Post("/profile/{id}/data", s.SetProfileData())
|
||||
router.Delete("/profile/{id}/data", s.DeleteProfileData())
|
||||
router.Post("/profile/{id}/paths/{path}", s.CreateProfilePath())
|
||||
router.Delete("/profile/{id}/paths/{path}", s.DeleteProfilePath())
|
||||
router.Get("/profile/{id}/paths/{path}", s.GetProfilePath())
|
||||
|
|
@ -89,11 +88,11 @@ func (s *Service) FetchJwks(uri string) {
|
|||
|
||||
}
|
||||
|
||||
func LoadProfile(path string) (*Profile, error) {
|
||||
func LoadProfileFromFile(path string) (*Profile, error) {
|
||||
return LoadFromJSONFile[Profile](path)
|
||||
}
|
||||
|
||||
func LoadPlugin(path string) (*configurator.Plugin, error) {
|
||||
func LoadPluginFromFile(path string) (*configurator.Plugin, error) {
|
||||
return LoadFromJSONFile[configurator.Plugin](path)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue