Skip to content

Commit 7cdc73b

Browse files
committed
Separate validating types & review feedback
1 parent fa29023 commit 7cdc73b

File tree

6 files changed

+137
-63
lines changed

6 files changed

+137
-63
lines changed

cmd/gateway/commands.go

+9-61
Original file line numberDiff line numberDiff line change
@@ -39,68 +39,20 @@ var (
3939
}
4040

4141
// Backing values for static subcommand cli flags.
42-
updateGCStatus bool
43-
disableMetrics bool
44-
metricsListenPort int
45-
metricsSecure bool
42+
updateGCStatus bool
43+
disableMetrics bool
44+
metricsSecure bool
4645

46+
metricsListenPort = intValidatingValue{
47+
validator: validatePort,
48+
value: 9113,
49+
}
4750
gateway = namespacedNameValue{}
4851
configName = stringValidatingValue{
4952
validator: validateResourceName,
5053
}
5154
)
5255

53-
// stringValidatingValue is a string flag value with custom validation logic.
54-
// it implements the pflag.Value interface.
55-
type stringValidatingValue struct {
56-
validator func(v string) error
57-
value string
58-
}
59-
60-
func (v *stringValidatingValue) String() string {
61-
return v.value
62-
}
63-
64-
func (v *stringValidatingValue) Set(param string) error {
65-
if err := v.validator(param); err != nil {
66-
return err
67-
}
68-
v.value = param
69-
return nil
70-
}
71-
72-
func (v *stringValidatingValue) Type() string {
73-
return "string"
74-
}
75-
76-
// namespacedNameValue is a string flag value that represents a namespaced name.
77-
// it implements the pflag.Value interface.
78-
type namespacedNameValue struct {
79-
value types.NamespacedName
80-
}
81-
82-
func (v *namespacedNameValue) String() string {
83-
if (v.value == types.NamespacedName{}) {
84-
// if we don't do that, the default value in the help message will be printed as "/"
85-
return ""
86-
}
87-
return v.value.String()
88-
}
89-
90-
func (v *namespacedNameValue) Set(param string) error {
91-
nsname, err := parseNamespacedResourceName(param)
92-
if err != nil {
93-
return err
94-
}
95-
96-
v.value = nsname
97-
return nil
98-
}
99-
100-
func (v *namespacedNameValue) Type() string {
101-
return "string"
102-
}
103-
10456
func createRootCommand() *cobra.Command {
10557
rootCmd := &cobra.Command{
10658
Use: "gateway",
@@ -158,11 +110,8 @@ func createStaticModeCommand() *cobra.Command {
158110

159111
metricsConfig := config.MetricsConfig{}
160112
if !disableMetrics {
161-
if err := validatePort(metricsListenPort); err != nil {
162-
return fmt.Errorf("error validating metrics listen port: %w", err)
163-
}
164113
metricsConfig.Enabled = true
165-
metricsConfig.Port = metricsListenPort
114+
metricsConfig.Port = metricsListenPort.value
166115
metricsConfig.Secure = metricsSecure
167116
}
168117

@@ -219,10 +168,9 @@ func createStaticModeCommand() *cobra.Command {
219168
"Disable exposing metrics in the Prometheus format.",
220169
)
221170

222-
cmd.Flags().IntVar(
171+
cmd.Flags().Var(
223172
&metricsListenPort,
224173
"metrics-port",
225-
9113,
226174
"Set the port where the metrics are exposed. Format: [1023 - 65535]",
227175
)
228176

cmd/gateway/commands_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ func TestStaticModeCmdFlagValidation(t *testing.T) {
118118
"--gateway=nginx-gateway/nginx",
119119
"--config=nginx-gateway-config",
120120
"--update-gatewayclass-status=true",
121+
"--metrics-port=9114",
122+
"--metrics-disable",
123+
"--metrics-secure-serving",
121124
},
122125
wantErr: false,
123126
},
@@ -175,6 +178,42 @@ func TestStaticModeCmdFlagValidation(t *testing.T) {
175178
wantErr: true,
176179
expectedErrPrefix: `invalid argument "invalid" for "--update-gatewayclass-status" flag: strconv.ParseBool`,
177180
},
181+
{
182+
name: "metrics-port is invalid type",
183+
args: []string{
184+
"--metrics-port=invalid", // not an int
185+
},
186+
wantErr: true,
187+
expectedErrPrefix: `invalid argument "invalid" for "--metrics-port" flag: failed to parse int value:` +
188+
` strconv.ParseInt: parsing "invalid": invalid syntax`,
189+
},
190+
{
191+
name: "metrics-port is outside of range",
192+
args: []string{
193+
"--metrics-port=999", // outside of range
194+
},
195+
wantErr: true,
196+
expectedErrPrefix: `invalid argument "999" for "--metrics-port" flag:` +
197+
` port outside of valid port range [1024 - 65535]: 999`,
198+
},
199+
{
200+
name: "metrics-disable is not a bool",
201+
args: []string{
202+
"--metrics-disable=999", // not a bool
203+
},
204+
wantErr: true,
205+
expectedErrPrefix: `invalid argument "999" for "--metrics-disable" flag: strconv.ParseBool:` +
206+
` parsing "999": invalid syntax`,
207+
},
208+
{
209+
name: "metrics-secure-serving is not a bool",
210+
args: []string{
211+
"--metrics-secure-serving=999", // not a bool
212+
},
213+
wantErr: true,
214+
expectedErrPrefix: `invalid argument "999" for "--metrics-secure-serving" flag: strconv.ParseBool:` +
215+
` parsing "999": invalid syntax`,
216+
},
178217
}
179218

180219
for _, test := range tests {

cmd/gateway/validating_types.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
7+
"k8s.io/apimachinery/pkg/types"
8+
)
9+
10+
// stringValidatingValue is a string flag value with custom validation logic.
11+
// it implements the pflag.Value interface.
12+
type stringValidatingValue struct {
13+
validator func(v string) error
14+
value string
15+
}
16+
17+
func (v *stringValidatingValue) String() string {
18+
return v.value
19+
}
20+
21+
func (v *stringValidatingValue) Set(param string) error {
22+
if err := v.validator(param); err != nil {
23+
return err
24+
}
25+
v.value = param
26+
return nil
27+
}
28+
29+
func (v *stringValidatingValue) Type() string {
30+
return "string"
31+
}
32+
33+
type intValidatingValue struct {
34+
validator func(v int) error
35+
value int
36+
}
37+
38+
func (v *intValidatingValue) String() string {
39+
return strconv.Itoa(v.value)
40+
}
41+
42+
func (v *intValidatingValue) Set(param string) error {
43+
intVal, err := strconv.ParseInt(param, 10, 32)
44+
if err != nil {
45+
return fmt.Errorf("failed to parse int value: %w", err)
46+
}
47+
48+
if err := v.validator(int(intVal)); err != nil {
49+
return err
50+
}
51+
52+
v.value = int(intVal)
53+
return nil
54+
}
55+
56+
func (v *intValidatingValue) Type() string {
57+
return "int"
58+
}
59+
60+
// namespacedNameValue is a string flag value that represents a namespaced name.
61+
// it implements the pflag.Value interface.
62+
type namespacedNameValue struct {
63+
value types.NamespacedName
64+
}
65+
66+
func (v *namespacedNameValue) String() string {
67+
if (v.value == types.NamespacedName{}) {
68+
// if we don't do that, the default value in the help message will be printed as "/"
69+
return ""
70+
}
71+
return v.value.String()
72+
}
73+
74+
func (v *namespacedNameValue) Set(param string) error {
75+
nsname, err := parseNamespacedResourceName(param)
76+
if err != nil {
77+
return err
78+
}
79+
80+
v.value = nsname
81+
return nil
82+
}
83+
84+
func (v *namespacedNameValue) Type() string {
85+
return "string"
86+
}

docs/architecture.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ parentheses. To enhance readability, the suffix "process" has been omitted from
9696

9797
1. (HTTPS) *NKG* reads the *Kubernetes API* to get the latest versions of the resources in the cluster and writes to the
9898
API to update the handled resources' statuses and emit events.
99-
2. (HTTP) *Prometheus* fetches the `controller-runtime` and NGINX metrics via an HTTP endpoint that *NKG* exposes.
99+
2. (HTTP, HTTPS) *Prometheus* fetches the `controller-runtime` and NGINX metrics via an HTTP endpoint that *NKG* exposes.
100100
The default is :9113/metrics. Note: Prometheus is not required by NKG, the endpoint can be turned off.
101101
3. (File I/O)
102102
- Write: *NKG* generates NGINX *configuration* based on the cluster resources and writes them as `.conf` files to the

internal/mode/static/nginx/runtime/manager.go

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func (m *ManagerImpl) Reload(ctx context.Context) error {
7070
return nil
7171
}
7272

73+
// EnsureNginxRunning ensures NGINX is running by locating the main process.
7374
func EnsureNginxRunning(ctx context.Context) error {
7475
if _, err := findMainProcess(ctx, os.Stat, os.ReadFile, pidFileTimeout); err != nil {
7576
return fmt.Errorf("failed to find NGINX main process: %w", err)

internal/mode/static/state/graph/gateway_listener_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func TestValidateHTTPSListener(t *testing.T) {
114114
l: v1beta1.Listener{
115115
Port: 9113,
116116
TLS: &v1beta1.GatewayTLSConfig{
117-
Mode: helpers.GetTLSModePointer(v1beta1.TLSModeTerminate),
117+
Mode: helpers.GetPointer(v1beta1.TLSModeTerminate),
118118
CertificateRefs: []v1beta1.SecretObjectReference{validSecretRef},
119119
},
120120
},

0 commit comments

Comments
 (0)