mirror of
https://github.com/davidallendj/configurator.git
synced 2025-12-19 19:17:01 -07:00
refactor: name changes and code clean up
This commit is contained in:
parent
b31056f297
commit
32065dc163
5 changed files with 134 additions and 135 deletions
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
configurator "github.com/OpenCHAMI/configurator/pkg"
|
||||
"github.com/OpenCHAMI/configurator/pkg/config"
|
||||
"github.com/OpenCHAMI/configurator/pkg/util"
|
||||
)
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ var configCmd = &cobra.Command{
|
|||
fmt.Printf("file or directory exists\n")
|
||||
continue
|
||||
}
|
||||
configurator.SaveDefaultConfig(path)
|
||||
config.SaveDefault(path)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ var fetchCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
// check to see if an access token is available from env
|
||||
if config.AccessToken == "" {
|
||||
if conf.AccessToken == "" {
|
||||
// check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
|
||||
accessToken := os.Getenv("ACCESS_TOKEN")
|
||||
if accessToken != "" {
|
||||
config.AccessToken = accessToken
|
||||
conf.AccessToken = accessToken
|
||||
} else {
|
||||
// TODO: try and fetch token first if it is needed
|
||||
if verbose {
|
||||
|
|
@ -46,7 +46,7 @@ var fetchCmd = &cobra.Command{
|
|||
|
||||
for _, target := range targets {
|
||||
// make a request for each target
|
||||
url := fmt.Sprintf("%s:%d/generate?target=%s", remoteHost, remotePort, target)
|
||||
url := fmt.Sprintf("%s/generate?target=%s", remoteHost, target)
|
||||
res, body, err := util.MakeRequest(url, http.MethodGet, nil, headers)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to make request")
|
||||
|
|
@ -63,8 +63,7 @@ var fetchCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
func init() {
|
||||
fetchCmd.Flags().StringVar(&remoteHost, "host", "", "set the remote configurator host")
|
||||
fetchCmd.Flags().IntVar(&remotePort, "port", 3334, "set the remote configurator port")
|
||||
fetchCmd.Flags().StringVar(&remoteHost, "host", "", "set the remote configurator host and port")
|
||||
fetchCmd.Flags().StringSliceVar(&targets, "target", nil, "set the target configs to make")
|
||||
fetchCmd.Flags().StringVarP(&outputPath, "output", "o", "", "set the output path for config targets")
|
||||
fetchCmd.Flags().StringVar(&accessToken, "access-token", "o", "set the output path for config targets")
|
||||
|
|
|
|||
196
cmd/generate.go
196
cmd/generate.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
configurator "github.com/OpenCHAMI/configurator/pkg"
|
||||
"github.com/OpenCHAMI/configurator/pkg/config"
|
||||
"github.com/OpenCHAMI/configurator/pkg/generator"
|
||||
"github.com/OpenCHAMI/configurator/pkg/util"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -28,155 +28,165 @@ var generateCmd = &cobra.Command{
|
|||
Short: "Generate a config file from state management",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// make sure that we have a token present before trying to make request
|
||||
if config.AccessToken == "" {
|
||||
if conf.AccessToken == "" {
|
||||
// check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
|
||||
accessToken := os.Getenv("ACCESS_TOKEN")
|
||||
if accessToken != "" {
|
||||
config.AccessToken = accessToken
|
||||
conf.AccessToken = accessToken
|
||||
} else {
|
||||
// TODO: try and fetch token first if it is needed
|
||||
if verbose {
|
||||
fmt.Printf("No token found. Attempting to generate config without one...\n")
|
||||
fmt.Printf("No token found. Attempting to generate conf without one...\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use cert path from cobra if empty
|
||||
if config.CertPath == "" {
|
||||
config.CertPath = cacertPath
|
||||
if conf.CertPath == "" {
|
||||
conf.CertPath = cacertPath
|
||||
}
|
||||
|
||||
// show config as JSON and generators if verbose
|
||||
// show conf as JSON and generators if verbose
|
||||
if verbose {
|
||||
b, err := json.MarshalIndent(config, "", " ")
|
||||
b, err := json.MarshalIndent(conf, "", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("failed to marshal config: %v\n", err)
|
||||
fmt.Printf("failed to marshal conf: %v\n", err)
|
||||
}
|
||||
fmt.Printf("%v\n", string(b))
|
||||
}
|
||||
|
||||
// run all of the target recursively until completion if provided
|
||||
if len(targets) > 0 {
|
||||
RunTargets(&config, args, targets...)
|
||||
RunTargets(&conf, args, targets...)
|
||||
} else {
|
||||
if pluginPath == "" {
|
||||
fmt.Printf("no plugin path specified")
|
||||
return
|
||||
}
|
||||
|
||||
// run generator.Generate() with just plugin path and templates provided
|
||||
generator.Generate(&config, generator.Params{
|
||||
PluginPath: pluginPath,
|
||||
TemplatePaths: templatePaths,
|
||||
})
|
||||
// load the templates to use
|
||||
templates := map[string]generator.Template{}
|
||||
for _, path := range templatePaths {
|
||||
template := generator.Template{}
|
||||
template.LoadFromFile(path)
|
||||
if !template.IsEmpty() {
|
||||
templates[path] = template
|
||||
}
|
||||
}
|
||||
|
||||
params := generator.Params{
|
||||
Templates: templates,
|
||||
}
|
||||
|
||||
// run generator.Generate() with just plugin path and templates provided
|
||||
outputBytes, err := generator.Generate(pluginPath, params)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to generate files")
|
||||
}
|
||||
|
||||
// if we have more than one target and output is set, create configs in directory
|
||||
writeOutput(outputBytes, len(targets), len(outputMap))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Generate files by supplying a list of targets as string values. Currently,
|
||||
// targets are defined statically in a config file. Targets are ran recursively
|
||||
// targets are defined statically in a conf file. Targets are ran recursively
|
||||
// if more targets are nested in a defined target, but will not run additional
|
||||
// child targets if it is the same as the parent.
|
||||
//
|
||||
// NOTE: This may be changed in the future how this is done.
|
||||
func RunTargets(config *configurator.Config, args []string, targets ...string) {
|
||||
// generate config with each supplied target
|
||||
func RunTargets(conf *config.Config, args []string, targets ...string) {
|
||||
// generate conf with each supplied target
|
||||
for _, target := range targets {
|
||||
outputBytes, err := generator.GenerateWithTarget(config, generator.Params{
|
||||
Args: args,
|
||||
PluginPath: pluginPath,
|
||||
Target: target,
|
||||
Verbose: verbose,
|
||||
})
|
||||
outputBytes, err := generator.GenerateWithTarget(conf, target)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to generate config")
|
||||
log.Error().Err(err).Msg("failed to generate conf")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// if we have more than one target and output is set, create configs in directory
|
||||
var (
|
||||
outputMap = generator.ConvertContentsToString(outputBytes)
|
||||
targetCount = len(targets)
|
||||
templateCount = len(outputMap)
|
||||
)
|
||||
if outputPath == "" {
|
||||
// write only to stdout by default
|
||||
if len(outputMap) == 1 {
|
||||
for _, contents := range outputMap {
|
||||
fmt.Printf("%s\n", string(contents))
|
||||
}
|
||||
} else {
|
||||
for path, contents := range outputMap {
|
||||
fmt.Printf("-- file: %s, size: %d B\n%s\n", path, len(contents), string(contents))
|
||||
}
|
||||
}
|
||||
} else if outputPath != "" && targetCount == 1 && templateCount == 1 {
|
||||
// write just a single file using provided name
|
||||
for _, contents := range outputBytes {
|
||||
err := os.WriteFile(outputPath, contents, 0o644)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write config to file")
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Info().Msgf("wrote file to '%s'\n", outputPath)
|
||||
}
|
||||
} else if outputPath != "" && targetCount > 1 && useCompression {
|
||||
// write multiple files to archive, compress, then save to output path
|
||||
out, err := os.Create(fmt.Sprintf("%s.tar.gz", outputPath))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write archive")
|
||||
os.Exit(1)
|
||||
}
|
||||
files := make([]string, len(outputBytes))
|
||||
i := 0
|
||||
for path := range outputBytes {
|
||||
files[i] = path
|
||||
i++
|
||||
}
|
||||
err = util.CreateArchive(files, out)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to create archive")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else if outputPath != "" && targetCount > 1 || templateCount > 1 {
|
||||
// write multiple files in directory using template name
|
||||
err := os.MkdirAll(filepath.Clean(outputPath), 0o755)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to make output directory")
|
||||
os.Exit(1)
|
||||
}
|
||||
for path, contents := range outputBytes {
|
||||
filename := filepath.Base(path)
|
||||
cleanPath := fmt.Sprintf("%s/%s", filepath.Clean(outputPath), filename)
|
||||
err := os.WriteFile(cleanPath, contents, 0o755)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write config to file")
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Info().Msgf("wrote file to '%s'\n", cleanPath)
|
||||
}
|
||||
}
|
||||
writeOutput(outputBytes, len(targets), len(outputMap))
|
||||
|
||||
// remove any targets that are the same as current to prevent infinite loop
|
||||
nextTargets := util.CopyIf(config.Targets[target].RunTargets, func(nextTarget string) bool {
|
||||
nextTargets := util.CopyIf(conf.Targets[target].RunTargets, func(nextTarget string) bool {
|
||||
return nextTarget != target
|
||||
})
|
||||
|
||||
// ...then, run any other targets that the current target has
|
||||
RunTargets(config, args, nextTargets...)
|
||||
RunTargets(conf, args, nextTargets...)
|
||||
}
|
||||
}
|
||||
|
||||
func writeOutput(outputBytes generator.FileMap, targetCount int, templateCount int) {
|
||||
outputMap := generator.ConvertContentsToString(outputBytes)
|
||||
if outputPath == "" {
|
||||
// write only to stdout by default
|
||||
if len(outputMap) == 1 {
|
||||
for _, contents := range outputMap {
|
||||
fmt.Printf("%s\n", string(contents))
|
||||
}
|
||||
} else {
|
||||
for path, contents := range outputMap {
|
||||
fmt.Printf("-- file: %s, size: %d B\n%s\n", path, len(contents), string(contents))
|
||||
}
|
||||
}
|
||||
} else if outputPath != "" && targetCount == 1 && templateCount == 1 {
|
||||
// write just a single file using provided name
|
||||
for _, contents := range outputBytes {
|
||||
err := os.WriteFile(outputPath, contents, 0o644)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write conf to file")
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Info().Msgf("wrote file to '%s'\n", outputPath)
|
||||
}
|
||||
} else if outputPath != "" && targetCount > 1 && useCompression {
|
||||
// write multiple files to archive, compress, then save to output path
|
||||
out, err := os.Create(fmt.Sprintf("%s.tar.gz", outputPath))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write archive")
|
||||
os.Exit(1)
|
||||
}
|
||||
files := make([]string, len(outputBytes))
|
||||
i := 0
|
||||
for path := range outputBytes {
|
||||
files[i] = path
|
||||
i++
|
||||
}
|
||||
err = util.CreateArchive(files, out)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to create archive")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else if outputPath != "" && targetCount > 1 || templateCount > 1 {
|
||||
// write multiple files in directory using template name
|
||||
err := os.MkdirAll(filepath.Clean(outputPath), 0o755)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to make output directory")
|
||||
os.Exit(1)
|
||||
}
|
||||
for path, contents := range outputBytes {
|
||||
filename := filepath.Base(path)
|
||||
cleanPath := fmt.Sprintf("%s/%s", filepath.Clean(outputPath), filename)
|
||||
err := os.WriteFile(cleanPath, contents, 0o755)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to write conf to file")
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Info().Msgf("wrote file to '%s'\n", cleanPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
generateCmd.Flags().StringSliceVar(&targets, "target", []string{}, "set the targets to run pre-defined config")
|
||||
generateCmd.Flags().StringSliceVar(&targets, "target", []string{}, "set the targets to run pre-defined conf")
|
||||
generateCmd.Flags().StringSliceVar(&templatePaths, "template", []string{}, "set the paths for the Jinja 2 templates to use")
|
||||
generateCmd.Flags().StringVar(&pluginPath, "plugin", "", "set the generator plugin path")
|
||||
generateCmd.Flags().StringVarP(&outputPath, "output", "o", "", "set the output path for config targets")
|
||||
generateCmd.Flags().StringVarP(&outputPath, "output", "o", "", "set the output path for conf targets")
|
||||
generateCmd.Flags().IntVar(&tokenFetchRetries, "fetch-retries", 5, "set the number of retries to fetch an access token")
|
||||
generateCmd.Flags().StringVar(&remoteHost, "host", "http://localhost", "set the remote host")
|
||||
generateCmd.Flags().IntVar(&remotePort, "port", 80, "set the remote port")
|
||||
generateCmd.Flags().BoolVar(&useCompression, "compress", false, "set whether to archive and compress multiple file outputs")
|
||||
|
||||
// requires either 'target' by itself or 'plugin' and 'templates' together
|
||||
|
|
|
|||
13
cmd/root.go
13
cmd/root.go
|
|
@ -4,14 +4,14 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
configurator "github.com/OpenCHAMI/configurator/pkg"
|
||||
"github.com/OpenCHAMI/configurator/pkg/config"
|
||||
"github.com/OpenCHAMI/configurator/pkg/util"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
config configurator.Config
|
||||
conf config.Config
|
||||
configPath string
|
||||
cacertPath string
|
||||
verbose bool
|
||||
|
|
@ -19,12 +19,11 @@ var (
|
|||
outputPath string
|
||||
accessToken string
|
||||
remoteHost string
|
||||
remotePort int
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "configurator",
|
||||
Short: "Tool for building common config files",
|
||||
Short: "Dynamically generate files defined by generators",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
cmd.Help()
|
||||
|
|
@ -55,7 +54,7 @@ func initConfig() {
|
|||
fmt.Printf("failed to load config")
|
||||
os.Exit(1)
|
||||
} else if exists {
|
||||
config = configurator.LoadConfig(configPath)
|
||||
conf = config.Load(configPath)
|
||||
} else {
|
||||
// show error and exit since a path was specified
|
||||
log.Error().Str("path", configPath).Msg("config file not found")
|
||||
|
|
@ -64,7 +63,7 @@ func initConfig() {
|
|||
} else {
|
||||
// set to the default value and create a new one
|
||||
configPath = "./config.yaml"
|
||||
config = configurator.NewConfig()
|
||||
conf = config.New()
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -74,6 +73,6 @@ func initConfig() {
|
|||
// set the JWKS url if we find the CONFIGURATOR_JWKS_URL environment variable
|
||||
jwksUrl := os.Getenv("CONFIGURATOR_JWKS_URL")
|
||||
if jwksUrl != "" {
|
||||
config.Server.Jwks.Uri = jwksUrl
|
||||
conf.Server.Jwks.Uri = jwksUrl
|
||||
}
|
||||
}
|
||||
|
|
|
|||
47
cmd/serve.go
47
cmd/serve.go
|
|
@ -10,8 +10,8 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/OpenCHAMI/configurator/pkg/generator"
|
||||
"github.com/OpenCHAMI/configurator/pkg/server"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -20,66 +20,57 @@ var serveCmd = &cobra.Command{
|
|||
Short: "Start configurator as a server and listen for requests",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// make sure that we have a token present before trying to make request
|
||||
if config.AccessToken == "" {
|
||||
// TODO: make request to check if request will need token
|
||||
|
||||
// check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
|
||||
if conf.AccessToken == "" {
|
||||
// check if ACCESS_TOKEN env var is set if no access token is provided and use that instead
|
||||
accessToken := os.Getenv("ACCESS_TOKEN")
|
||||
if accessToken != "" {
|
||||
config.AccessToken = accessToken
|
||||
conf.AccessToken = accessToken
|
||||
} else {
|
||||
// TODO: try and fetch token first if it is needed
|
||||
if verbose {
|
||||
fmt.Printf("No token found. Attempting to generate config without one...\n")
|
||||
fmt.Printf("No token found. Continuing without one...\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show config as JSON and generators if verbose
|
||||
// show conf as JSON and generators if verbose
|
||||
if verbose {
|
||||
b, err := json.MarshalIndent(config, "", " ")
|
||||
b, err := json.MarshalIndent(conf, "", "\t")
|
||||
if err != nil {
|
||||
fmt.Printf("failed to marshal config: %v\n", err)
|
||||
log.Error().Err(err).Msg("failed to marshal config")
|
||||
}
|
||||
fmt.Printf("%v\n", string(b))
|
||||
}
|
||||
|
||||
// set up the routes and start the serve
|
||||
server := server.Server{
|
||||
Config: &config,
|
||||
Config: &conf,
|
||||
Server: &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", config.Server.Host, config.Server.Port),
|
||||
Addr: fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port),
|
||||
},
|
||||
Jwks: server.Jwks{
|
||||
Uri: config.Server.Jwks.Uri,
|
||||
Retries: config.Server.Jwks.Retries,
|
||||
},
|
||||
GeneratorParams: generator.Params{
|
||||
Args: args,
|
||||
// PluginPath: pluginPath,
|
||||
// Target: target, // NOTE: targets are set via HTTP requests (ex: curl http://configurator:3334/generate?target=dnsmasq)
|
||||
Verbose: verbose,
|
||||
Uri: conf.Server.Jwks.Uri,
|
||||
Retries: conf.Server.Jwks.Retries,
|
||||
},
|
||||
}
|
||||
|
||||
// start listening with the server
|
||||
err := server.Serve(cacertPath)
|
||||
err := server.Serve()
|
||||
if errors.Is(err, http.ErrServerClosed) {
|
||||
if verbose {
|
||||
fmt.Printf("Server closed.")
|
||||
log.Info().Msg("server closed")
|
||||
}
|
||||
} else if err != nil {
|
||||
fmt.Errorf("failed to start server: %v", err)
|
||||
log.Error().Err(err).Msg("failed to start server")
|
||||
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")
|
||||
serveCmd.Flags().StringVar(&conf.Server.Host, "host", conf.Server.Host, "set the server host")
|
||||
serveCmd.Flags().IntVar(&conf.Server.Port, "port", conf.Server.Port, "set the server port")
|
||||
// serveCmd.Flags().StringVar(&pluginPath, "plugin", "", "set the generator plugins directory path")
|
||||
serveCmd.Flags().StringVar(&config.Server.Jwks.Uri, "jwks-uri", config.Server.Jwks.Uri, "set the JWKS url to fetch public key")
|
||||
serveCmd.Flags().IntVar(&config.Server.Jwks.Retries, "jwks-fetch-retries", config.Server.Jwks.Retries, "set the JWKS fetch retry count")
|
||||
serveCmd.Flags().StringVar(&conf.Server.Jwks.Uri, "jwks-uri", conf.Server.Jwks.Uri, "set the JWKS url to fetch public key")
|
||||
serveCmd.Flags().IntVar(&conf.Server.Jwks.Retries, "jwks-fetch-retries", conf.Server.Jwks.Retries, "set the JWKS fetch retry count")
|
||||
rootCmd.AddCommand(serveCmd)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue