refactor: name changes and code clean up

This commit is contained in:
David Allen 2024-11-21 14:13:31 -07:00
parent b31056f297
commit 32065dc163
Signed by: towk
GPG key ID: 793B2924A49B3A3F
5 changed files with 134 additions and 135 deletions

View file

@ -5,7 +5,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
configurator "github.com/OpenCHAMI/configurator/pkg" "github.com/OpenCHAMI/configurator/pkg/config"
"github.com/OpenCHAMI/configurator/pkg/util" "github.com/OpenCHAMI/configurator/pkg/util"
) )
@ -23,7 +23,7 @@ var configCmd = &cobra.Command{
fmt.Printf("file or directory exists\n") fmt.Printf("file or directory exists\n")
continue continue
} }
configurator.SaveDefaultConfig(path) config.SaveDefault(path)
} }
}, },
} }

View file

@ -25,11 +25,11 @@ var fetchCmd = &cobra.Command{
} }
// check to see if an access token is available from env // 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 // check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
accessToken := os.Getenv("ACCESS_TOKEN") accessToken := os.Getenv("ACCESS_TOKEN")
if accessToken != "" { if accessToken != "" {
config.AccessToken = accessToken conf.AccessToken = accessToken
} else { } else {
// TODO: try and fetch token first if it is needed // TODO: try and fetch token first if it is needed
if verbose { if verbose {
@ -46,7 +46,7 @@ var fetchCmd = &cobra.Command{
for _, target := range targets { for _, target := range targets {
// make a request for each target // 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) res, body, err := util.MakeRequest(url, http.MethodGet, nil, headers)
if err != nil { if err != nil {
log.Error().Err(err).Msg("failed to make request") log.Error().Err(err).Msg("failed to make request")
@ -63,8 +63,7 @@ var fetchCmd = &cobra.Command{
} }
func init() { func init() {
fetchCmd.Flags().StringVar(&remoteHost, "host", "", "set the remote configurator host") fetchCmd.Flags().StringVar(&remoteHost, "host", "", "set the remote configurator host and port")
fetchCmd.Flags().IntVar(&remotePort, "port", 3334, "set the remote configurator port")
fetchCmd.Flags().StringSliceVar(&targets, "target", nil, "set the target configs to make") 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().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") fetchCmd.Flags().StringVar(&accessToken, "access-token", "o", "set the output path for config targets")

View file

@ -9,7 +9,7 @@ import (
"os" "os"
"path/filepath" "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/generator"
"github.com/OpenCHAMI/configurator/pkg/util" "github.com/OpenCHAMI/configurator/pkg/util"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -28,78 +28,98 @@ var generateCmd = &cobra.Command{
Short: "Generate a config file from state management", Short: "Generate a config file from state management",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
// make sure that we have a token present before trying to make request // 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 // check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
accessToken := os.Getenv("ACCESS_TOKEN") accessToken := os.Getenv("ACCESS_TOKEN")
if accessToken != "" { if accessToken != "" {
config.AccessToken = accessToken conf.AccessToken = accessToken
} else { } else {
// TODO: try and fetch token first if it is needed // TODO: try and fetch token first if it is needed
if verbose { 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 // use cert path from cobra if empty
if config.CertPath == "" { if conf.CertPath == "" {
config.CertPath = cacertPath conf.CertPath = cacertPath
} }
// show config as JSON and generators if verbose // show conf as JSON and generators if verbose
if verbose { if verbose {
b, err := json.MarshalIndent(config, "", " ") b, err := json.MarshalIndent(conf, "", " ")
if err != nil { 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)) fmt.Printf("%v\n", string(b))
} }
// run all of the target recursively until completion if provided // run all of the target recursively until completion if provided
if len(targets) > 0 { if len(targets) > 0 {
RunTargets(&config, args, targets...) RunTargets(&conf, args, targets...)
} else { } else {
if pluginPath == "" { if pluginPath == "" {
fmt.Printf("no plugin path specified") fmt.Printf("no plugin path specified")
return return
} }
// run generator.Generate() with just plugin path and templates provided // load the templates to use
generator.Generate(&config, generator.Params{ templates := map[string]generator.Template{}
PluginPath: pluginPath, for _, path := range templatePaths {
TemplatePaths: 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, // 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 // if more targets are nested in a defined target, but will not run additional
// child targets if it is the same as the parent. // child targets if it is the same as the parent.
// //
// NOTE: This may be changed in the future how this is done. // NOTE: This may be changed in the future how this is done.
func RunTargets(config *configurator.Config, args []string, targets ...string) { func RunTargets(conf *config.Config, args []string, targets ...string) {
// generate config with each supplied target // generate conf with each supplied target
for _, target := range targets { for _, target := range targets {
outputBytes, err := generator.GenerateWithTarget(config, generator.Params{ outputBytes, err := generator.GenerateWithTarget(conf, target)
Args: args,
PluginPath: pluginPath,
Target: target,
Verbose: verbose,
})
if err != nil { if err != nil {
log.Error().Err(err).Msg("failed to generate config") log.Error().Err(err).Msg("failed to generate conf")
os.Exit(1) os.Exit(1)
} }
// if we have more than one target and output is set, create configs in directory // if we have more than one target and output is set, create configs in directory
var ( writeOutput(outputBytes, len(targets), len(outputMap))
outputMap = generator.ConvertContentsToString(outputBytes)
targetCount = len(targets) // remove any targets that are the same as current to prevent infinite loop
templateCount = len(outputMap) 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(conf, args, nextTargets...)
}
}
func writeOutput(outputBytes generator.FileMap, targetCount int, templateCount int) {
outputMap := generator.ConvertContentsToString(outputBytes)
if outputPath == "" { if outputPath == "" {
// write only to stdout by default // write only to stdout by default
if len(outputMap) == 1 { if len(outputMap) == 1 {
@ -116,7 +136,7 @@ func RunTargets(config *configurator.Config, args []string, targets ...string) {
for _, contents := range outputBytes { for _, contents := range outputBytes {
err := os.WriteFile(outputPath, contents, 0o644) err := os.WriteFile(outputPath, contents, 0o644)
if err != nil { if err != nil {
log.Error().Err(err).Msg("failed to write config to file") log.Error().Err(err).Msg("failed to write conf to file")
os.Exit(1) os.Exit(1)
} }
log.Info().Msgf("wrote file to '%s'\n", outputPath) log.Info().Msgf("wrote file to '%s'\n", outputPath)
@ -152,31 +172,21 @@ func RunTargets(config *configurator.Config, args []string, targets ...string) {
cleanPath := fmt.Sprintf("%s/%s", filepath.Clean(outputPath), filename) cleanPath := fmt.Sprintf("%s/%s", filepath.Clean(outputPath), filename)
err := os.WriteFile(cleanPath, contents, 0o755) err := os.WriteFile(cleanPath, contents, 0o755)
if err != nil { if err != nil {
log.Error().Err(err).Msg("failed to write config to file") log.Error().Err(err).Msg("failed to write conf to file")
os.Exit(1) os.Exit(1)
} }
log.Info().Msgf("wrote file to '%s'\n", cleanPath) log.Info().Msgf("wrote file to '%s'\n", cleanPath)
} }
} }
// remove any targets that are the same as current to prevent infinite loop
nextTargets := util.CopyIf(config.Targets[target].RunTargets, func(nextTarget string) bool {
return nextTarget != target
})
// ...then, run any other targets that the current target has
RunTargets(config, args, nextTargets...)
}
} }
func init() { 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().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().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().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().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") 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 // requires either 'target' by itself or 'plugin' and 'templates' together

View file

@ -4,14 +4,14 @@ import (
"fmt" "fmt"
"os" "os"
configurator "github.com/OpenCHAMI/configurator/pkg" "github.com/OpenCHAMI/configurator/pkg/config"
"github.com/OpenCHAMI/configurator/pkg/util" "github.com/OpenCHAMI/configurator/pkg/util"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var (
config configurator.Config conf config.Config
configPath string configPath string
cacertPath string cacertPath string
verbose bool verbose bool
@ -19,12 +19,11 @@ var (
outputPath string outputPath string
accessToken string accessToken string
remoteHost string remoteHost string
remotePort int
) )
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "configurator", Use: "configurator",
Short: "Tool for building common config files", Short: "Dynamically generate files defined by generators",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
cmd.Help() cmd.Help()
@ -55,7 +54,7 @@ func initConfig() {
fmt.Printf("failed to load config") fmt.Printf("failed to load config")
os.Exit(1) os.Exit(1)
} else if exists { } else if exists {
config = configurator.LoadConfig(configPath) conf = config.Load(configPath)
} else { } else {
// show error and exit since a path was specified // show error and exit since a path was specified
log.Error().Str("path", configPath).Msg("config file not found") log.Error().Str("path", configPath).Msg("config file not found")
@ -64,7 +63,7 @@ func initConfig() {
} else { } else {
// set to the default value and create a new one // set to the default value and create a new one
configPath = "./config.yaml" 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 // set the JWKS url if we find the CONFIGURATOR_JWKS_URL environment variable
jwksUrl := os.Getenv("CONFIGURATOR_JWKS_URL") jwksUrl := os.Getenv("CONFIGURATOR_JWKS_URL")
if jwksUrl != "" { if jwksUrl != "" {
config.Server.Jwks.Uri = jwksUrl conf.Server.Jwks.Uri = jwksUrl
} }
} }

View file

@ -10,8 +10,8 @@ import (
"net/http" "net/http"
"os" "os"
"github.com/OpenCHAMI/configurator/pkg/generator"
"github.com/OpenCHAMI/configurator/pkg/server" "github.com/OpenCHAMI/configurator/pkg/server"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,66 +20,57 @@ var serveCmd = &cobra.Command{
Short: "Start configurator as a server and listen for requests", Short: "Start configurator as a server and listen for requests",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
// make sure that we have a token present before trying to make request // make sure that we have a token present before trying to make request
if config.AccessToken == "" { if conf.AccessToken == "" {
// TODO: make request to check if request will need token // check if ACCESS_TOKEN env var is set if no access token is provided and use that instead
// check if OCHAMI_ACCESS_TOKEN env var is set if no access token is provided and use that instead
accessToken := os.Getenv("ACCESS_TOKEN") accessToken := os.Getenv("ACCESS_TOKEN")
if accessToken != "" { if accessToken != "" {
config.AccessToken = accessToken conf.AccessToken = accessToken
} else { } else {
// TODO: try and fetch token first if it is needed
if verbose { 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 { if verbose {
b, err := json.MarshalIndent(config, "", " ") b, err := json.MarshalIndent(conf, "", "\t")
if err != nil { 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)) fmt.Printf("%v\n", string(b))
} }
// set up the routes and start the serve // set up the routes and start the serve
server := server.Server{ server := server.Server{
Config: &config, Config: &conf,
Server: &http.Server{ 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{ Jwks: server.Jwks{
Uri: config.Server.Jwks.Uri, Uri: conf.Server.Jwks.Uri,
Retries: config.Server.Jwks.Retries, Retries: conf.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,
}, },
} }
// start listening with the server // start listening with the server
err := server.Serve(cacertPath) err := server.Serve()
if errors.Is(err, http.ErrServerClosed) { if errors.Is(err, http.ErrServerClosed) {
if verbose { if verbose {
fmt.Printf("Server closed.") log.Info().Msg("server closed")
} }
} else if err != nil { } else if err != nil {
fmt.Errorf("failed to start server: %v", err) log.Error().Err(err).Msg("failed to start server")
os.Exit(1) os.Exit(1)
} }
}, },
} }
func init() { func init() {
serveCmd.Flags().StringVar(&config.Server.Host, "host", config.Server.Host, "set the server host") serveCmd.Flags().StringVar(&conf.Server.Host, "host", conf.Server.Host, "set the server host")
serveCmd.Flags().IntVar(&config.Server.Port, "port", config.Server.Port, "set the server port") 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(&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().StringVar(&conf.Server.Jwks.Uri, "jwks-uri", conf.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().IntVar(&conf.Server.Jwks.Retries, "jwks-fetch-retries", conf.Server.Jwks.Retries, "set the JWKS fetch retry count")
rootCmd.AddCommand(serveCmd) rootCmd.AddCommand(serveCmd)
} }