Skip to content

Commit

Permalink
Validate pod IP at entry
Browse files Browse the repository at this point in the history
  • Loading branch information
sjberman committed May 16, 2023
1 parent 95ec715 commit f077362
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 15 deletions.
24 changes: 17 additions & 7 deletions cmd/gateway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,38 @@ var (
)

gatewayClassName = flag.String("gatewayclass", "", gatewayClassNameUsage)

// Environment variables
podIP = os.Getenv("POD_IP")
)

func main() {
flag.Parse()

MustValidateArguments(
flag.CommandLine,
GatewayControllerParam(domain),
GatewayClassParam(),
)

if err := ValidatePodIP(podIP); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}

logger := zap.New()
conf := config.Config{
GatewayCtlrName: *gatewayCtlrName,
Logger: logger,
GatewayClassName: *gatewayClassName,
PodIP: podIP,
}

MustValidateArguments(
flag.CommandLine,
GatewayControllerParam(domain),
GatewayClassParam(),
)

logger.Info("Starting NGINX Kubernetes Gateway",
"version", version,
"commit", commit,
"date", date)
"date", date,
)

err := manager.Start(conf)
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions cmd/gateway/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"errors"
"fmt"
"net"
"os"
"regexp"
"strings"
Expand All @@ -27,6 +28,12 @@ type (
V Validator
Key string
}

EnvValidator func(string) error
EnvValidatorContext struct {
V EnvValidator
Key string
}
)

func GatewayControllerParam(domain string) ValidatorContext {
Expand Down Expand Up @@ -120,3 +127,13 @@ func MustValidateArguments(flagset *flag.FlagSet, validators ...ValidatorContext
os.Exit(1)
}
}

func ValidatePodIP(podIP string) error {
if podIP == "" {
return errors.New("POD_IP environment variable must be set")
} else if net.ParseIP(podIP) == nil {
return fmt.Errorf("POD_IP '%s' must be a valid IP address", podIP)
}

return nil
}
13 changes: 13 additions & 0 deletions cmd/gateway/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,17 @@ var _ = Describe("Main", func() {
}) // should fail with invalid name
}) // gatewayclass validation
}) // CLI argument validation

Describe("environment variable validaton", func() {
It("should validate the POD_IP env var", func() {
// var not set
err := ValidatePodIP("")
Expect(err.Error()).To(ContainSubstring("must be set"))
// var set to invalid value
err = ValidatePodIP("invalid")
Expect(err.Error()).To(ContainSubstring("must be a valid"))
// var set to valid value
Expect(ValidatePodIP("1.2.3.4")).To(Succeed())
})
}) // environment variable validation
}) // end Main
2 changes: 2 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ type Config struct {
GatewayNsName types.NamespacedName
// GatewayClassName is the name of the GatewayClass resource that the Gateway will use.
GatewayClassName string
// PodIP is the IP address of this Pod.
PodIP string
}
1 change: 1 addition & 0 deletions internal/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func Start(cfg config.Config) error {
GatewayCtlrName: cfg.GatewayCtlrName,
GatewayClassName: cfg.GatewayClassName,
Client: mgr.GetClient(),
PodIP: cfg.PodIP,
// FIXME(pleshakov) Make sure each component:
// (1) Has a dedicated named logger.
// (2) Get it from the Manager (the WithName is done here for all components).
Expand Down
13 changes: 8 additions & 5 deletions internal/status/gateway.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package status

import (
"os"
"sort"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -24,7 +23,11 @@ const (
// FIXME(pleshakov): Be compliant with in the Gateway API.
// Currently, we only support simple valid/invalid status per each listener.
// Extend support to cover more cases.
func prepareGatewayStatus(gatewayStatus state.GatewayStatus, transitionTime metav1.Time) v1beta1.GatewayStatus {
func prepareGatewayStatus(
gatewayStatus state.GatewayStatus,
podIP string,
transitionTime metav1.Time,
) v1beta1.GatewayStatus {
listenerStatuses := make([]v1beta1.ListenerStatus, 0, len(gatewayStatus.ListenerStatuses))

// FIXME(pleshakov) Maintain the order from the Gateway resource
Expand All @@ -50,14 +53,14 @@ func prepareGatewayStatus(gatewayStatus state.GatewayStatus, transitionTime meta
}

ipAddrType := v1beta1.IPAddressType
podIP := v1beta1.GatewayAddress{
gwPodIP := v1beta1.GatewayAddress{
Type: &ipAddrType,
Value: os.Getenv("POD_IP"),
Value: podIP,
}

return v1beta1.GatewayStatus{
Listeners: listenerStatuses,
Addresses: []v1beta1.GatewayAddress{podIP},
Addresses: []v1beta1.GatewayAddress{gwPodIP},
Conditions: nil, // FIXME(pleshakov) Create conditions for the Gateway resource.
}
}
Expand Down
3 changes: 1 addition & 2 deletions internal/status/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
)

func TestPrepareGatewayStatus(t *testing.T) {
t.Setenv("POD_IP", "1.2.3.4")
ipAddrType := v1beta1.IPAddressType
podIP := v1beta1.GatewayAddress{
Type: &ipAddrType,
Expand Down Expand Up @@ -51,7 +50,7 @@ func TestPrepareGatewayStatus(t *testing.T) {

g := NewGomegaWithT(t)

result := prepareGatewayStatus(status, transitionTime)
result := prepareGatewayStatus(status, "1.2.3.4", transitionTime)
g.Expect(helpers.Diff(expected, result)).To(BeEmpty())
}

Expand Down
4 changes: 3 additions & 1 deletion internal/status/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type UpdaterConfig struct {
GatewayCtlrName string
// GatewayClassName is the name of the GatewayClass resource.
GatewayClassName string
// PodIP is the IP address of this Pod.
PodIP string
}

// updaterImpl updates statuses of the Gateway API resources.
Expand Down Expand Up @@ -101,7 +103,7 @@ func (upd *updaterImpl) Update(ctx context.Context, statuses state.Statuses) {
if statuses.GatewayStatus != nil {
upd.update(ctx, statuses.GatewayStatus.NsName, &v1beta1.Gateway{}, func(object client.Object) {
gw := object.(*v1beta1.Gateway)
gw.Status = prepareGatewayStatus(*statuses.GatewayStatus, upd.cfg.Clock.Now())
gw.Status = prepareGatewayStatus(*statuses.GatewayStatus, upd.cfg.PodIP, upd.cfg.Clock.Now())
})
}

Expand Down

0 comments on commit f077362

Please sign in to comment.