Skip to content

Commit

Permalink
[1.18] Backport configure NodePort with GatewayParams (#10563)
Browse files Browse the repository at this point in the history
  • Loading branch information
EItanya authored Jan 10, 2025
1 parent cdaa04d commit db4142d
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 2 deletions.
9 changes: 9 additions & 0 deletions changelog/v1.18.4/7504-gwapi-static-node-ports.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

changelog:
- type: FIX
issueLink: https://github.com/solo-io/solo-projects/issues/7504
resolvesIssue: true
description: >
Add a new Ports field to the `GatewayParameters` `Kube.Service` Spec in order to allow admin users
to configure additional information about the ports that the Gateway should listen on. This is useful
if the user wants to specify a static `NodePort`
Original file line number Diff line number Diff line change
Expand Up @@ -7678,6 +7678,13 @@ Resource Types:
<br/>
</td>
<td>false</td>
</tr><tr>
<td><b><a href="#gatewayparametersspeckubeserviceportsindex">ports</a></b></td>
<td>[]object</td>
<td>
<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>type</b></td>
<td>string</td>
Expand All @@ -7689,6 +7696,40 @@ Resource Types:
</table>


### GatewayParameters.spec.kube.service.ports[index]
<sup><sup>[↩ Parent](#gatewayparametersspeckubeservice)</sup></sup>





<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody><tr>
<td><b>port</b></td>
<td>integer</td>
<td>
<br/>
</td>
<td>true</td>
</tr><tr>
<td><b>nodePort</b></td>
<td>integer</td>
<td>
<br/>
</td>
<td>false</td>
</tr></tbody>
</table>


### GatewayParameters.spec.kube.serviceAccount
<sup><sup>[↩ Parent](#gatewayparametersspeckube)</sup></sup>

Expand Down
12 changes: 12 additions & 0 deletions install/helm/gloo/crds/gateway.gloo.solo.io_gatewayparameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,18 @@ spec:
additionalProperties:
type: string
type: object
ports:
items:
properties:
nodePort:
type: integer
port:
type: integer
required:
- port
type: object
maxItems: 8
type: array
type:
type: string
type: object
Expand Down
4 changes: 4 additions & 0 deletions install/helm/gloo/templates/43-gatewayparameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ spec:
extraAnnotations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with ($gg.service).ports }}
ports:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if $gg.serviceAccount }}
serviceAccount:
{{- with $gg.serviceAccount.extraLabels }}
Expand Down
14 changes: 14 additions & 0 deletions projects/gateway2/api/v1alpha1/gateway_parameters_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ type GatewayParametersSpec struct {
SelfManaged *SelfManagedGateway `json:"selfManaged,omitempty"`
}

func (in *GatewayParametersSpec) GetKube() *KubernetesProxyConfig {
if in == nil {
return nil
}
return in.Kube
}

func (in *GatewayParametersSpec) GetSelfManaged() *SelfManagedGateway {
if in == nil {
return nil
}
return in.SelfManaged
}

