Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for TLS route #2211

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add suport for tls route
  • Loading branch information
sarthyparty committed Aug 8, 2024
commit e1de7fdfde305ba7565e3517f2c9cec67bbfd6b5
2 changes: 2 additions & 0 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
@@ -75,6 +75,7 @@ jobs:
run: |
ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric
ngf_tag=${{ steps.ngf-meta.outputs.version }}
if [ ${{ inputs.enable-experimental }} == "true" ]; then export ENABLE_EXPERIMENTAL=true; fi
make generate-static-deployment PLUS_ENABLED=${{ inputs.image == 'plus' && 'true' || 'false' }} PREFIX=${ngf_prefix} TAG=${ngf_tag}
working-directory: ./tests

@@ -146,6 +147,7 @@ jobs:

- name: Run conformance tests
run: |
if [ ${{ inputs.enable-experimental }} == "true" ]; then export ENABLE_EXPERIMENTAL=true; fi
make run-conformance-tests CONFORMANCE_TAG=${{ github.sha }} NGF_VERSION=${{ github.ref_name }} CLUSTER_NAME=${{ github.run_id }}
core_result=$(cat conformance-profile.yaml | yq '.profiles[0].core.result')
extended_result=$(cat conformance-profile.yaml | yq '.profiles[0].extended.result')
2 changes: 2 additions & 0 deletions charts/nginx-gateway-fabric/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ rules:
- grpcroutes
{{- if .Values.nginxGateway.gwAPIExperimentalFeatures.enable }}
- backendtlspolicies
- tlsroutes
{{- end }}
verbs:
- list
@@ -85,6 +86,7 @@ rules:
- grpcroutes/status
{{- if .Values.nginxGateway.gwAPIExperimentalFeatures.enable }}
- backendtlspolicies/status
- tlsroutes/status
{{- end }}
verbs:
- update
2 changes: 2 additions & 0 deletions deploy/experimental-nginx-plus/deploy.yaml
Original file line number Diff line number Diff line change
@@ -82,6 +82,7 @@ rules:
- referencegrants
- grpcroutes
- backendtlspolicies
- tlsroutes
verbs:
- list
- watch
@@ -93,6 +94,7 @@ rules:
- gatewayclasses/status
- grpcroutes/status
- backendtlspolicies/status
- tlsroutes/status
verbs:
- update
- apiGroups:
2 changes: 2 additions & 0 deletions deploy/experimental/deploy.yaml
Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@ rules:
- referencegrants
- grpcroutes
- backendtlspolicies
- tlsroutes
verbs:
- list
- watch
@@ -85,6 +86,7 @@ rules:
- gatewayclasses/status
- grpcroutes/status
- backendtlspolicies/status
- tlsroutes/status
verbs:
- update
- apiGroups:
1 change: 1 addition & 0 deletions internal/framework/gatewayclass/validate.go
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ var gatewayCRDs = map[string]apiVersion{
"referencegrants.gateway.networking.k8s.io": {},
"backendtlspolicies.gateway.networking.k8s.io": {},
"grpcroutes.gateway.networking.k8s.io": {},
"tlsroutes.gateway.networking.k8s.io": {},
}

type apiVersion struct {
2 changes: 2 additions & 0 deletions internal/framework/kinds/kinds.go
Original file line number Diff line number Diff line change
@@ -19,6 +19,8 @@ const (
HTTPRoute = "HTTPRoute"
// GRPCRoute is the GRPCRoute kind.
GRPCRoute = "GRPCRoute"
// TLSRoute is the TLSRoute kind.
TLSRoute = "TLSRoute"
)

// NGINX Gateway Fabric kinds.
1 change: 1 addition & 0 deletions internal/mode/static/handler.go
Original file line number Diff line number Diff line change
@@ -246,6 +246,7 @@ func (h *eventHandlerImpl) updateStatuses(ctx context.Context, logger logr.Logge
gcReqs = status.PrepareGatewayClassRequests(graph.GatewayClass, graph.IgnoredGatewayClasses, transitionTime)
}
routeReqs := status.PrepareRouteRequests(
graph.L4Routes,
graph.Routes,
transitionTime,
h.latestReloadResult,
9 changes: 9 additions & 0 deletions internal/mode/static/manager.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ import (
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
k8spredicate "sigs.k8s.io/controller-runtime/pkg/predicate"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

@@ -73,6 +74,7 @@ func init() {
utilruntime.Must(gatewayv1beta1.Install(scheme))
utilruntime.Must(gatewayv1.Install(scheme))
utilruntime.Must(gatewayv1alpha3.Install(scheme))
utilruntime.Must(gatewayv1alpha2.Install(scheme))
utilruntime.Must(apiv1.AddToScheme(scheme))
utilruntime.Must(discoveryV1.AddToScheme(scheme))
utilruntime.Must(ngfAPI.AddToScheme(scheme))
@@ -489,6 +491,12 @@ func registerControllers(
// https://github.com/nginxinc/nginx-gateway-fabric/issues/1545
objectType: &apiv1.ConfigMap{},
},
{
objectType: &gatewayv1alpha2.TLSRoute{},
options: []controller.Option{
controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}),
},
},
sarthyparty marked this conversation as resolved.
Show resolved Hide resolved
}
controllerRegCfgs = append(controllerRegCfgs, gwExpFeatures...)
}
@@ -663,6 +671,7 @@ func prepareFirstEventBatchPreparerArgs(
objectLists,
&gatewayv1alpha3.BackendTLSPolicyList{},
&apiv1.ConfigMapList{},
&gatewayv1alpha2.TLSRouteList{},
)
}

2 changes: 2 additions & 0 deletions internal/mode/static/manager_test.go
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

