Skip to content

Commit 52a5b73

Browse files
Resolve FIXMEs for gateway-ctlr-name CLI arg (#235)
- Removes the requirement for namespace in gateway-ctlr-name CLI arg. The expected format is now DOMAIN/PATH. Valid examples include: "k8s-gateway.nginx.org/nginx-gateway-controller", "k8s-gateway.nginx.org/nginx-gateway/nginx-gateway-controller", and "k8s-gateway.nginx.org/nginx-gateway/nginx-gateway-controller/v2". - Updates the validation of the argument to use the regex provided by the kubebuilder annotation for GatewayClass.Spec.controllerName. - Updates manifests to use the controller name "k8s-gateway.nginx.org/nginx-gateway-controller". - Removes unused GatewayConfig CRD. Co-authored-by: Michael Pleshakov <[email protected]>
1 parent 3c90c22 commit 52a5b73

File tree

8 files changed

+52
-130
lines changed

8 files changed

+52
-130
lines changed

cmd/gateway/main.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import (
1212
)
1313

1414
const (
15-
domain string = "k8s-gateway.nginx.org"
16-
namespace string = "nginx-gateway"
15+
domain string = "k8s-gateway.nginx.org"
1716
)
1817

1918
var (
@@ -26,13 +25,14 @@ var (
2625
gatewayCtlrName = flag.String(
2726
"gateway-ctlr-name",
2827
"",
29-
fmt.Sprintf("The name of the Gateway controller. The controller name must be of the form: DOMAIN/NAMESPACE/NAME. The controller's domain is '%s'; the namespace is '%s'", domain, namespace),
28+
fmt.Sprintf("The name of the Gateway controller. The controller name must be of the form: DOMAIN/PATH. The controller's domain is '%s'", domain),
3029
)
3130

3231
gatewayClassName = flag.String(
3332
"gatewayclass",
3433
"",
35-
"The name of the GatewayClass resource. Every NGINX Gateway must have a unique corresponding GatewayClass resource")
34+
"The name of the GatewayClass resource. Every NGINX Gateway must have a unique corresponding GatewayClass resource",
35+
)
3636
)
3737

3838
func main() {
@@ -47,7 +47,7 @@ func main() {
4747

4848
MustValidateArguments(
4949
flag.CommandLine,
50-
GatewayControllerParam(domain, namespace /* FIXME(f5yacobucci) dynamically set */),
50+
GatewayControllerParam(domain),
5151
GatewayClassParam(),
5252
)
5353

cmd/gateway/setup.go

+21-24
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"regexp"
78
"strings"
89

910
flag "github.com/spf13/pflag"
1011
"k8s.io/apimachinery/pkg/util/validation"
12+
13+
// Adding a dummy import here to remind us to check the controllerNameRegex when we update the Gateway API version.
14+
_ "sigs.k8s.io/gateway-api/apis/v1beta1"
1115
)
1216

1317
const (
14-
errTmpl = "failed validation - flag: '--%s' reason: '%s'\n"
18+
errTmpl = "failed validation - flag: '--%s' reason: '%s'\n"
19+
controllerNameRegex = `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
1520
)
1621

1722
type (
@@ -22,13 +27,11 @@ type (
2227
}
2328
)
2429

25-
func GatewayControllerParam(domain string, namespace string) ValidatorContext {
30+
func GatewayControllerParam(domain string) ValidatorContext {
2631
name := "gateway-ctlr-name"
2732
return ValidatorContext{
2833
name,
2934
func(flagset *flag.FlagSet) error {
30-
// FIXME(f5yacobucci) this does not provide the same regex validation as
31-
// GatewayClass.ControllerName. provide equal and then specific validation
3235
param, err := flagset.GetString(name)
3336
if err != nil {
3437
return err
@@ -40,34 +43,28 @@ func GatewayControllerParam(domain string, namespace string) ValidatorContext {
4043

4144
fields := strings.Split(param, "/")
4245
l := len(fields)
43-
if l != 3 {
44-
return errors.New("unsupported path length, must be form DOMAIN/NAMESPACE/NAME")
46+
if l < 2 {
47+
return errors.New("invalid format; must be DOMAIN/PATH")
4548
}
4649

47-
for i := len(fields); i > 0; i-- {
48-
switch i {
49-
case 3:
50-
if fields[0] != domain {
51-
return fmt.Errorf("invalid domain: %s", fields[0])
52-
}
53-
fields = fields[1:]
54-
case 2:
55-
if fields[0] != namespace {
56-
return fmt.Errorf("cross namespace unsupported: %s", fields[0])
57-
}
58-
fields = fields[1:]
59-
case 1:
60-
if fields[0] == "" {
61-
return errors.New("must provide a name")
62-
}
63-
}
50+
if fields[0] != domain {
51+
return fmt.Errorf("invalid domain: %s; domain must be: %s", fields[0], domain)
6452
}
6553

66-
return nil
54+
return validateControllerName(param)
6755
},
6856
}
6957
}
7058

59+
func validateControllerName(name string) error {
60+
// Regex from: https://github.com/kubernetes-sigs/gateway-api/blob/547122f7f55ac0464685552898c560658fb40073/apis/v1alpha2/shared_types.go#L462
61+
re := regexp.MustCompile(controllerNameRegex)
62+
if !re.MatchString(name) {
63+
return fmt.Errorf("invalid gateway controller name: %s; expected format is DOMAIN/PATH", name)
64+
}
65+
return nil
66+
}
67+
7168
func GatewayClassParam() ValidatorContext {
7269
name := "gatewayclass"
7370
return ValidatorContext{

cmd/gateway/setup_test.go

+23-29
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ var _ = Describe("Main", func() {
156156
return testCase{
157157
Flag: "gateway-ctlr-name",
158158
Value: value,
159-
ValidatorContext: GatewayControllerParam("k8s-gateway.nginx.org", "nginx-gateway"),
159+
ValidatorContext: GatewayControllerParam("k8s-gateway.nginx.org"),
160160
ExpError: expError,
161161
}
162162
}
@@ -171,29 +171,32 @@ var _ = Describe("Main", func() {
171171
mockFlags = nil
172172
})
173173

174-
It("should parse full gateway-ctlr-name", func() {
175-
t := prepareTestCase(
176-
"k8s-gateway.nginx.org/nginx-gateway/my-gateway",
177-
expectSuccess,
178-
)
179-
tester(t)
180-
}) // should parse full gateway-ctlr-name
181-
182-
It("should fail with too many path elements", func() {
183-
t := prepareTestCase(
184-
"k8s-gateway.nginx.org/nginx-gateway/my-gateway/broken",
185-
expectError)
186-
tester(t)
187-
}) // should fail with too many path elements
174+
It("should parse valid gateway-ctlr-name", func() {
175+
table := []testCase{
176+
prepareTestCase(
177+
"k8s-gateway.nginx.org/my-gateway",
178+
expectSuccess,
179+
),
180+
prepareTestCase(
181+
"k8s-gateway.nginx.org/nginx-gateway/my-gateway",
182+
expectSuccess,
183+
),
184+
prepareTestCase(
185+
"k8s-gateway.nginx.org/nginx-gateway/my-gateway/v1",
186+
expectSuccess,
187+
),
188+
}
189+
runner(table)
190+
}) // should parse valid gateway-ctlr-name
188191

189192
It("should fail with too few path elements", func() {
190193
table := []testCase{
191194
prepareTestCase(
192-
"nginx-gateway/my-gateway",
195+
"k8s-gateway.nginx.org",
193196
expectError,
194197
),
195198
prepareTestCase(
196-
"my-gateway",
199+
"k8s-gateway.nginx.org/",
197200
expectError,
198201
),
199202
}
@@ -205,26 +208,17 @@ var _ = Describe("Main", func() {
205208
table := []testCase{
206209
prepareTestCase(
207210
// bad domain
208-
"invalid-domain/nginx-gateway/my-gateway",
211+
"invalid-domain/my-gateway",
209212
expectError,
210213
),
211214
prepareTestCase(
212215
// bad domain
213216
"/default/my-gateway",
214217
expectError,
215218
),
216-
prepareTestCase(
217-
// bad namespace
218-
"k8s-gateway.nginx.org/default/my-gateway",
219-
expectError),
220-
prepareTestCase(
221-
// bad namespace
222-
"k8s-gateway.nginx.org//my-gateway",
223-
expectError,
224-
),
225219
prepareTestCase(
226220
// bad name
227-
"k8s-gateway.nginx.org/default/",
221+
"k8s-gateway.nginx.org/",
228222
expectError,
229223
),
230224
}
@@ -266,7 +260,7 @@ var _ = Describe("Main", func() {
266260
"$nginx",
267261
expectError)
268262
tester(t)
269-
}) // should fail with invalid name"
263+
}) // should fail with invalid name
270264
}) // gatewayclass validation
271265
}) // CLI argument validation
272266
}) // end Main

deploy/manifests/crds/gateway.nginx.org_gatewayconfigs.yaml

-58
This file was deleted.

deploy/manifests/gatewayclass.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ kind: GatewayClass
33
metadata:
44
name: nginx
55
spec:
6-
controllerName: k8s-gateway.nginx.org/nginx-gateway/gateway
6+
controllerName: k8s-gateway.nginx.org/nginx-gateway-controller

deploy/manifests/gatewayconfig.yaml

-11
This file was deleted.

deploy/manifests/nginx-gateway.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ spec:
9898
# dropping ALL and adding only CAP_KILL doesn't work
9999
# Note: CAP_KILL is needed for sending HUP signal to NGINX main process
100100
args:
101-
- --gateway-ctlr-name=k8s-gateway.nginx.org/nginx-gateway/gateway
101+
- --gateway-ctlr-name=k8s-gateway.nginx.org/nginx-gateway-controller
102102
- --gatewayclass=nginx
103103
- image: nginx:1.23.1
104104
imagePullPolicy: IfNotPresent

docs/cli-args.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ The table below describes the command-line arguments of the `gateway` binary fro
44

55
| Name | Type | Description |
66
|-|-|-|
7-
|`gateway-ctlr-name` | `string` | The name of the Gateway controller. The controller name must be of the form: `DOMAIN/NAMESPACE/NAME`. The controller's domain is `k8s-gateway.nginx.org`; the namespace is `nginx-ingress`. |
7+
|`gateway-ctlr-name` | `string` | The name of the Gateway controller. The controller name must be of the form: `DOMAIN/PATH`. The controller's domain is `k8s-gateway.nginx.org`. |
88
|`gatewayclass`| `string` | The name of the GatewayClass resource. Every NGINX Gateway must have a unique corresponding GatewayClass resource. |

0 commit comments

Comments
 (0)