Skip to content

Commit 97723e4

Browse files
authored
Merge pull request #331 from gatewayd-io/lint-on-run
Lint on run
2 parents 5732a59 + ea6cf0e commit 97723e4

File tree

7 files changed

+46
-17
lines changed

7 files changed

+46
-17
lines changed

cmd/config_lint.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ var configLintCmd = &cobra.Command{
3131
defer sentry.Recover()
3232
}
3333

34-
lintConfig(cmd, Global, globalConfigFile)
34+
if err := lintConfig(Global, globalConfigFile); err != nil {
35+
log.Fatal(err)
36+
}
37+
38+
cmd.Println("global config is valid")
3539
},
3640
}
3741

cmd/plugin_lint.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ var pluginLintCmd = &cobra.Command{
3131
defer sentry.Recover()
3232
}
3333

34-
lintConfig(cmd, Plugins, pluginConfigFile)
34+
if err := lintConfig(Plugins, pluginConfigFile); err != nil {
35+
log.Fatal(err)
36+
}
37+
38+
cmd.Println("plugins config is valid")
3539
},
3640
}
3741

cmd/run.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import (
4545
// https://github.com/gatewayd-io/gatewayd/issues/324
4646
var (
4747
enableTracing bool
48+
enableLinting bool
4849
collectorURL string
4950
enableSentry bool
5051
devMode bool
@@ -168,6 +169,22 @@ var runCmd = &cobra.Command{
168169
defer sentry.Recover()
169170
}
170171

172+
// Lint the configuration files before loading them.
173+
if enableLinting {
174+
_, span := otel.Tracer(config.TracerName).Start(runCtx, "Lint configuration files")
175+
defer span.End()
176+
177+
// Lint the global configuration file and fail if it's not valid.
178+
if err := lintConfig(Global, globalConfigFile); err != nil {
179+
log.Fatal(err)
180+
}
181+
182+
// Lint the plugin configuration file and fail if it's not valid.
183+
if err := lintConfig(Plugins, pluginConfigFile); err != nil {
184+
log.Fatal(err)
185+
}
186+
}
187+
171188
// Load global and plugin configuration.
172189
conf = config.NewConfig(runCtx, globalConfigFile, pluginConfigFile)
173190
conf.InitConfig(runCtx)
@@ -775,4 +792,6 @@ func init() {
775792
&enableSentry, "sentry", true, "Enable Sentry")
776793
runCmd.Flags().BoolVar(
777794
&enableUsageReport, "usage-report", true, "Enable usage report")
795+
runCmd.Flags().BoolVar(
796+
&enableLinting, "lint", true, "Enable linting of configuration files")
778797
}

cmd/utils.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"strings"
1717

1818
"github.com/gatewayd-io/gatewayd/config"
19+
gerr "github.com/gatewayd-io/gatewayd/errors"
1920
"github.com/google/go-github/v53/github"
2021
jsonSchemaGenerator "github.com/invopop/jsonschema"
2122
"github.com/knadh/koanf"
@@ -92,9 +93,7 @@ func generateConfig(
9293
cmd.Printf("Config file '%s' was %s successfully.", configFile, verb)
9394
}
9495

95-
func lintConfig(cmd *cobra.Command, fileType configFileType, configFile string) {
96-
logger := log.New(cmd.OutOrStdout(), "", 0)
97-
96+
func lintConfig(fileType configFileType, configFile string) error {
9897
// Load the config file and check it for errors.
9998
var conf *config.Config
10099
switch fileType {
@@ -109,7 +108,7 @@ func lintConfig(cmd *cobra.Command, fileType configFileType, configFile string)
109108
conf.LoadPluginConfigFile(context.TODO())
110109
conf.UnmarshalPluginConfig(context.TODO())
111110
default:
112-
logger.Fatal("Invalid config file type")
111+
return gerr.ErrLintingFailed
113112
}
114113

115114
// Marshal the config to JSON.
@@ -121,17 +120,17 @@ func lintConfig(cmd *cobra.Command, fileType configFileType, configFile string)
121120
case Plugins:
122121
jsonData, err = conf.PluginKoanf.Marshal(koanfJson.Parser())
123122
default:
124-
logger.Fatal("Invalid config file type")
123+
return gerr.ErrLintingFailed
125124
}
126125
if err != nil {
127-
logger.Fatalf("Error marshalling %s config to JSON: %s\n", string(fileType), err)
126+
return gerr.ErrLintingFailed.Wrap(err)
128127
}
129128

130129
// Unmarshal the JSON data into a map.
131130
var jsonBytes map[string]interface{}
132131
err = json.Unmarshal(jsonData, &jsonBytes)
133132
if err != nil {
134-
logger.Fatal("Error unmarshalling schema to JSON:\n", err)
133+
return gerr.ErrLintingFailed.Wrap(err)
135134
}
136135

137136
// Generate a JSON schema from the config struct.
@@ -142,28 +141,28 @@ func lintConfig(cmd *cobra.Command, fileType configFileType, configFile string)
142141
case Plugins:
143142
generatedSchema = jsonSchemaGenerator.Reflect(&config.PluginConfig{})
144143
default:
145-
logger.Fatal("Invalid config file type")
144+
return gerr.ErrLintingFailed
146145
}
147146

148147
// Marshal the schema to JSON.
149148
schemaBytes, err := json.Marshal(generatedSchema)
150149
if err != nil {
151-
logger.Fatal("Error marshalling schema to JSON:\n", err)
150+
return gerr.ErrLintingFailed.Wrap(err)
152151
}
153152

154153
// Compile the schema for validation.
155154
schema, err := jsonSchemaV5.CompileString("", string(schemaBytes))
156155
if err != nil {
157-
logger.Fatal("Error compiling schema:\n", err)
156+
return gerr.ErrLintingFailed.Wrap(err)
158157
}
159158

160159
// Validate the config against the schema.
161160
err = schema.Validate(jsonBytes)
162161
if err != nil {
163-
logger.Fatalf("Error validating %s config: %s\n", string(fileType), err)
162+
return gerr.ErrLintingFailed.Wrap(err)
164163
}
165164

166-
cmd.Printf("%s config is valid\n", fileType)
165+
return nil
167166
}
168167

