Merge pull request #2 from OpenCHAMI/microservice
Add `serve` command to run configurator as a microservice
This commit is contained in:
commit
540c9a2911
10 changed files with 392 additions and 25 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
||||||
./configurator
|
**configurator**
|
||||||
|
**.yaml
|
||||||
|
**.yml
|
||||||
|
|
|
||||||
26
README.md
26
README.md
|
|
@ -4,10 +4,12 @@ Configurator is a tool that fetchs data from an instance of [SMD](https://github
|
||||||
|
|
||||||
## Building and Usage
|
## Building and Usage
|
||||||
|
|
||||||
Configurator is built using Go:
|
Configurator is built using standard `go` build tools. The project separates the client and server with build tags. To get started, clone the project, download the dependencies, and build the project:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go mod tidy && go build
|
git clone https://github.com/OpenCHAMI/configurator.git
|
||||||
|
go mod tidy
|
||||||
|
go build --tags all # equivalent to `go build --tags client,server``
|
||||||
```
|
```
|
||||||
|
|
||||||
To use the tool, run the following:
|
To use the tool, run the following:
|
||||||
|
|
@ -18,6 +20,20 @@ To use the tool, run the following:
|
||||||
|
|
||||||
This will generate a new DHCP `dnsmasq` config file based on the Jinja 2 template specified in the config file for "dnsmasq". The `--target` flag is set by passing an argument in the form of "type:template" to specify the type of config file being generate and the template file to use respectively. The configurator requires valid access token when making requests to an instance of SMD that has protected routes.
|
This will generate a new DHCP `dnsmasq` config file based on the Jinja 2 template specified in the config file for "dnsmasq". The `--target` flag is set by passing an argument in the form of "type:template" to specify the type of config file being generate and the template file to use respectively. The configurator requires valid access token when making requests to an instance of SMD that has protected routes.
|
||||||
|
|
||||||
|
The tool can also be ran as a microservice:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./configurator serve --config config.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the server is up and listening for HTTP requests, you can try making a request to it with curl:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:3334/target?type=dhcp&template=dnsmasq
|
||||||
|
```
|
||||||
|
|
||||||
|
This will do the same thing as the `generate` subcommand, but remotely.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Here is an example config file to start using configurator:
|
Here is an example config file to start using configurator:
|
||||||
|
|
@ -31,9 +47,9 @@ templates:
|
||||||
coredhcp: templates/dhcp/coredhcp.config.jinja
|
coredhcp: templates/dhcp/coredhcp.config.jinja
|
||||||
dnsmasq: templates/dhcp/dnsmasq.conf.jinja
|
dnsmasq: templates/dhcp/dnsmasq.conf.jinja
|
||||||
syslog: templates/syslog.jinja
|
syslog: templates/syslog.jinja
|
||||||
ansible: templates/ansible
|
ansible: templates/ansible.j2
|
||||||
powerman: templates/powerman
|
powerman: templates/powerman.jinja
|
||||||
conman: templates/conman
|
conman: templates/conman.jinja
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
//go:build client || all
|
||||||
|
// +build client all
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -43,11 +46,13 @@ var generateCmd = &cobra.Command{
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
// split the target and type
|
// split the target and type
|
||||||
tmp := strings.Split(target, ":")
|
tmp := strings.Split(target, ":")
|
||||||
configType := tmp[0]
|
g := generator.Generator{
|
||||||
configTemplate := tmp[1]
|
Type: tmp[0],
|
||||||
|
Template: tmp[1],
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: we probably don't want to hardcode the types, but should do for now
|
// NOTE: we probably don't want to hardcode the types, but should do for now
|
||||||
if configType == "dhcp" {
|
if g.Type == "dhcp" {
|
||||||
// fetch eths from SMD
|
// fetch eths from SMD
|
||||||
eths, err := client.FetchEthernetInterfaces()
|
eths, err := client.FetchEthernetInterfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -57,17 +62,17 @@ var generateCmd = &cobra.Command{
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// generate a new config from that data
|
// generate a new config from that data
|
||||||
g := generator.New()
|
|
||||||
g.GenerateDHCP(config, configTemplate, eths)
|
g.GenerateDHCP(&config, eths)
|
||||||
} else if configType == "dns" {
|
} else if g.Type == "dns" {
|
||||||
// TODO: fetch from SMD
|
// TODO: fetch from SMD
|
||||||
// TODO: generate config from pulled info
|
// TODO: generate config from pulled info
|
||||||
|
|
||||||
} else if configType == "syslog" {
|
} else if g.Type == "syslog" {
|
||||||
|
|
||||||
} else if configType == "ansible" {
|
} else if g.Type == "ansible" {
|
||||||
|
|
||||||
} else if configType == "warewulf" {
|
} else if g.Type == "warewulf" {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configPath string
|
configPath string
|
||||||
config *configurator.Config
|
config configurator.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
|
|
@ -34,7 +34,7 @@ func Execute() {
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
rootCmd.PersistentFlags().StringVar(&configPath, "config", "", "set the config path")
|
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "set the config path")
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
|
|
||||||
37
cmd/serve.go
Normal file
37
cmd/serve.go
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
//go:build server || all
|
||||||
|
// +build server all
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/OpenCHAMI/configurator/internal/server"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var serveCmd = &cobra.Command{
|
||||||
|
Use: "serve",
|
||||||
|
Short: "Start configurator as a server and listen for requests",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// set up the routes and start the server
|
||||||
|
server := server.New()
|
||||||
|
err := server.Start(&config)
|
||||||
|
if errors.Is(err, http.ErrServerClosed) {
|
||||||
|
fmt.Printf("Server closed.")
|
||||||
|
} else if err != nil {
|
||||||
|
logrus.Errorf("failed to start server: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
serveCmd.Flags().StringVar(&config.Server.Host, "host", config.Server.Host, "set the server host")
|
||||||
|
serveCmd.Flags().IntVar(&config.Server.Port, "port", config.Server.Port, "set the server port")
|
||||||
|
rootCmd.AddCommand(serveCmd)
|
||||||
|
}
|
||||||
37
go.mod
Normal file
37
go.mod
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
module github.com/OpenCHAMI/configurator
|
||||||
|
|
||||||
|
go 1.21.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/OpenCHAMI/jwtauth/v5 v5.0.0-20240321222802-e6cb468a2a18
|
||||||
|
github.com/go-chi/chi/v5 v5.0.12
|
||||||
|
github.com/lestrrat-go/jwx v1.2.29
|
||||||
|
github.com/nikolalohinski/gonja/v2 v2.2.0
|
||||||
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
github.com/spf13/cobra v1.8.0
|
||||||
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.2 // 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/backoff/v2 v2.0.8 // 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.4 // indirect
|
||||||
|
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||||
|
github.com/lestrrat-go/jwx/v2 v2.0.20 // indirect
|
||||||
|
github.com/lestrrat-go/option v1.0.1 // 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/spf13/pflag v1.0.5 // indirect
|
||||||
|
golang.org/x/crypto v0.21.0 // indirect
|
||||||
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
)
|
||||||
145
go.sum
Normal file
145
go.sum
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
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/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/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.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/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.12/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.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/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/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
|
||||||
|
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
|
||||||
|
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=
|
||||||
|
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
|
||||||
|
github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8=
|
||||||
|
github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
|
||||||
|
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
|
||||||
|
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
|
||||||
|
github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ=
|
||||||
|
github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8=
|
||||||
|
github.com/lestrrat-go/jwx/v2 v2.0.20 h1:sAgXuWS/t8ykxS9Bi2Qtn5Qhpakw1wrcjxChudjolCc=
|
||||||
|
github.com/lestrrat-go/jwx/v2 v2.0.20/go.mod h1:UlCSmKqw+agm5BsOBfEAbTvKsEApaGNqHAEUTv5PJC4=
|
||||||
|
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||||
|
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/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/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/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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||||
|
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
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=
|
||||||
|
|
@ -8,16 +8,27 @@ import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
JwksUri string `yaml:"jwks-uri"`
|
||||||
|
JwksRetries int `yaml:"jwks-retries"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
}
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Version string `yaml:"version"`
|
Version string `yaml:"version"`
|
||||||
SmdHost string `yaml:"smd-host"`
|
SmdHost string `yaml:"smd-host"`
|
||||||
SmdPort int `yaml:"smd-port"`
|
SmdPort int `yaml:"smd-port"`
|
||||||
AccessToken string `yaml:"access-token"`
|
AccessToken string `yaml:"access-token"`
|
||||||
TemplatePaths map[string]string `yaml:"templates"`
|
TemplatePaths map[string]string `yaml:"templates"`
|
||||||
|
Server Server `yaml:"server"`
|
||||||
|
Options Options `yaml:"options"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() Config {
|
||||||
return &Config{
|
return Config{
|
||||||
Version: "",
|
Version: "",
|
||||||
SmdHost: "http://127.0.0.1",
|
SmdHost: "http://127.0.0.1",
|
||||||
SmdPort: 27779,
|
SmdPort: 27779,
|
||||||
|
|
@ -28,11 +39,19 @@ func NewConfig() *Config {
|
||||||
"powerman": "templates/powerman",
|
"powerman": "templates/powerman",
|
||||||
"conman": "templates/conman",
|
"conman": "templates/conman",
|
||||||
},
|
},
|
||||||
|
Server: Server{
|
||||||
|
Host: "127.0.0.1",
|
||||||
|
Port: 3334,
|
||||||
|
},
|
||||||
|
Options: Options{
|
||||||
|
JwksUri: "",
|
||||||
|
JwksRetries: 5,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig(path string) *Config {
|
func LoadConfig(path string) Config {
|
||||||
var c *Config = NewConfig()
|
var c Config = NewConfig()
|
||||||
file, err := os.ReadFile(path)
|
file, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to read config file: %v\n", err)
|
log.Printf("failed to read config file: %v\n", err)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Generator struct {
|
type Generator struct {
|
||||||
|
Type string
|
||||||
|
Template string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *Generator {
|
func New() *Generator {
|
||||||
|
|
@ -24,12 +26,11 @@ func (g *Generator) GenerateDNS(config *configurator.Config) {
|
||||||
// TODO: print generated config file to STDOUT
|
// TODO: print generated config file to STDOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) GenerateDHCP(config *configurator.Config, target string, eths []configurator.EthernetInterface) error {
|
func (g *Generator) GenerateDHCP(config *configurator.Config, eths []configurator.EthernetInterface) error {
|
||||||
// generate file using gonja template
|
// generate file using gonja template
|
||||||
// TODO: load template file for DHCP
|
path := config.TemplatePaths[g.Template]
|
||||||
path := config.TemplatePaths[target]
|
|
||||||
fmt.Printf("path: %s\neth count: %v\n", path, len(eths))
|
fmt.Printf("path: %s\neth count: %v\n", path, len(eths))
|
||||||
t, err := gonja.FromFile(config.TemplatePaths[target])
|
t, err := gonja.FromFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read template from file: %v", err)
|
return fmt.Errorf("failed to read template from file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
105
internal/server/server.go
Normal file
105
internal/server/server.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
//go:build server || all
|
||||||
|
// +build server all
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
configurator "github.com/OpenCHAMI/configurator/internal"
|
||||||
|
"github.com/OpenCHAMI/configurator/internal/generator"
|
||||||
|
"github.com/OpenCHAMI/jwtauth/v5"
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tokenAuth *jwtauth.JWTAuth = nil
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
*http.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *Server {
|
||||||
|
return &Server{
|
||||||
|
Server: &http.Server{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Start(config *configurator.Config) error {
|
||||||
|
// create client just for the server to use to fetch data from SMD
|
||||||
|
client := &configurator.SmdClient{
|
||||||
|
Host: config.SmdHost,
|
||||||
|
Port: config.SmdPort,
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the server address with config values
|
||||||
|
s.Server.Addr = fmt.Sprintf("%s:%d", config.Server.Host, config.Server.Port)
|
||||||
|
|
||||||
|
// fetch JWKS public key from authorization server
|
||||||
|
if config.Options.JwksUri != "" && tokenAuth == nil {
|
||||||
|
for i := 0; i < config.Options.JwksRetries; i++ {
|
||||||
|
var err error
|
||||||
|
tokenAuth, err = configurator.FetchPublicKeyFromURL(config.Options.JwksUri)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("failed to fetch JWKS: %w", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new go-chi router with its routes
|
||||||
|
router := chi.NewRouter()
|
||||||
|
router.Use(middleware.RedirectSlashes)
|
||||||
|
router.Use(middleware.Timeout(60 * time.Second))
|
||||||
|
router.Group(func(r chi.Router) {
|
||||||
|
if config.Options.JwksUri != "" {
|
||||||
|
r.Use(
|
||||||
|
jwtauth.Verifier(tokenAuth),
|
||||||
|
jwtauth.Authenticator(tokenAuth),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
r.HandleFunc("/target", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
g := generator.Generator{
|
||||||
|
Type: r.URL.Query().Get("type"),
|
||||||
|
Template: r.URL.Query().Get("template"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: we probably don't want to hardcode the types, but should do for now
|
||||||
|
if g.Type == "dhcp" {
|
||||||
|
// fetch eths from SMD
|
||||||
|
eths, err := client.FetchEthernetInterfaces()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("failed to fetch DHCP metadata: %v\n", err)
|
||||||
|
w.Write([]byte("An error has occurred"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(eths) <= 0 {
|
||||||
|
logrus.Warnf("no ethernet interfaces found")
|
||||||
|
w.Write([]byte("no ethernet interfaces found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// generate a new config from that data
|
||||||
|
|
||||||
|
err = g.GenerateDHCP(config, eths)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("failed to generate DHCP: %v", err)
|
||||||
|
w.Write([]byte("An error has occurred."))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
r.HandleFunc("/templates", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// TODO: handle GET request
|
||||||
|
// TODO: handle POST request
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
s.Handler = router
|
||||||
|
return s.ListenAndServe()
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue