Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 27 additions & 0 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ on:
enable-experimental:
required: true
type: boolean
enable-inference-extension:
required: true
type: boolean
production-release:
required: false
type: boolean
Expand All @@ -32,6 +35,7 @@ defaults:
env:
PLUS_USAGE_ENDPOINT: ${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }}
ENABLE_EXPERIMENTAL: ${{ inputs.enable-experimental }}
ENABLE_INFERENCE_EXTENSION: ${{ inputs.enable-inference-extension }}

permissions:
contents: read
Expand Down Expand Up @@ -194,3 +198,26 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload ${{ github.ref_name }} conformance-profile.yaml --clobber
working-directory: ./tests

# The same setup works for inference conformance tests
# and inference extension flag is enabled
- name: Run inference conformance tests
run: |
make run-inference-conformance-tests CONFORMANCE_TAG=${{ github.sha }} NGF_VERSION=${{ github.ref_name }} CLUSTER_NAME=${{ github.run_id }}
core_result=$(cat conformance-inference-profile.yaml | yq '.profiles[0].core.result')
if [ "${core_result}" == "failure" ] ]; then echo "Inference Conformance test failed, see above for details." && exit 2; fi
working-directory: ./tests

- name: Upload profile to GitHub
if: ${{ inputs.enable-inference-extension }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: conformance-profile-inference-${{ inputs.image }}-${{ inputs.k8s-version }}-${{ steps.ngf-meta.outputs.version }}
path: ./tests/conformance-profile-inference.yaml

- name: Upload profile to release
if: ${{ inputs.production-release && inputs.enable-inference-extension }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload ${{ github.ref_name }} conformance-profile-inference.yaml --clobber
working-directory: ./tests
2 changes: 2 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ jobs:
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
with:
version: 3.14.0 # renovate: datasource=github-tags depName=helm/chart-testing
# v6.0.0 resolved the compatibility issue with Python > 3.13. may be removed after the action itself is updated
yamale_version: "6.0.0"

- name: Run chart-testing
run: ct lint --print-config --config .ct.yaml
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22
24
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ TELEMETRY_ENDPOINT=# if empty, NGF will report telemetry in its logs at debug le
TELEMETRY_ENDPOINT_INSECURE = false

ENABLE_EXPERIMENTAL ?= false
ENABLE_INFERENCE_EXTENSION ?= false

# go build flags - should not be overridden by the user
GO_LINKER_FlAGS_VARS = -X main.version=${VERSION} -X main.telemetryReportPeriod=${TELEMETRY_REPORT_PERIOD} -X main.telemetryEndpoint=${TELEMETRY_ENDPOINT} -X main.telemetryEndpointInsecure=${TELEMETRY_ENDPOINT_INSECURE}
Expand All @@ -33,7 +34,7 @@ GEN_CRD_API_REFERENCE_DOCS_VERSION = v0.3.0
# renovate: datasource=go depName=sigs.k8s.io/controller-tools
CONTROLLER_TOOLS_VERSION = v0.19.0
# renovate: datasource=docker depName=node
NODE_VERSION = 22
NODE_VERSION = 24
# renovate: datasource=docker depName=quay.io/helmpack/chart-testing
CHART_TESTING_VERSION = v3.14.0
# renovate: datasource=github-tags depName=dadav/helm-schema
Expand Down Expand Up @@ -139,6 +140,14 @@ install-gateway-crds: ## Install Gateway API CRDs
uninstall-gateway-crds: ## Uninstall Gateway API CRDs
kubectl kustomize $(SELF_DIR)config/crd/gateway-api/$(if $(filter true,$(ENABLE_EXPERIMENTAL)),experimental,standard) | kubectl delete -f -

.PHONY: install-inference-crds
install-inference-crds: ## Install Gateway API Inference Extension CRDs
kubectl kustomize $(SELF_DIR)config/crd/inference-extension | kubectl apply -f -

.PHONY: uninstall-inference-crds
uninstall-inference-crds: ## Uninstall Gateway API Inference Extension CRDs
kubectl kustomize $(SELF_DIR)config/crd/inference-extension | kubectl delete -f -

.PHONY: generate-manifests
generate-manifests: ## Generate manifests using Helm.
./scripts/generate-manifests.sh
Expand Down Expand Up @@ -229,10 +238,16 @@ install-ngf-local-build-with-plus: check-for-plus-usage-endpoint build-images-wi

.PHONY: helm-install-local
helm-install-local: install-gateway-crds ## Helm install NGF on configured kind cluster with local images. To build, load, and install with helm run make install-ngf-local-build.
helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PREFIX) --create-namespace --wait --set nginxGateway.image.pullPolicy=$(PULL_POLICY) --set nginx.service.type=$(NGINX_SERVICE_TYPE) --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=$(PULL_POLICY) --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway $(HELM_PARAMETERS)
@if [ "$(ENABLE_INFERENCE_EXTENSION)" = "true" ]; then \
$(MAKE) install-inference-crds; \
fi
helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PREFIX) --create-namespace --wait --set nginxGateway.image.pullPolicy=Never --set nginx.service.type=NodePort --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway $(HELM_PARAMETERS)