169168
func listPlugins(cmd *cobra.Command, pluginConfigFile string, onlyEnabled bool) {

errors/errors.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const (
3232
ErrCodeDuplicateMetricsCollector
3333
ErrCodeInvalidMetricType
3434
ErrCodeValidationFailed
35+
ErrCodeLintingFailed
3536
)
3637

3738
var (
@@ -104,6 +105,8 @@ var (
104105

105106
ErrValidationFailed = NewGatewayDError(
106107
ErrCodeValidationFailed, "validation failed", nil)
108+
ErrLintingFailed = NewGatewayDError(
109+
ErrCodeLintingFailed, "linting failed", nil)
107110
)
108111

109112
const (

network/proxy_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestNewProxy(t *testing.T) {
1919
Output: []config.LogOutput{config.Console},
2020
TimeFormat: zerolog.TimeFormatUnix,
2121
ConsoleTimeFormat: time.RFC3339,
22-
Level: zerolog.DebugLevel,
22+
Level: zerolog.WarnLevel,
2323
NoColor: true,
2424
})
2525

@@ -82,7 +82,7 @@ func TestNewProxyElastic(t *testing.T) {
8282
Output: []config.LogOutput{config.Console},
8383
TimeFormat: zerolog.TimeFormatUnix,
8484
ConsoleTimeFormat: time.RFC3339,
85-
Level: zerolog.DebugLevel,
85+
Level: zerolog.WarnLevel,
8686
NoColor: true,
8787
})
8888

network/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestRunServer(t *testing.T) {
3131
},
3232
TimeFormat: zerolog.TimeFormatUnix,
3333
ConsoleTimeFormat: time.RFC3339,
34-
Level: zerolog.DebugLevel,
34+
Level: zerolog.WarnLevel,
3535
NoColor: true,
3636
FileName: "server_test.log",
3737
})

0 commit comments

Comments
 (0)