// The current conditions of the GatewayParameters. This is not currently implemented.
type GatewayParametersStatus struct {
}
Expand Down
40 changes: 40 additions & 0 deletions projects/gateway2/api/v1alpha1/kube_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ type Service struct {
// +kubebuilder:validation:Optional
ExtraAnnotations map[string]string `json:"extraAnnotations,omitempty"`

// Additional configuration for the service ports.
// The actual port numbers are specified in the Gateway resource.
//
// +optional
// +kubebuilder:validation:MaxItems=8
Ports []*Port `json:"ports"`
// External Traffic Policy on the Service object.
//
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -131,13 +137,47 @@ func (in *Service) GetExtraAnnotations() map[string]string {
return in.ExtraAnnotations
}

func (in *Service) GetPorts() []*Port {
if in == nil {
return nil
}
return in.Ports
}

func (in *Service) GetExternalTrafficPolicy() *corev1.ServiceExternalTrafficPolicy {
if in == nil {
return nil
}
return in.ExternalTrafficPolicy
}

type Port struct {
// The port number to match on the Gateway
//
// +kubebuilder:validation:Required
Port uint16 `json:"port"`

// The NodePort to be used for the service. If not specified, a random port
// will be assigned by the Kubernetes API server.
//
// +kubebuilder:validation:Optional
NodePort *uint16 `json:"nodePort,omitempty"`
}

func (in *Port) GetPort() uint16 {
if in == nil {
return 0
}
return in.Port
}

func (in *Port) GetNodePort() *uint16 {
if in == nil {
return nil
}
return in.NodePort
}

type ServiceAccount struct {
// Additional labels to add to the ServiceAccount object metadata.
//
Expand Down
31 changes: 31 additions & 0 deletions projects/gateway2/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion projects/gateway2/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (d *Deployer) getValues(gw *api.Gateway, gwParam *v1alpha1.GatewayParameter
Name: &gw.Name,
GatewayName: &gw.Name,
GatewayNamespace: &gw.Namespace,
Ports: getPortsValues(gw),
Ports: getPortsValues(gw, gwParam),
Xds: &helmXds{
// The xds host/port MUST map to the Service definition for the Control Plane
// This is the socket address that the Proxy will connect to on startup, to receive xds updates
Expand Down
37 changes: 37 additions & 0 deletions projects/gateway2/deployer/deployer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1255,9 +1255,46 @@ var _ = Describe("Deployer", func() {
port := svc.Spec.Ports[0]
Expect(port.Port).To(Equal(int32(80)))
Expect(port.TargetPort.IntVal).To(Equal(int32(8080)))
Expect(port.NodePort).To(Equal(int32(0)))
return nil
},
}),
Entry("static NodePort", &input{
dInputs: defaultDeployerInputs(),
gw: defaultGatewayWithGatewayParams(gwpOverrideName),
defaultGwp: defaultGatewayParams(),
overrideGwp: &gw2_v1alpha1.GatewayParameters{
ObjectMeta: metav1.ObjectMeta{
Name: gwpOverrideName,
Namespace: defaultNamespace,
},
Spec: gw2_v1alpha1.GatewayParametersSpec{
Kube: &gw2_v1alpha1.KubernetesProxyConfig{
Service: &gw2_v1alpha1.Service{
Type: ptr.To(corev1.ServiceTypeNodePort),
Ports: []*gw2_v1alpha1.Port{
{
Port: 80,
NodePort: ptr.To(uint16(30000)),
},
},
},
},
},
},
}, &expectedOutput{
validationFunc: func(objs clientObjects, inp *input) error {
svc := objs.findService(defaultNamespace, defaultServiceName)
Expect(svc).NotTo(BeNil())

port := svc.Spec.Ports[0]
Expect(port.Port).To(Equal(int32(80)))
Expect(port.TargetPort.IntVal).To(Equal(int32(8080)))
Expect(port.NodePort).To(Equal(int32(30000)))
return nil
},
}),

Entry("duplicate ports", &input{
dInputs: defaultDeployerInputs(),
gw: &api.Gateway{
Expand Down
1 change: 1 addition & 0 deletions projects/gateway2/deployer/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ func deepMergeService(dst, src *v1alpha1.Service) *v1alpha1.Service {

dst.ExtraLabels = deepMergeMaps(dst.GetExtraLabels(), src.GetExtraLabels())
dst.ExtraAnnotations = deepMergeMaps(dst.GetExtraAnnotations(), src.GetExtraAnnotations())
dst.Ports = deepMergeSlices(dst.GetPorts(), src.GetPorts())

if src.GetExternalTrafficPolicy() != nil {
dst.ExternalTrafficPolicy = src.GetExternalTrafficPolicy()
Expand Down
1 change: 1 addition & 0 deletions projects/gateway2/deployer/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type helmPort struct {
Protocol *string `json:"protocol,omitempty"`
Name *string `json:"name,omitempty"`
TargetPort *uint16 `json:"targetPort,omitempty"`
NodePort *uint16 `json:"nodePort,omitempty"`
}

type helmImage struct {
Expand Down
15 changes: 14 additions & 1 deletion projects/gateway2/deployer/values_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/solo-io/gloo/projects/gateway2/api/v1alpha1"
"github.com/solo-io/gloo/projects/gateway2/ports"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
api "sigs.k8s.io/gateway-api/apis/v1"
)
Expand All @@ -24,7 +25,7 @@ var ComponentLogLevelEmptyError = func(key string, value string) error {
// Extract the listener ports from a Gateway. These will be used to populate:
// 1. the ports exposed on the envoy container
// 2. the ports exposed on the proxy service
func getPortsValues(gw *api.Gateway) []helmPort {
func getPortsValues(gw *api.Gateway, gwp *v1alpha1.GatewayParameters) []helmPort {
gwPorts := []helmPort{}
for _, l := range gw.Spec.Listeners {
listenerPort := uint16(l.Port)
Expand All @@ -38,11 +39,23 @@ func getPortsValues(gw *api.Gateway) []helmPort {
portName := string(l.Name)
protocol := "TCP"

// Search for static NodePort set from the GatewayParameters spec
// If not found the default value of `nil` will not render anything.
var nodePort *uint16 = nil
if gwp.Spec.GetKube().GetService().GetType() != nil && *(gwp.Spec.GetKube().GetService().GetType()) == corev1.ServiceTypeNodePort {
if idx := slices.IndexFunc(gwp.Spec.GetKube().GetService().GetPorts(), func(p *v1alpha1.Port) bool {
return p.GetPort() == uint16(listenerPort)
}); idx != -1 {
nodePort = ptr.To(uint16(*gwp.Spec.GetKube().GetService().GetPorts()[idx].GetNodePort()))
}
}

gwPorts = append(gwPorts, helmPort{
Port: &listenerPort,
TargetPort: &targetPort,
Name: &portName,
Protocol: &protocol,
NodePort: nodePort,
})
}
return gwPorts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ spec:
protocol: {{ $p.protocol }}
targetPort: {{ $p.targetPort }}
port: {{ $p.port }}
nodePort: {{ $p.nodePort }}
{{- end }}
selector:
{{- include "gloo-gateway.gateway.selectorLabels" . | nindent 4 }}
Expand Down

0 comments on commit db4142d

Please sign in to comment.