.PHONY: helm-install-local-with-plus
helm-install-local-with-plus: check-for-plus-usage-endpoint install-gateway-crds ## Helm install NGF with NGINX Plus on configured kind cluster with local images. To build, load, and install with helm run make install-ngf-local-build-with-plus.
@if [ "$(ENABLE_INFERENCE_EXTENSION)" = "true" ]; then \
$(MAKE) install-inference-crds; \
fi
kubectl create namespace nginx-gateway || true
kubectl -n nginx-gateway create secret generic nplus-license --from-file $(PLUS_LICENSE_FILE) || true
helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PLUS_PREFIX) --wait --set nginxGateway.image.pullPolicy=$(PULL_POLICY) --set nginx.service.type=$(NGINX_SERVICE_TYPE) --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=$(PULL_POLICY) --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway --set nginx.plus=true --set nginx.usage.endpoint=$(PLUS_USAGE_ENDPOINT) $(HELM_PARAMETERS)
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.nginx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN apk add --no-cache bash \
&& ln -sf /dev/stderr /var/log/nginx/error.log

COPY build/entrypoint.sh /agent/entrypoint.sh
COPY ${NJS_DIR}/httpmatches.js /usr/lib/nginx/modules/njs/httpmatches.js
COPY ${NJS_DIR}/ /usr/lib/nginx/modules/njs/
COPY ${NGINX_CONF_DIR}/nginx.conf /etc/nginx/nginx.conf
COPY ${NGINX_CONF_DIR}/grpc-error-locations.conf /etc/nginx/grpc-error-locations.conf
COPY ${NGINX_CONF_DIR}/grpc-error-pages.conf /etc/nginx/grpc-error-pages.conf
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.nginxplus
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ RUN apk add --no-cache bash \
&& ln -sf /dev/stderr /var/log/nginx/error.log