@@ -105,6 +106,7 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) {
&ngfAPI.NginxProxyList{},
partialObjectMetadataList,
&gatewayv1alpha3.BackendTLSPolicyList{},
&gatewayv1alpha2.TLSRouteList{},
&gatewayv1.GRPCRouteList{},
&ngfAPI.ClientSettingsPolicyList{},
&ngfAPI.ObservabilityPolicyList{},
10 changes: 8 additions & 2 deletions internal/mode/static/nginx/config/generator_test.go
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import (
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config"
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file"
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane"
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver"
)

func TestGenerate(t *testing.T) {
@@ -62,8 +63,13 @@ func TestGenerate(t *testing.T) {
},
StreamUpstreams: []dataplane.Upstream{
{
Name: "stream_up",
Endpoints: nil,
Name: "stream_up",
Endpoints: []resolver.Endpoint{
{
Address: "1.1.1.1",
Port: 80,
},
},
},
},
BackendGroups: []dataplane.BackendGroup{bg},
11 changes: 4 additions & 7 deletions internal/mode/static/nginx/config/http/config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package http

import "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/shared"

const InternalRoutePathPrefix = "/_ngf-internal"

// Server holds all configuration for an HTTP server.
@@ -12,12 +14,7 @@ type Server struct {
IsDefaultHTTP bool
IsDefaultSSL bool
GRPC bool
}

// IPFamily holds the IP family configuration to be used by NGINX.
type IPFamily struct {
IPv4 bool
IPv6 bool
IsSocket bool
}

type LocationType string
@@ -113,7 +110,7 @@ type ProxySSLVerify struct {
// ServerConfig holds configuration for an HTTP server and IP family to be used by NGINX.
type ServerConfig struct {
Servers []Server
IPFamily IPFamily
IPFamily shared.IPFamily
}

// Include defines a file that's included via the include directive.
62 changes: 43 additions & 19 deletions internal/mode/static/nginx/config/maps.go
Original file line number Diff line number Diff line change
@@ -11,12 +11,18 @@ import (

var mapsTemplate = gotemplate.Must(gotemplate.New("maps").Parse(mapsTemplateText))

// emptyStringSocket is used when the stream server has an invalid upstream. In this case, we pass the connection
// to the empty socket so that NGINX will close the connection with an error in the error log --
// no host in pass "" -- and set $status variable to 500 (logged by stream access log),
// which will indicate the problem to the user.
// https://nginx.org/en/docs/stream/ngx_stream_core_module.html#var_status
const emptyStringSocket = `""`
const (
// emptyStringSocket is used when the stream server has an invalid upstream. In this case, we pass the connection
// to the empty socket so that NGINX will close the connection with an error in the error log --
// no host in pass "" -- and set $status variable to 500 (logged by stream access log),
// which will indicate the problem to the user.
// https://nginx.org/en/docs/stream/ngx_stream_core_module.html#var_status
emptyStringSocket = `""`

// connectionClosedStreamServerSocket is used when we want to listen on a port but have no service configured,
// so we pass to this server that just returns an empty string to tell users that we are listening.
connectionClosedStreamServerSocket = "unix:/var/run/nginx/connection-closed-server.sock"
sarthyparty marked this conversation as resolved.
Show resolved Hide resolved
)

func executeMaps(conf dataplane.Configuration) []executeResult {
maps := buildAddHeaderMaps(append(conf.HTTPServers, conf.SSLServers...))
@@ -44,32 +50,43 @@ func createStreamMaps(conf dataplane.Configuration) []shared.Map {
return nil
}
portsToMap := make(map[int32]shared.Map)
portHasDefault := make(map[int32]struct{})
upstreams := make(map[string]dataplane.Upstream)

for _, u := range conf.StreamUpstreams {
upstreams[u.Name] = u
}

for _, server := range conf.TLSPassthroughServers {
streamMap, portInUse := portsToMap[server.Port]

socket := emptyStringSocket

if server.UpstreamName != "" {
if u, ok := upstreams[server.UpstreamName]; ok && server.UpstreamName != "" && len(u.Endpoints) > 0 {
socket = getSocketNameTLS(server.Port, server.Hostname)
}

mapParam := shared.MapParameter{
Value: server.Hostname,
Result: socket,
if server.IsDefault {
socket = connectionClosedStreamServerSocket
}

if !portInUse {
m := shared.Map{
Source: "$ssl_preread_server_name",
Variable: getTLSPassthroughVarName(server.Port),
Parameters: []shared.MapParameter{
mapParam,
},
streamMap = shared.Map{
Source: "$ssl_preread_server_name",
Variable: getTLSPassthroughVarName(server.Port),
Parameters: make([]shared.MapParameter, 0),
UseHostnames: true,
}
portsToMap[server.Port] = m
} else {
portsToMap[server.Port] = streamMap
}

// If the hostname is empty, we don't want to add an entry to the map. This case occurs when
// the gateway listener hostname is not specified
if server.Hostname != "" {
mapParam := shared.MapParameter{
Value: server.Hostname,
Result: socket,
}
streamMap.Parameters = append(streamMap.Parameters, mapParam)
portsToMap[server.Port] = streamMap
}
@@ -82,6 +99,7 @@ func createStreamMaps(conf dataplane.Configuration) []shared.Map {

if server.IsDefault {
hostname = "default"
portHasDefault[server.Port] = struct{}{}
}

if portInUse {
@@ -95,7 +113,13 @@ func createStreamMaps(conf dataplane.Configuration) []shared.Map {

maps := make([]shared.Map, 0, len(portsToMap))

for _, m := range portsToMap {
for p, m := range portsToMap {
if _, ok := portHasDefault[p]; !ok {
m.Parameters = append(m.Parameters, shared.MapParameter{
Value: "default",
Result: connectionClosedStreamServerSocket,
})
}
maps = append(maps, m)
}

3 changes: 1 addition & 2 deletions internal/mode/static/nginx/config/maps_template.go
Original file line number Diff line number Diff line change
@@ -3,10 +3,9 @@ package config
const mapsTemplateText = `
{{ range $m := . }}
map {{ $m.Source }} {{ $m.Variable }} {
{{- if $m.UseHostnames -}}
{{- if $m.UseHostnames }}
hostnames;
{{ end }}

{{ range $p := $m.Parameters }}
{{ $p.Value }} {{ $p.Result }};
{{ end }}
Loading