COPY build/entrypoint.sh /agent/entrypoint.sh
COPY ${NJS_DIR}/httpmatches.js /usr/lib/nginx/modules/njs/httpmatches.js
COPY ${NJS_DIR}/ /usr/lib/nginx/modules/njs/
COPY ${NGINX_CONF_DIR}/nginx-plus.conf /etc/nginx/nginx.conf
COPY ${NGINX_CONF_DIR}/grpc-error-locations.conf /etc/nginx/grpc-error-locations.conf
COPY ${NGINX_CONF_DIR}/grpc-error-pages.conf /etc/nginx/grpc-error-pages.conf
Expand Down
3 changes: 2 additions & 1 deletion charts/nginx-gateway-fabric/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `nginx.usage.resolver` | The nameserver used to resolve the NGINX Plus usage reporting endpoint. Used with NGINX Instance Manager. | string | `""` |
| `nginx.usage.secretName` | The name of the Secret containing the JWT for NGINX Plus usage reporting. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `"nplus-license"` |
| `nginx.usage.skipVerify` | Disable client verification of the NGINX Plus usage reporting server certificate. | bool | `false` |
| `nginxGateway` | The nginxGateway section contains configuration for the NGINX Gateway Fabric control plane deployment. | object | `{"affinity":{},"autoscaling":{"enable":false},"config":{"logging":{"level":"info"}},"configAnnotations":{},"extraVolumeMounts":[],"extraVolumes":[],"gatewayClassAnnotations":{},"gatewayClassName":"nginx","gatewayControllerName":"gateway.nginx.org/nginx-gateway-controller","gwAPIExperimentalFeatures":{"enable":false},"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric","tag":"edge"},"kind":"deployment","labels":{},"leaderElection":{"enable":true,"lockName":""},"lifecycle":{},"metrics":{"enable":true,"port":9113,"secure":false},"name":"","nodeSelector":{},"podAnnotations":{},"productTelemetry":{"enable":true},"readinessProbe":{"enable":true,"initialDelaySeconds":3,"port":8081},"replicas":1,"resources":{},"service":{"annotations":{},"labels":{}},"serviceAccount":{"annotations":{},"imagePullSecret":"","imagePullSecrets":[],"name":""},"snippetsFilters":{"enable":false},"terminationGracePeriodSeconds":30,"tolerations":[],"topologySpreadConstraints":[]}` |
| `nginxGateway` | The nginxGateway section contains configuration for the NGINX Gateway Fabric control plane deployment. | object | `{"affinity":{},"autoscaling":{"enable":false},"config":{"logging":{"level":"info"}},"configAnnotations":{},"extraVolumeMounts":[],"extraVolumes":[],"gatewayClassAnnotations":{},"gatewayClassName":"nginx","gatewayControllerName":"gateway.nginx.org/nginx-gateway-controller","gwAPIExperimentalFeatures":{"enable":false},"gwAPIInferenceExtension":{"enable":false},"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric","tag":"edge"},"kind":"deployment","labels":{},"leaderElection":{"enable":true,"lockName":""},"lifecycle":{},"metrics":{"enable":true,"port":9113,"secure":false},"name":"","nodeSelector":{},"podAnnotations":{},"productTelemetry":{"enable":true},"readinessProbe":{"enable":true,"initialDelaySeconds":3,"port":8081},"replicas":1,"resources":{},"service":{"annotations":{},"labels":{}},"serviceAccount":{"annotations":{},"imagePullSecret":"","imagePullSecrets":[],"name":""},"snippetsFilters":{"enable":false},"terminationGracePeriodSeconds":30,"tolerations":[],"topologySpreadConstraints":[]}` |
| `nginxGateway.affinity` | The affinity of the NGINX Gateway Fabric control plane pod. | object | `{}` |
| `nginxGateway.autoscaling` | Autoscaling configuration for the NGINX Gateway Fabric control plane. | object | `{"enable":false}` |
| `nginxGateway.autoscaling.enable` | Enable or disable Horizontal Pod Autoscaler for the control plane. | bool | `false` |
Expand All @@ -257,6 +257,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `nginxGateway.gatewayClassName` | The name of the GatewayClass that will be created as part of this release. Every NGINX Gateway Fabric must have a unique corresponding GatewayClass resource. NGINX Gateway Fabric only processes resources that belong to its class - i.e. have the "gatewayClassName" field resource equal to the class. | string | `"nginx"` |
| `nginxGateway.gatewayControllerName` | The name of the Gateway controller. The controller name must be of the form: DOMAIN/PATH. The controller's domain is gateway.nginx.org. | string | `"gateway.nginx.org/nginx-gateway-controller"` |
| `nginxGateway.gwAPIExperimentalFeatures.enable` | Enable the experimental features of Gateway API which are supported by NGINX Gateway Fabric. Requires the Gateway APIs installed from the experimental channel. | bool | `false` |
| `nginxGateway.gwAPIInferenceExtension.enable` | Enable Gateway API Inference Extension support. Allows for configuring InferencePools to route traffic to AI workloads. | bool | `false` |
| `nginxGateway.image` | The image configuration for the NGINX Gateway Fabric control plane. | object | `{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric","tag":"edge"}` |
| `nginxGateway.image.repository` | The NGINX Gateway Fabric image to use | string | `"ghcr.io/nginx/nginx-gateway-fabric"` |
| `nginxGateway.kind` | The kind of the NGINX Gateway Fabric installation - currently, only deployment is supported. | string | `"deployment"` |
Expand Down
16 changes: 16 additions & 0 deletions charts/nginx-gateway-fabric/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ rules:
{{- end }}
verbs:
- update
{{- if .Values.nginxGateway.gwAPIInferenceExtension.enable }}
- apiGroups:
- inference.networking.k8s.io
resources:
- inferencepools
verbs:
- get
- list
- watch
- apiGroups:
- inference.networking.k8s.io
resources:
- inferencepools/status
verbs:
- update
{{- end }}
{{- if .Values.nginxGateway.leaderElection.enable }}
- apiGroups:
- coordination.k8s.io
Expand Down
3 changes: 3 additions & 0 deletions charts/nginx-gateway-fabric/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ spec:
{{- if .Values.nginxGateway.gwAPIExperimentalFeatures.enable }}
- --gateway-api-experimental-features
{{- end }}
{{- if .Values.nginxGateway.gwAPIInferenceExtension.enable }}
- --gateway-api-inference-extension
{{- end }}
{{- if .Values.nginxGateway.snippetsFilters.enable }}
- --snippets-filters
{{- end }}
Expand Down
14 changes: 14 additions & 0 deletions charts/nginx-gateway-fabric/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,20 @@
"title": "gwAPIExperimentalFeatures",
"type": "object"
},
"gwAPIInferenceExtension": {
"properties": {
"enable": {
"default": false,
"description": "Enable Gateway API Inference Extension support. Allows for configuring InferencePools to route traffic to AI workloads.",
"required": [],
"title": "enable",
"type": "boolean"
}
},
"required": [],
"title": "gwAPIInferenceExtension",
"type": "object"
},
"image": {
"description": "The image configuration for the NGINX Gateway Fabric control plane.",
"properties": {
Expand Down
4 changes: 4 additions & 0 deletions charts/nginx-gateway-fabric/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ nginxGateway:
# APIs installed from the experimental channel.
enable: false

gwAPIInferenceExtension:
# -- Enable Gateway API Inference Extension support. Allows for configuring InferencePools to route traffic to AI workloads.
enable: false

snippetsFilters:
# -- Enable SnippetsFilters feature. SnippetsFilters allow inserting NGINX configuration into the generated NGINX
# config for HTTPRoute and GRPCRoute resources.
Expand Down
25 changes: 25 additions & 0 deletions cmd/gateway/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func createControllerCommand() *cobra.Command {
leaderElectionLockNameFlag = "leader-election-lock-name"
productTelemetryDisableFlag = "product-telemetry-disable"
gwAPIExperimentalFlag = "gateway-api-experimental-features"
gwAPIInferenceExtensionFlag = "gateway-api-inference-extension"
nginxDockerSecretFlag = "nginx-docker-secret" //nolint:gosec // not credentials
usageReportSecretFlag = "usage-report-secret"
usageReportEndpointFlag = "usage-report-endpoint"
Expand Down Expand Up @@ -151,6 +152,7 @@ func createControllerCommand() *cobra.Command {
}

gwExperimentalFeatures bool
gwInferenceExtension bool

disableProductTelemetry bool

Expand Down Expand Up @@ -270,6 +272,7 @@ func createControllerCommand() *cobra.Command {
},
Plus: plus,
ExperimentalFeatures: gwExperimentalFeatures,
InferenceExtension: gwInferenceExtension,
ImageSource: imageSource,
Flags: config.Flags{
Names: flagKeys,
Expand Down Expand Up @@ -430,6 +433,14 @@ func createControllerCommand() *cobra.Command {
"Requires the Gateway APIs installed from the experimental channel.",
)

cmd.Flags().BoolVar(
&gwInferenceExtension,
gwAPIInferenceExtensionFlag,
false,
"Enable Gateway API Inference Extension support. Allows for configuring InferencePools to route "+
"traffic to AI workloads.",
)

cmd.Flags().Var(
&nginxDockerSecrets,
nginxDockerSecretFlag,
Expand Down Expand Up @@ -746,6 +757,20 @@ func createSleepCommand() *cobra.Command {
return cmd
}

func createEndpointPickerCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "endpoint-picker",
Short: "Shim server for communication between NGINX and the Gateway API Inference Extension Endpoint Picker",
RunE: func(_ *cobra.Command, _ []string) error {
logger := ctlrZap.New().WithName("endpoint-picker-shim")
handler := createEndpointPickerHandler(realExtProcClientFactory(), logger)
return endpointPickerServer(handler)
},
}

return cmd
}

func parseFlags(flags *pflag.FlagSet) ([]string, []string) {
var flagKeys, flagValues []string

Expand Down
Loading