diff --git a/build/Dockerfile b/build/Dockerfile index f546c15de4..c1b7a6a29b 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -11,25 +11,8 @@ RUN make build FROM golang:1.23 AS ca-certs-provider -FROM alpine:3.20 AS capabilizer -RUN apk add --no-cache libcap - -FROM capabilizer AS local-capabilizer -COPY ./build/out/gateway /usr/bin/ -RUN setcap 'cap_kill=+ep' /usr/bin/gateway - -FROM capabilizer AS container-capabilizer -COPY --from=builder /go/src/github.com/nginxinc/nginx-gateway-fabric/build/out/gateway /usr/bin/ -RUN setcap 'cap_kill=+ep' /usr/bin/gateway - -FROM capabilizer AS goreleaser-capabilizer -ARG TARGETARCH -COPY dist/gateway_linux_$TARGETARCH*/gateway /usr/bin/ -RUN setcap 'cap_kill=+ep' /usr/bin/gateway - FROM scratch AS common -# CA certs are needed for telemetry report and NGINX Plus usage report features, so that -# NGF can verify the server's certificate. +# CA certs are needed for telemetry report so that NGF can verify the server's certificate. COPY --from=ca-certs-provider --link /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ USER 102:1001 ARG BUILD_AGENT @@ -37,10 +20,11 @@ ENV BUILD_AGENT=${BUILD_AGENT} ENTRYPOINT [ "/usr/bin/gateway" ] FROM common AS container -COPY --from=container-capabilizer /usr/bin/gateway /usr/bin/ +COPY --from=builder /go/src/github.com/nginxinc/nginx-gateway-fabric/build/out/gateway /usr/bin/ FROM common AS local -COPY --from=local-capabilizer /usr/bin/gateway /usr/bin/ +COPY ./build/out/gateway /usr/bin/ FROM common AS goreleaser -COPY --from=goreleaser-capabilizer /usr/bin/gateway /usr/bin/ +ARG TARGETARCH +COPY dist/gateway_linux_$TARGETARCH*/gateway /usr/bin/ diff --git a/charts/nginx-gateway-fabric/README.md b/charts/nginx-gateway-fabric/README.md index a2136f24a0..9fdd20bca7 100644 --- a/charts/nginx-gateway-fabric/README.md +++ b/charts/nginx-gateway-fabric/README.md @@ -268,6 +268,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri | `nginx.image.tag` | | string | `"edge"` | | `nginx.lifecycle` | The lifecycle of the nginx container. | object | `{}` | | `nginx.plus` | Is NGINX Plus image being used | bool | `false` | +| `nginx.securityContext.allowPrivilegeEscalation` | Some environments may need this set to true in order for the control plane to successfully reload NGINX. | bool | `false` | | `nginx.usage.caSecretName` | The name of the Secret containing the NGINX Instance Manager CA certificate. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` | | `nginx.usage.clientSSLSecretName` | The name of the Secret containing the client certificate and key for authenticating with NGINX Instance Manager. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` | | `nginx.usage.endpoint` | The endpoint of the NGINX Plus usage reporting server. Default: product.connect.nginx.com | string | `""` | @@ -295,7 +296,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri | `nginxGateway.readinessProbe.port` | Port in which the readiness endpoint is exposed. | int | `8081` | | `nginxGateway.replicaCount` | The number of replicas of the NGINX Gateway Fabric Deployment. | int | `1` | | `nginxGateway.resources` | The resource requests and/or limits of the nginx-gateway container. | object | `{}` | -| `nginxGateway.securityContext.allowPrivilegeEscalation` | Some environments may need this set to true in order for the control plane to successfully reload NGINX. | bool | `false` | +| `nginxGateway.service.annotations` | The annotations of the NGINX Gateway Fabric control plane service. | object | `{}` | | `nginxGateway.snippetsFilters.enable` | Enable SnippetsFilters feature. SnippetsFilters allow inserting NGINX configuration into the generated NGINX config for HTTPRoute and GRPCRoute resources. | bool | `false` | | `nodeSelector` | The nodeSelector of the NGINX Gateway Fabric pod. | object | `{}` | | `service.annotations` | The annotations of the NGINX Gateway Fabric service. | object | `{}` | diff --git a/charts/nginx-gateway-fabric/templates/deployment.yaml b/charts/nginx-gateway-fabric/templates/deployment.yaml index 4149bdf587..00fef5f7f2 100644 --- a/charts/nginx-gateway-fabric/templates/deployment.yaml +++ b/charts/nginx-gateway-fabric/templates/deployment.yaml @@ -33,43 +33,6 @@ spec: topologySpreadConstraints: {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} {{- end }} - initContainers: - - name: init - image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }} - imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }} - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - {{- if .Values.nginx.plus }} - - --source - - /includes/mgmt.conf - - --nginx-plus - {{- end }} - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - securityContext: - seccompProfile: - type: RuntimeDefault - capabilities: - add: - - KILL # Set because the binary has CAP_KILL for the main controller process. Not used by init. - drop: - - ALL - readOnlyRootFilesystem: true - runAsUser: 102 - runAsGroup: 1001 - volumeMounts: - - name: nginx-includes-bootstrap - mountPath: /includes - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes containers: - args: - static-mode @@ -171,99 +134,21 @@ spec: securityContext: seccompProfile: type: RuntimeDefault - allowPrivilegeEscalation: {{ .Values.nginxGateway.securityContext.allowPrivilegeEscalation }} capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true runAsUser: 102 runAsGroup: 1001 - volumeMounts: - - name: nginx-conf - mountPath: /etc/nginx/conf.d - - name: nginx-stream-conf - mountPath: /etc/nginx/stream-conf.d - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes - - name: nginx-secrets - mountPath: /etc/nginx/secrets - - name: nginx-run - mountPath: /var/run/nginx - - name: nginx-includes - mountPath: /etc/nginx/includes {{- with .Values.nginxGateway.extraVolumeMounts -}} {{ toYaml . | nindent 8 }} {{- end }} - - image: {{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag | default .Chart.AppVersion }} - imagePullPolicy: {{ .Values.nginx.image.pullPolicy }} - name: nginx - {{- if .Values.nginx.lifecycle }} - lifecycle: - {{- toYaml .Values.nginx.lifecycle | nindent 10 }} - {{- end }} - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - seccompProfile: - type: RuntimeDefault - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsUser: 101 - runAsGroup: 1001 - volumeMounts: - - name: nginx-conf - mountPath: /etc/nginx/conf.d - - name: nginx-stream-conf - mountPath: /etc/nginx/stream-conf.d - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes - - name: nginx-secrets - mountPath: /etc/nginx/secrets - - name: nginx-run - mountPath: /var/run/nginx - - name: nginx-cache - mountPath: /var/cache/nginx - - name: nginx-includes - mountPath: /etc/nginx/includes - {{- if .Values.nginx.plus }} - - name: nginx-lib - mountPath: /var/lib/nginx/state - {{- if .Values.nginx.usage.secretName }} - - name: nginx-plus-license - mountPath: /etc/nginx/license.jwt - subPath: license.jwt - {{- end }} - {{- if or .Values.nginx.usage.caSecretName .Values.nginx.usage.clientSSLSecretName }} - - name: nginx-plus-usage-certs - mountPath: /etc/nginx/certs-bootstrap/ - {{- end }} - {{- end }} - {{- with .Values.nginx.extraVolumeMounts -}} - {{ toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.nginx.debug }} - command: - - "/bin/sh" - args: - - "-c" - - "rm -rf /var/run/nginx/*.sock && nginx-debug -g 'daemon off;'" - {{- end }} terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} {{- if .Values.affinity }} affinity: {{- toYaml .Values.affinity | nindent 8 }} {{- end }} serviceAccountName: {{ include "nginx-gateway.serviceAccountName" . }} - shareProcessNamespace: true securityContext: fsGroup: 1001 runAsNonRoot: true @@ -275,46 +160,6 @@ spec: nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} {{- end }} - volumes: - - name: nginx-conf - emptyDir: {} - - name: nginx-stream-conf - emptyDir: {} - - name: nginx-main-includes - emptyDir: {} - - name: nginx-secrets - emptyDir: {} - - name: nginx-run - emptyDir: {} - - name: nginx-cache - emptyDir: {} - - name: nginx-includes - emptyDir: {} - - name: nginx-includes-bootstrap - configMap: - name: nginx-includes-bootstrap - {{- if .Values.nginx.plus }} - - name: nginx-lib - emptyDir: {} - {{- if .Values.nginx.usage.secretName }} - - name: nginx-plus-license - secret: - secretName: {{ .Values.nginx.usage.secretName }} - {{- end }} - {{- if or .Values.nginx.usage.caSecretName .Values.nginx.usage.clientSSLSecretName }} - - name: nginx-plus-usage-certs - projected: - sources: - {{- if .Values.nginx.usage.caSecretName }} - - secret: - name: {{ .Values.nginx.usage.caSecretName }} - {{- end }} - {{- if .Values.nginx.usage.clientSSLSecretName }} - - secret: - name: {{ .Values.nginx.usage.clientSSLSecretName }} - {{- end }} - {{- end }} - {{- end }} {{- with .Values.extraVolumes -}} {{ toYaml . | nindent 6 }} {{- end }} diff --git a/charts/nginx-gateway-fabric/templates/scc.yaml b/charts/nginx-gateway-fabric/templates/scc.yaml index 8156b279b7..e58389a8ec 100644 --- a/charts/nginx-gateway-fabric/templates/scc.yaml +++ b/charts/nginx-gateway-fabric/templates/scc.yaml @@ -3,7 +3,7 @@ kind: SecurityContextConstraints apiVersion: security.openshift.io/v1 metadata: name: {{ include "nginx-gateway.scc-name" . }} -allowPrivilegeEscalation: {{ .Values.nginxGateway.securityContext.allowPrivilegeEscalation }} +allowPrivilegeEscalation: {{ .Values.nginx.securityContext.allowPrivilegeEscalation }} allowHostDirVolumePlugin: false allowHostIPC: false allowHostNetwork: false diff --git a/charts/nginx-gateway-fabric/templates/service.yaml b/charts/nginx-gateway-fabric/templates/service.yaml index a80686dc7e..7324f04723 100644 --- a/charts/nginx-gateway-fabric/templates/service.yaml +++ b/charts/nginx-gateway-fabric/templates/service.yaml @@ -1,4 +1,3 @@ -{{- if .Values.service.create }} apiVersion: v1 kind: Service metadata: @@ -6,30 +5,16 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "nginx-gateway.labels" . | nindent 4 }} -{{- if .Values.service.annotations }} +{{- if .Values.nginxGateway.service.annotations }} annotations: -{{ toYaml .Values.service.annotations | indent 4 }} +{{ toYaml .Values.nginxGateway.service.annotations | indent 4 }} {{- end }} spec: -{{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} - {{- if .Values.service.externalTrafficPolicy }} - externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} - {{- end }} -{{- end }} - type: {{ .Values.service.type }} -{{- if eq .Values.service.type "LoadBalancer" }} - {{- if .Values.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - {{- if .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{ toYaml .Values.service.loadBalancerSourceRanges | nindent 2 }} - {{- end }} -{{- end}} + type: ClusterIP selector: {{- include "nginx-gateway.selectorLabels" . | nindent 4 }} - ports: # Update the following ports to match your Gateway Listener ports -{{- if .Values.service.ports }} -{{ toYaml .Values.service.ports | indent 2 }} -{{ end }} -{{- end }} + ports: + - name: grpc + port: 443 + protocol: TCP + targetPort: 443 diff --git a/charts/nginx-gateway-fabric/tmp/tmp-nginx-deployment.yaml b/charts/nginx-gateway-fabric/tmp/tmp-nginx-deployment.yaml new file mode 100644 index 0000000000..9ddaea89f1 --- /dev/null +++ b/charts/nginx-gateway-fabric/tmp/tmp-nginx-deployment.yaml @@ -0,0 +1,169 @@ +# apiVersion: apps/v1 +# kind: Deployment +# metadata: +# name: tmp-nginx-deployment +# namespace: {{ .Release.Namespace }} +# spec: +# template: +# spec: +# initContainers: +# - name: init +# image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }} +# imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }} +# command: +# - /usr/bin/gateway +# - initialize +# - --source +# - /includes/main.conf +# {{- if .Values.nginx.plus }} +# - --source +# - /includes/mgmt.conf +# - --nginx-plus +# {{- end }} +# - --destination +# - /etc/nginx/main-includes +# env: +# - name: POD_UID +# valueFrom: +# fieldRef: +# fieldPath: metadata.uid +# securityContext: +# seccompProfile: +# type: RuntimeDefault +# capabilities: +# add: +# - KILL # Set because the binary has CAP_KILL for the main controller process. Not used by init. +# drop: +# - ALL +# readOnlyRootFilesystem: true +# runAsUser: 102 +# runAsGroup: 1001 +# volumeMounts: +# - name: nginx-includes-bootstrap +# mountPath: /includes +# - name: nginx-main-includes +# mountPath: /etc/nginx/main-includes +# containers: +# - image: {{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag | default .Chart.AppVersion }} +# imagePullPolicy: {{ .Values.nginx.image.pullPolicy }} +# name: nginx +# {{- if .Values.nginx.lifecycle }} +# lifecycle: +# {{- toYaml .Values.nginx.lifecycle | nindent 10 }} +# {{- end }} +# ports: +# - containerPort: 80 +# name: http +# - containerPort: 443 +# name: https +# securityContext: +# seccompProfile: +# type: RuntimeDefault +# allowPrivilegeEscalation: {{ .Values.nginx.securityContext.allowPrivilegeEscalation }} +# capabilities: +# add: +# - NET_BIND_SERVICE +# drop: +# - ALL +# readOnlyRootFilesystem: true +# runAsUser: 101 +# runAsGroup: 1001 +# volumeMounts: +# - name: nginx-conf +# mountPath: /etc/nginx/conf.d +# - name: nginx-stream-conf +# mountPath: /etc/nginx/stream-conf.d +# - name: nginx-main-includes +# mountPath: /etc/nginx/main-includes +# - name: nginx-secrets +# mountPath: /etc/nginx/secrets +# - name: nginx-run +# mountPath: /var/run/nginx +# - name: nginx-cache +# mountPath: /var/cache/nginx +# - name: nginx-includes +# mountPath: /etc/nginx/includes +# {{- if .Values.nginx.plus }} +# - name: nginx-lib +# mountPath: /var/lib/nginx/state +# {{- if .Values.nginx.usage.secretName }} +# - name: nginx-plus-license +# mountPath: /etc/nginx/license.jwt +# subPath: license.jwt +# {{- end }} +# {{- if or .Values.nginx.usage.caSecretName .Values.nginx.usage.clientSSLSecretName }} +# - name: nginx-plus-usage-certs +# mountPath: /etc/nginx/certs-bootstrap/ +# {{- end }} +# {{- end }} +# {{- with .Values.nginx.extraVolumeMounts -}} +# {{ toYaml . | nindent 8 }} +# {{- end }} +# {{- if .Values.nginx.debug }} +# command: +# - "/bin/sh" +# args: +# - "-c" +# - "rm -rf /var/run/nginx/*.sock && nginx-debug -g 'daemon off;'" +# {{- end }} +# terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} +# {{- if .Values.affinity }} +# affinity: +# {{- toYaml .Values.affinity | nindent 8 }} +# {{- end }} +# serviceAccountName: {{ include "nginx-gateway.serviceAccountName" . }} +# shareProcessNamespace: true +# securityContext: +# fsGroup: 1001 +# runAsNonRoot: true +# {{- if .Values.tolerations }} +# tolerations: +# {{- toYaml .Values.tolerations | nindent 6 }} +# {{- end }} +# {{- if .Values.nodeSelector }} +# nodeSelector: +# {{- toYaml .Values.nodeSelector | nindent 8 }} +# {{- end }} +# volumes: +# - name: nginx-conf +# emptyDir: {} +# - name: nginx-stream-conf +# emptyDir: {} +# - name: nginx-main-includes +# emptyDir: {} +# - name: nginx-secrets +# emptyDir: {} +# - name: nginx-run +# emptyDir: {} +# - name: nginx-cache +# emptyDir: {} +# - name: nginx-includes +# emptyDir: {} +# - name: nginx-includes-bootstrap +# configMap: +# name: nginx-includes-bootstrap +# {{- if .Values.nginx.plus }} +# - name: nginx-lib +# emptyDir: {} +# {{- if .Values.nginx.usage.secretName }} +# - name: nginx-plus-license +# secret: +# secretName: {{ .Values.nginx.usage.secretName }} +# {{- end }} +# {{- if or .Values.nginx.usage.caSecretName .Values.nginx.usage.clientSSLSecretName }} +# - name: nginx-plus-usage-certs +# projected: +# sources: +# {{- if .Values.nginx.usage.caSecretName }} +# - secret: +# name: {{ .Values.nginx.usage.caSecretName }} +# {{- end }} +# {{- if .Values.nginx.usage.clientSSLSecretName }} +# - secret: +# name: {{ .Values.nginx.usage.clientSSLSecretName }} +# {{- end }} +# {{- end }} +# {{- end }} +# {{- with .Values.extraVolumes -}} +# {{ toYaml . | nindent 6 }} +# {{- end }} diff --git a/charts/nginx-gateway-fabric/tmp/tmp-nginx-service.yaml b/charts/nginx-gateway-fabric/tmp/tmp-nginx-service.yaml new file mode 100644 index 0000000000..30901bfb6a --- /dev/null +++ b/charts/nginx-gateway-fabric/tmp/tmp-nginx-service.yaml @@ -0,0 +1,35 @@ +# {{- if .Values.service.create }} +# apiVersion: v1 +# kind: Service +# metadata: +# name: {{ include "nginx-gateway.fullname" . }} +# namespace: {{ .Release.Namespace }} +# labels: +# {{- include "nginx-gateway.labels" . | nindent 4 }} +# {{- if .Values.service.annotations }} +# annotations: +# {{ toYaml .Values.service.annotations | indent 4 }} +# {{- end }} +# spec: +# {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} +# {{- if .Values.service.externalTrafficPolicy }} +# externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} +# {{- end }} +# {{- end }} +# type: {{ .Values.service.type }} +# {{- if eq .Values.service.type "LoadBalancer" }} +# {{- if .Values.service.loadBalancerIP }} +# loadBalancerIP: {{ .Values.service.loadBalancerIP }} +# {{- end }} +# {{- if .Values.service.loadBalancerSourceRanges }} +# loadBalancerSourceRanges: +# {{ toYaml .Values.service.loadBalancerSourceRanges | nindent 2 }} +# {{- end }} +# {{- end}} +# selector: +# {{- include "nginx-gateway.selectorLabels" . | nindent 4 }} +# ports: # Update the following ports to match your Gateway Listener ports +# {{- if .Values.service.ports }} +# {{ toYaml .Values.service.ports | indent 2 }} +# {{ end }} +# {{- end }} diff --git a/charts/nginx-gateway-fabric/values.schema.json b/charts/nginx-gateway-fabric/values.schema.json index 801f372c1e..651fea311c 100644 --- a/charts/nginx-gateway-fabric/values.schema.json +++ b/charts/nginx-gateway-fabric/values.schema.json @@ -259,6 +259,20 @@ "title": "plus", "type": "boolean" }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "default": false, + "description": "Some environments may need this set to true in order for the control plane to successfully reload NGINX.", + "required": [], + "title": "allowPrivilegeEscalation", + "type": "boolean" + } + }, + "required": [], + "title": "securityContext", + "type": "object" + }, "usage": { "description": "Configuration for NGINX Plus usage reporting.", "properties": { @@ -477,7 +491,7 @@ "type": "object" }, "readinessProbe": { - "description": "# Defines the settings for the control plane readiness probe. This probe returns Ready when the controller\n# has started and configured NGINX to serve traffic.", + "description": "# Defines the settings for the control plane readiness probe. This probe returns Ready when the controller\n# has started and is ready to configure NGINX.", "properties": { "enable": { "default": true, @@ -520,18 +534,17 @@ "title": "resources", "type": "object" }, - "securityContext": { + "service": { "properties": { - "allowPrivilegeEscalation": { - "default": false, - "description": "Some environments may need this set to true in order for the control plane to successfully reload NGINX.", + "annotations": { + "description": "The annotations of the NGINX Gateway Fabric control plane service.", "required": [], - "title": "allowPrivilegeEscalation", - "type": "boolean" + "title": "annotations", + "type": "object" } }, "required": [], - "title": "securityContext", + "title": "service", "type": "object" }, "snippetsFilters": { diff --git a/charts/nginx-gateway-fabric/values.yaml b/charts/nginx-gateway-fabric/values.yaml index c2b5d2bba0..4168c3d66e 100644 --- a/charts/nginx-gateway-fabric/values.yaml +++ b/charts/nginx-gateway-fabric/values.yaml @@ -47,6 +47,10 @@ nginxGateway: # -- Set of custom annotations for NginxGateway objects. configAnnotations: {} + service: + # -- The annotations of the NGINX Gateway Fabric control plane service. + annotations: {} + # -- The number of replicas of the NGINX Gateway Fabric Deployment. replicaCount: 1 @@ -63,7 +67,7 @@ nginxGateway: lockName: "" ## Defines the settings for the control plane readiness probe. This probe returns Ready when the controller - ## has started and configured NGINX to serve traffic. + ## has started and is ready to configure NGINX. readinessProbe: # -- Enable the /readyz endpoint on the control plane. enable: true @@ -91,10 +95,6 @@ nginxGateway: # @schema pullPolicy: Always - securityContext: - # -- Some environments may need this set to true in order for the control plane to successfully reload NGINX. - allowPrivilegeEscalation: false - productTelemetry: # -- Enable the collection of product telemetry. enable: true @@ -131,6 +131,10 @@ nginx: # @schema pullPolicy: Always + securityContext: + # -- Some environments may need this set to true in order for the control plane to successfully reload NGINX. + allowPrivilegeEscalation: false + # -- Is NGINX Plus image being used plus: false diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 34c595f455..aaa18a21ac 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -19,12 +19,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ctlrZap "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/provisioner" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" ngxConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" ) // These flags are shared by multiple commands. diff --git a/cmd/gateway/initialize.go b/cmd/gateway/initialize.go index 1aa01f923e..4ce6fc0495 100644 --- a/cmd/gateway/initialize.go +++ b/cmd/gateway/initialize.go @@ -8,9 +8,9 @@ import ( "github.com/go-logr/logr" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" ) const ( @@ -58,7 +58,7 @@ func initialize(cfg initializeConfig) error { return fmt.Errorf("failed to generate deployment context file: %w", err) } - if err := file.WriteFile(cfg.fileManager, depCtxFile); err != nil { + if err := file.Write(cfg.fileManager, depCtxFile); err != nil { return fmt.Errorf("failed to write deployment context file: %w", err) } diff --git a/cmd/gateway/initialize_test.go b/cmd/gateway/initialize_test.go index 507acc6fa0..4276ff9a24 100644 --- a/cmd/gateway/initialize_test.go +++ b/cmd/gateway/initialize_test.go @@ -11,11 +11,11 @@ import ( . "github.com/onsi/gomega" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file/filefakes" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing/licensingfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/configfakes" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" ) diff --git a/config/tests/static-deployment.yaml b/config/tests/static-deployment.yaml index e84e3cbfd4..0997a8e2cb 100644 --- a/config/tests/static-deployment.yaml +++ b/config/tests/static-deployment.yaml @@ -21,38 +21,6 @@ spec: app.kubernetes.io/name: nginx-gateway app.kubernetes.io/instance: nginx-gateway spec: - initContainers: - - name: init - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - securityContext: - seccompProfile: - type: RuntimeDefault - capabilities: - add: - - KILL # Set because the binary has CAP_KILL for the main controller process. Not used by init. - drop: - - ALL - readOnlyRootFilesystem: true - runAsUser: 102 - runAsGroup: 1001 - volumeMounts: - - name: nginx-includes-bootstrap - mountPath: /includes - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes containers: - args: - static-mode @@ -96,83 +64,14 @@ spec: securityContext: seccompProfile: type: RuntimeDefault - allowPrivilegeEscalation: false capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true runAsUser: 102 runAsGroup: 1001 - volumeMounts: - - name: nginx-conf - mountPath: /etc/nginx/conf.d - - name: nginx-stream-conf - mountPath: /etc/nginx/stream-conf.d - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes - - name: nginx-secrets - mountPath: /etc/nginx/secrets - - name: nginx-run - mountPath: /var/run/nginx - - name: nginx-includes - mountPath: /etc/nginx/includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - seccompProfile: - type: RuntimeDefault - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsUser: 101 - runAsGroup: 1001 - volumeMounts: - - name: nginx-conf - mountPath: /etc/nginx/conf.d - - name: nginx-stream-conf - mountPath: /etc/nginx/stream-conf.d - - name: nginx-main-includes - mountPath: /etc/nginx/main-includes - - name: nginx-secrets - mountPath: /etc/nginx/secrets - - name: nginx-run - mountPath: /var/run/nginx - - name: nginx-cache - mountPath: /var/cache/nginx - - name: nginx-includes - mountPath: /etc/nginx/includes terminationGracePeriodSeconds: 30 serviceAccountName: nginx-gateway - shareProcessNamespace: true securityContext: fsGroup: 1001 runAsNonRoot: true - volumes: - - name: nginx-conf - emptyDir: {} - - name: nginx-stream-conf - emptyDir: {} - - name: nginx-main-includes - emptyDir: {} - - name: nginx-secrets - emptyDir: {} - - name: nginx-run - emptyDir: {} - - name: nginx-cache - emptyDir: {} - - name: nginx-includes - emptyDir: {} - - name: nginx-includes-bootstrap - configMap: - name: nginx-includes-bootstrap diff --git a/deploy/aws-nlb/deploy.yaml b/deploy/aws-nlb/deploy.yaml index 018cf36107..4f815d2520 100644 --- a/deploy/aws-nlb/deploy.yaml +++ b/deploy/aws-nlb/deploy.yaml @@ -160,9 +160,6 @@ metadata: apiVersion: v1 kind: Service metadata: - annotations: - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip - service.beta.kubernetes.io/aws-load-balancer-type: external labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway @@ -170,20 +167,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -250,85 +242,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -336,35 +251,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/azure/deploy.yaml b/deploy/azure/deploy.yaml index a8dc451b7e..2250415ec0 100644 --- a/deploy/azure/deploy.yaml +++ b/deploy/azure/deploy.yaml @@ -167,20 +167,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -247,85 +242,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -333,37 +251,13 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes nodeSelector: kubernetes.io/os: linux securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/default/deploy.yaml b/deploy/default/deploy.yaml index 69853e77d3..4f815d2520 100644 --- a/deploy/default/deploy.yaml +++ b/deploy/default/deploy.yaml @@ -167,20 +167,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -247,85 +242,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -333,35 +251,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/experimental-nginx-plus/deploy.yaml b/deploy/experimental-nginx-plus/deploy.yaml index 9f30307439..b4965aed6f 100644 --- a/deploy/experimental-nginx-plus/deploy.yaml +++ b/deploy/experimental-nginx-plus/deploy.yaml @@ -185,20 +185,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -268,93 +263,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - - mountPath: /var/lib/nginx/state - name: nginx-lib - - mountPath: /etc/nginx/license.jwt - name: nginx-plus-license - subPath: license.jwt - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --source - - /includes/mgmt.conf - - --nginx-plus - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -362,40 +272,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap - - emptyDir: {} - name: nginx-lib - - name: nginx-plus-license - secret: - secretName: nplus-license --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/experimental/deploy.yaml b/deploy/experimental/deploy.yaml index f3114d3b55..3f5ce9f10f 100644 --- a/deploy/experimental/deploy.yaml +++ b/deploy/experimental/deploy.yaml @@ -172,20 +172,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -253,85 +248,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -339,35 +257,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/nginx-plus/deploy.yaml b/deploy/nginx-plus/deploy.yaml index 4561a6edb9..95586af37c 100644 --- a/deploy/nginx-plus/deploy.yaml +++ b/deploy/nginx-plus/deploy.yaml @@ -180,20 +180,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -262,93 +257,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - - mountPath: /var/lib/nginx/state - name: nginx-lib - - mountPath: /etc/nginx/license.jwt - name: nginx-plus-license - subPath: license.jwt - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --source - - /includes/mgmt.conf - - --nginx-plus - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -356,40 +266,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap - - emptyDir: {} - name: nginx-lib - - name: nginx-plus-license - secret: - secretName: nplus-license --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/nodeport/deploy.yaml b/deploy/nodeport/deploy.yaml index 19bae58059..4f815d2520 100644 --- a/deploy/nodeport/deploy.yaml +++ b/deploy/nodeport/deploy.yaml @@ -167,20 +167,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: NodePort + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -247,85 +242,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -333,35 +251,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/openshift/deploy.yaml b/deploy/openshift/deploy.yaml index 8dd460e35a..ede56b948b 100644 --- a/deploy/openshift/deploy.yaml +++ b/deploy/openshift/deploy.yaml @@ -175,20 +175,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -255,85 +250,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -341,35 +259,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/snippets-filters-nginx-plus/deploy.yaml b/deploy/snippets-filters-nginx-plus/deploy.yaml index 176cf08c0a..49bac6d55f 100644 --- a/deploy/snippets-filters-nginx-plus/deploy.yaml +++ b/deploy/snippets-filters-nginx-plus/deploy.yaml @@ -182,20 +182,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -265,93 +260,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - - mountPath: /var/lib/nginx/state - name: nginx-lib - - mountPath: /etc/nginx/license.jwt - name: nginx-plus-license - subPath: license.jwt - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --source - - /includes/mgmt.conf - - --nginx-plus - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -359,40 +269,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap - - emptyDir: {} - name: nginx-lib - - name: nginx-plus-license - secret: - secretName: nplus-license --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/deploy/snippets-filters/deploy.yaml b/deploy/snippets-filters/deploy.yaml index 6c177233bd..45f8802d2a 100644 --- a/deploy/snippets-filters/deploy.yaml +++ b/deploy/snippets-filters/deploy.yaml @@ -169,20 +169,15 @@ metadata: name: nginx-gateway namespace: nginx-gateway spec: - externalTrafficPolicy: Local ports: - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https + - name: grpc port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - type: LoadBalancer + type: ClusterIP --- apiVersion: apps/v1 kind: Deployment @@ -250,85 +245,8 @@ spec: port: health initialDelaySeconds: 3 periodSeconds: 1 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - KILL - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 102 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /etc/nginx/includes - name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:edge - imagePullPolicy: Always - name: nginx - ports: - - containerPort: 80 - name: http - - containerPort: 443 - name: https - securityContext: - capabilities: - add: - - NET_BIND_SERVICE - drop: - - ALL - readOnlyRootFilesystem: true - runAsGroup: 1001 - runAsUser: 101 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /etc/nginx/conf.d - name: nginx-conf - - mountPath: /etc/nginx/stream-conf.d - name: nginx-stream-conf - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes - - mountPath: /etc/nginx/secrets - name: nginx-secrets - - mountPath: /var/run/nginx - name: nginx-run - - mountPath: /var/cache/nginx - name: nginx-cache - - mountPath: /etc/nginx/includes - name: nginx-includes - initContainers: - - command: - - /usr/bin/gateway - - initialize - - --source - - /includes/main.conf - - --destination - - /etc/nginx/main-includes - env: - - name: POD_UID - valueFrom: - fieldRef: - fieldPath: metadata.uid - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge - imagePullPolicy: Always - name: init securityContext: capabilities: - add: - - KILL drop: - ALL readOnlyRootFilesystem: true @@ -336,35 +254,11 @@ spec: runAsUser: 102 seccompProfile: type: RuntimeDefault - volumeMounts: - - mountPath: /includes - name: nginx-includes-bootstrap - - mountPath: /etc/nginx/main-includes - name: nginx-main-includes securityContext: fsGroup: 1001 runAsNonRoot: true serviceAccountName: nginx-gateway - shareProcessNamespace: true terminationGracePeriodSeconds: 30 - volumes: - - emptyDir: {} - name: nginx-conf - - emptyDir: {} - name: nginx-stream-conf - - emptyDir: {} - name: nginx-main-includes - - emptyDir: {} - name: nginx-secrets - - emptyDir: {} - name: nginx-run - - emptyDir: {} - name: nginx-cache - - emptyDir: {} - name: nginx-includes - - configMap: - name: nginx-includes-bootstrap - name: nginx-includes-bootstrap --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass diff --git a/go.mod b/go.mod index 76bc007ee3..df195fe1b5 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,6 @@ require ( github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2 - github.com/nginxinc/nginx-plus-go-client v1.3.0 - github.com/nginxinc/nginx-prometheus-exporter v1.3.0 github.com/nginxinc/telemetry-exporter v0.1.2 github.com/onsi/ginkgo/v2 v2.22.1 github.com/onsi/gomega v1.36.1 diff --git a/go.sum b/go.sum index 9e1a86bb0c..f8357426c4 100644 --- a/go.sum +++ b/go.sum @@ -81,10 +81,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nginxinc/nginx-plus-go-client v1.3.0 h1:q/aeT4B5k0KLwWlefoBzfLfraBBvIKLuDg+lLFWAo4I= -github.com/nginxinc/nginx-plus-go-client v1.3.0/go.mod h1:n8OFLzrJulJ2fur28Cwa1Qp5DZNS2VicLV+Adt30LQ4= -github.com/nginxinc/nginx-prometheus-exporter v1.3.0 h1:1JtdxsZH0Uwhu1nL/j/QyOXytP5V5j68AEo2X+DFWb0= -github.com/nginxinc/nginx-prometheus-exporter v1.3.0/go.mod h1:hXoH+X6aIKSyQuO6QTIiPKH3eZyxqy/wW8GYiE3dflU= github.com/nginxinc/telemetry-exporter v0.1.2 h1:97vUGhQYgQ2KEsXKCBmr5gqfuujJCKPHwdg5HKoANUs= github.com/nginxinc/telemetry-exporter v0.1.2/go.mod h1:eKa/Ceh9irmyZ1xV2QxBIxduIyVC5RlmtiWwcTlHuMg= github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= diff --git a/internal/mode/static/nginx/file/manager.go b/internal/framework/file/file.go similarity index 53% rename from internal/mode/static/nginx/file/manager.go rename to internal/framework/file/file.go index 6c535ddfc4..0a6fb491a4 100644 --- a/internal/mode/static/nginx/file/manager.go +++ b/internal/framework/file/file.go @@ -4,10 +4,7 @@ import ( "errors" "fmt" "io" - "io/fs" "os" - - "github.com/go-logr/logr" ) //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate @@ -49,13 +46,8 @@ type File struct { //counterfeiter:generate . OSFileManager -// OSFileManager is an interface that exposes File I/O operations for ManagerImpl. -// Used for unit testing. +// OSFileManager is an interface that exposes File I/O operations. type OSFileManager interface { - // ReadDir returns the directory entries for the directory. - ReadDir(dirname string) ([]fs.DirEntry, error) - // Remove file with given name. - Remove(name string) error // Create file at the provided filepath. Create(name string) (*os.File, error) // Chmod sets the mode of the file. @@ -68,68 +60,7 @@ type OSFileManager interface { Copy(dst io.Writer, src io.Reader) error } -//counterfeiter:generate . Manager - -// Manager manages NGINX configuration files. -type Manager interface { - // ReplaceFiles replaces the files on the file system with the given files removing any previous files. - ReplaceFiles(files []File) error -} - -// ManagerImpl is an implementation of Manager. -// Note: It is not thread safe. -type ManagerImpl struct { - logger logr.Logger - osFileManager OSFileManager - lastWrittenPaths []string -} - -// NewManagerImpl creates a new NewManagerImpl. -func NewManagerImpl(logger logr.Logger, osFileManager OSFileManager) *ManagerImpl { - return &ManagerImpl{ - logger: logger, - osFileManager: osFileManager, - } -} - -// ReplaceFiles replaces the files on the file system with the given files removing any previous files. -// It panics if a file type is unknown. -func (m *ManagerImpl) ReplaceFiles(files []File) error { - for _, path := range m.lastWrittenPaths { - if err := m.osFileManager.Remove(path); err != nil { - if os.IsNotExist(err) { - m.logger.Info( - "File not found when attempting to delete", - "path", path, - "error", err, - ) - continue - } - return fmt.Errorf("failed to delete file %q: %w", path, err) - } - - m.logger.V(1).Info("Deleted file", "path", path) - } - - // In some cases, NGINX reads files in runtime, like a JWK. If you remove such file, NGINX will fail - // any request (return 500 status code) that involves reading the file. - // However, we don't have such files yet, so we're not considering this case. - - m.lastWrittenPaths = make([]string, 0, len(files)) - - for _, file := range files { - if err := WriteFile(m.osFileManager, file); err != nil { - return fmt.Errorf("failed to write file %q of type %v: %w", file.Path, file.Type, err) - } - - m.lastWrittenPaths = append(m.lastWrittenPaths, file.Path) - m.logger.V(1).Info("Wrote file", "path", file.Path) - } - - return nil -} - -func WriteFile(fileMgr OSFileManager, file File) error { +func Write(fileMgr OSFileManager, file File) error { ensureType(file.Type) f, err := fileMgr.Create(file.Path) diff --git a/internal/mode/static/nginx/file/file_suite_test.go b/internal/framework/file/file_suite_test.go similarity index 100% rename from internal/mode/static/nginx/file/file_suite_test.go rename to internal/framework/file/file_suite_test.go diff --git a/internal/framework/file/file_test.go b/internal/framework/file/file_test.go new file mode 100644 index 0000000000..d5b52b48a6 --- /dev/null +++ b/internal/framework/file/file_test.go @@ -0,0 +1,155 @@ +package file_test + +import ( + "errors" + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file/filefakes" +) + +var _ = Describe("Write files", Ordered, func() { + var ( + mgr file.OSFileManager + tmpDir string + regular1, regular2, secret file.File + ) + + ensureFiles := func(files []file.File) { + entries, err := os.ReadDir(tmpDir) + Expect(err).ToNot(HaveOccurred()) + Expect(entries).Should(HaveLen(len(files))) + + entriesMap := make(map[string]os.DirEntry) + for _, entry := range entries { + entriesMap[entry.Name()] = entry + } + + for _, f := range files { + _, ok := entriesMap[filepath.Base(f.Path)] + Expect(ok).Should(BeTrue()) + + info, err := os.Stat(f.Path) + Expect(err).ToNot(HaveOccurred()) + + Expect(info.IsDir()).To(BeFalse()) + + if f.Type == file.TypeRegular { + Expect(info.Mode()).To(Equal(os.FileMode(0o644))) + } else { + Expect(info.Mode()).To(Equal(os.FileMode(0o640))) + } + + bytes, err := os.ReadFile(f.Path) + Expect(err).ToNot(HaveOccurred()) + Expect(bytes).To(Equal(f.Content)) + } + } + + BeforeAll(func() { + mgr = file.NewStdLibOSFileManager() + tmpDir = GinkgoT().TempDir() + + regular1 = file.File{ + Type: file.TypeRegular, + Path: filepath.Join(tmpDir, "regular-1.conf"), + Content: []byte("regular-1"), + } + regular2 = file.File{ + Type: file.TypeRegular, + Path: filepath.Join(tmpDir, "regular-2.conf"), + Content: []byte("regular-2"), + } + secret = file.File{ + Type: file.TypeSecret, + Path: filepath.Join(tmpDir, "secret.conf"), + Content: []byte("secret"), + } + }) + + It("should write files", func() { + files := []file.File{regular1, regular2, secret} + + for _, f := range files { + Expect(file.Write(mgr, f)).To(Succeed()) + } + + ensureFiles(files) + }) + + When("file type is not supported", func() { + It("should panic", func() { + mgr = file.NewStdLibOSFileManager() + + f := file.File{ + Type: 123, + Path: "unsupported.conf", + } + + replace := func() { + _ = file.Write(mgr, f) + } + + Expect(replace).Should(Panic()) + }) + }) + + Describe("Edge cases with IO errors", func() { + var ( + files = []file.File{ + { + Type: file.TypeRegular, + Path: "regular.conf", + Content: []byte("regular"), + }, + { + Type: file.TypeSecret, + Path: "secret.conf", + Content: []byte("secret"), + }, + } + errTest = errors.New("test error") + ) + + DescribeTable( + "should return error on file IO error", + func(fakeOSMgr *filefakes.FakeOSFileManager) { + mgr := fakeOSMgr + + for _, f := range files { + err := file.Write(mgr, f) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(errTest)) + } + }, + Entry( + "Create", + &filefakes.FakeOSFileManager{ + CreateStub: func(_ string) (*os.File, error) { + return nil, errTest + }, + }, + ), + Entry( + "Chmod", + &filefakes.FakeOSFileManager{ + ChmodStub: func(_ *os.File, _ os.FileMode) error { + return errTest + }, + }, + ), + Entry( + "Write", + &filefakes.FakeOSFileManager{ + WriteStub: func(_ *os.File, _ []byte) error { + return errTest + }, + }, + ), + ) + }) +}) diff --git a/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go b/internal/framework/file/filefakes/fake_osfile_manager.go similarity index 72% rename from internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go rename to internal/framework/file/filefakes/fake_osfile_manager.go index 733da9a1c4..6c1090fbf8 100644 --- a/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go +++ b/internal/framework/file/filefakes/fake_osfile_manager.go @@ -3,11 +3,10 @@ package filefakes import ( "io" - "io/fs" "os" "sync" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" ) type FakeOSFileManager struct { @@ -61,30 +60,6 @@ type FakeOSFileManager struct { result1 *os.File result2 error } - ReadDirStub func(string) ([]fs.DirEntry, error) - readDirMutex sync.RWMutex - readDirArgsForCall []struct { - arg1 string - } - readDirReturns struct { - result1 []fs.DirEntry - result2 error - } - readDirReturnsOnCall map[int]struct { - result1 []fs.DirEntry - result2 error - } - RemoveStub func(string) error - removeMutex sync.RWMutex - removeArgsForCall []struct { - arg1 string - } - removeReturns struct { - result1 error - } - removeReturnsOnCall map[int]struct { - result1 error - } WriteStub func(*os.File, []byte) error writeMutex sync.RWMutex writeArgsForCall []struct { @@ -353,131 +328,6 @@ func (fake *FakeOSFileManager) OpenReturnsOnCall(i int, result1 *os.File, result }{result1, result2} } -func (fake *FakeOSFileManager) ReadDir(arg1 string) ([]fs.DirEntry, error) { - fake.readDirMutex.Lock() - ret, specificReturn := fake.readDirReturnsOnCall[len(fake.readDirArgsForCall)] - fake.readDirArgsForCall = append(fake.readDirArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.ReadDirStub - fakeReturns := fake.readDirReturns - fake.recordInvocation("ReadDir", []interface{}{arg1}) - fake.readDirMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeOSFileManager) ReadDirCallCount() int { - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - return len(fake.readDirArgsForCall) -} - -func (fake *FakeOSFileManager) ReadDirCalls(stub func(string) ([]fs.DirEntry, error)) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = stub -} - -func (fake *FakeOSFileManager) ReadDirArgsForCall(i int) string { - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - argsForCall := fake.readDirArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeOSFileManager) ReadDirReturns(result1 []fs.DirEntry, result2 error) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = nil - fake.readDirReturns = struct { - result1 []fs.DirEntry - result2 error - }{result1, result2} -} - -func (fake *FakeOSFileManager) ReadDirReturnsOnCall(i int, result1 []fs.DirEntry, result2 error) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = nil - if fake.readDirReturnsOnCall == nil { - fake.readDirReturnsOnCall = make(map[int]struct { - result1 []fs.DirEntry - result2 error - }) - } - fake.readDirReturnsOnCall[i] = struct { - result1 []fs.DirEntry - result2 error - }{result1, result2} -} - -func (fake *FakeOSFileManager) Remove(arg1 string) error { - fake.removeMutex.Lock() - ret, specificReturn := fake.removeReturnsOnCall[len(fake.removeArgsForCall)] - fake.removeArgsForCall = append(fake.removeArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.RemoveStub - fakeReturns := fake.removeReturns - fake.recordInvocation("Remove", []interface{}{arg1}) - fake.removeMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeOSFileManager) RemoveCallCount() int { - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() - return len(fake.removeArgsForCall) -} - -func (fake *FakeOSFileManager) RemoveCalls(stub func(string) error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = stub -} - -func (fake *FakeOSFileManager) RemoveArgsForCall(i int) string { - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() - argsForCall := fake.removeArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeOSFileManager) RemoveReturns(result1 error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = nil - fake.removeReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeOSFileManager) RemoveReturnsOnCall(i int, result1 error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = nil - if fake.removeReturnsOnCall == nil { - fake.removeReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.removeReturnsOnCall[i] = struct { - result1 error - }{result1} -} - func (fake *FakeOSFileManager) Write(arg1 *os.File, arg2 []byte) error { var arg2Copy []byte if arg2 != nil { @@ -556,10 +406,6 @@ func (fake *FakeOSFileManager) Invocations() map[string][][]interface{} { defer fake.createMutex.RUnlock() fake.openMutex.RLock() defer fake.openMutex.RUnlock() - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() fake.writeMutex.RLock() defer fake.writeMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} diff --git a/internal/mode/static/nginx/file/os_filemanager.go b/internal/framework/file/os_filemanager.go similarity index 100% rename from internal/mode/static/nginx/file/os_filemanager.go rename to internal/framework/file/os_filemanager.go diff --git a/internal/mode/static/handler.go b/internal/mode/static/handler.go index 2a835b8584..a076884811 100644 --- a/internal/mode/static/handler.go +++ b/internal/mode/static/handler.go @@ -2,13 +2,11 @@ package static import ( "context" - "errors" "fmt" "sync" "time" "github.com/go-logr/logr" - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -22,9 +20,8 @@ import ( frameworkStatus "github.com/nginxinc/nginx-gateway-fabric/internal/framework/status" ngfConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/agent" ngxConfig "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/nginx/runtime" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/graph" @@ -38,12 +35,10 @@ type handlerMetricsCollector interface { // eventHandlerConfig holds configuration parameters for eventHandlerImpl. type eventHandlerConfig struct { - // nginxFileMgr is the file Manager for nginx. - nginxFileMgr file.Manager + // nginxUpdater updates nginx configuration using the NGINX agent. + nginxUpdater agent.NginxUpdater // metricsCollector collects metrics for this controller. metricsCollector handlerMetricsCollector - // nginxRuntimeMgr manages nginx runtime. - nginxRuntimeMgr runtime.Manager // statusUpdater updates statuses on Kubernetes resources. statusUpdater frameworkStatus.GroupUpdater // processor is the state ChangeProcessor. @@ -62,8 +57,8 @@ type eventHandlerConfig struct { eventRecorder record.EventRecorder // deployCtxCollector collects the deployment context for N+ licensing deployCtxCollector licensing.Collector - // nginxConfiguredOnStartChecker sets the health of the Pod to Ready once we've written out our initial config. - nginxConfiguredOnStartChecker *nginxConfiguredOnStartChecker + // graphBuiltHealthChecker sets the health of the Pod to Ready once we've built our initial graph. + graphBuiltHealthChecker *graphBuiltHealthChecker // gatewayPodConfig contains information about this Pod. gatewayPodConfig ngfConfig.GatewayPodConfig // controlConfigNSName is the NamespacedName of the NginxGateway config for this controller. @@ -164,13 +159,15 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, logger logr.Log changeType, gr := h.cfg.processor.Process() + // Once we've processed resources on startup and built our first graph, mark the Pod as ready. + if !h.cfg.graphBuiltHealthChecker.ready { + h.cfg.graphBuiltHealthChecker.setAsReady() + } + var err error switch changeType { case state.NoChange: logger.Info("Handling events didn't result into NGINX configuration changes") - if !h.cfg.nginxConfiguredOnStartChecker.ready && h.cfg.nginxConfiguredOnStartChecker.firstBatchError == nil { - h.cfg.nginxConfiguredOnStartChecker.setAsReady() - } return case state.EndpointsOnlyChange: h.version++ @@ -184,9 +181,9 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, logger logr.Log h.setLatestConfiguration(&cfg) if h.cfg.plus { - err = h.updateUpstreamServers(cfg) + h.cfg.nginxUpdater.UpdateUpstreamServers() } else { - err = h.updateNginxConf(ctx, cfg) + err = h.updateNginxConf(cfg) } case state.ClusterStateChange: h.version++ @@ -199,21 +196,15 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, logger logr.Log h.setLatestConfiguration(&cfg) - err = h.updateNginxConf(ctx, cfg) + err = h.updateNginxConf(cfg) } var nginxReloadRes status.NginxReloadResult if err != nil { logger.Error(err, "Failed to update NGINX configuration") nginxReloadRes.Error = err - if !h.cfg.nginxConfiguredOnStartChecker.ready { - h.cfg.nginxConfiguredOnStartChecker.firstBatchError = err - } } else { logger.Info("NGINX configuration was successfully updated") - if !h.cfg.nginxConfiguredOnStartChecker.ready { - h.cfg.nginxConfiguredOnStartChecker.setAsReady() - } } h.latestReloadResult = nginxReloadRes @@ -304,134 +295,21 @@ func (h *eventHandlerImpl) parseAndCaptureEvent(ctx context.Context, logger logr } // updateNginxConf updates nginx conf files and reloads nginx. -func (h *eventHandlerImpl) updateNginxConf( - ctx context.Context, - conf dataplane.Configuration, -) error { +// +//nolint:unparam // temporarily returning only nil +func (h *eventHandlerImpl) updateNginxConf(conf dataplane.Configuration) error { files := h.cfg.generator.Generate(conf) - if err := h.cfg.nginxFileMgr.ReplaceFiles(files); err != nil { - return fmt.Errorf("failed to replace NGINX configuration files: %w", err) - } - if err := h.cfg.nginxRuntimeMgr.Reload(ctx, conf.Version); err != nil { - return fmt.Errorf("failed to reload NGINX: %w", err) - } + h.cfg.nginxUpdater.UpdateConfig(len(files)) // If using NGINX Plus, update upstream servers using the API. - if err := h.updateUpstreamServers(conf); err != nil { - return fmt.Errorf("failed to update upstream servers: %w", err) + if h.cfg.plus { + h.cfg.nginxUpdater.UpdateUpstreamServers() } return nil } -// updateUpstreamServers determines which servers have changed and uses the NGINX Plus API to update them. -// Only applicable when using NGINX Plus. -func (h *eventHandlerImpl) updateUpstreamServers(conf dataplane.Configuration) error { - if !h.cfg.plus { - return nil - } - - prevUpstreams, prevStreamUpstreams, err := h.cfg.nginxRuntimeMgr.GetUpstreams() - if err != nil { - return fmt.Errorf("failed to get upstreams from API: %w", err) - } - - type upstream struct { - name string - servers []ngxclient.UpstreamServer - } - var upstreams []upstream - - for _, u := range conf.Upstreams { - confUpstream := upstream{ - name: u.Name, - servers: ngxConfig.ConvertEndpoints(u.Endpoints), - } - - if u, ok := prevUpstreams[confUpstream.name]; ok { - if !serversEqual(confUpstream.servers, u.Peers) { - upstreams = append(upstreams, confUpstream) - } - } - } - - type streamUpstream struct { - name string - servers []ngxclient.StreamUpstreamServer - } - var streamUpstreams []streamUpstream - - for _, u := range conf.StreamUpstreams { - confUpstream := streamUpstream{ - name: u.Name, - servers: ngxConfig.ConvertStreamEndpoints(u.Endpoints), - } - - if u, ok := prevStreamUpstreams[confUpstream.name]; ok { - if !serversEqual(confUpstream.servers, u.Peers) { - streamUpstreams = append(streamUpstreams, confUpstream) - } - } - } - - var updateErr error - for _, upstream := range upstreams { - if err := h.cfg.nginxRuntimeMgr.UpdateHTTPServers(upstream.name, upstream.servers); err != nil { - updateErr = errors.Join(updateErr, fmt.Errorf( - "couldn't update upstream %q via the API: %w", upstream.name, err)) - } - } - - for _, upstream := range streamUpstreams { - if err := h.cfg.nginxRuntimeMgr.UpdateStreamServers(upstream.name, upstream.servers); err != nil { - updateErr = errors.Join(updateErr, fmt.Errorf( - "couldn't update stream upstream %q via the API: %w", upstream.name, err)) - } - } - - return updateErr -} - -// serversEqual accepts lists of either UpstreamServer/Peer or StreamUpstreamServer/StreamPeer and determines -// if the server names within these lists are equal. -func serversEqual[ - upstreamServer ngxclient.UpstreamServer | ngxclient.StreamUpstreamServer, - peer ngxclient.Peer | ngxclient.StreamPeer, -](newServers []upstreamServer, oldServers []peer) bool { - if len(newServers) != len(oldServers) { - return false - } - - getServerVal := func(T any) string { - var server string - switch t := T.(type) { - case ngxclient.UpstreamServer: - server = t.Server - case ngxclient.StreamUpstreamServer: - server = t.Server - case ngxclient.Peer: - server = t.Server - case ngxclient.StreamPeer: - server = t.Server - } - return server - } - - diff := make(map[string]struct{}, len(newServers)) - for _, s := range newServers { - diff[getServerVal(s)] = struct{}{} - } - - for _, s := range oldServers { - if _, ok := diff[getServerVal(s)]; !ok { - return false - } - } - - return true -} - // updateControlPlaneAndSetStatus updates the control plane configuration and then sets the status // based on the outcome. func (h *eventHandlerImpl) updateControlPlaneAndSetStatus( diff --git a/internal/mode/static/handler_test.go b/internal/mode/static/handler_test.go index 8d8ef9a8d3..ce185565c6 100644 --- a/internal/mode/static/handler_test.go +++ b/internal/mode/static/handler_test.go @@ -4,7 +4,6 @@ import ( "context" "errors" - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/zap" @@ -20,15 +19,14 @@ import ( ngfAPI "github.com/nginxinc/nginx-gateway-fabric/apis/v1alpha1" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/events" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/status/statusfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing/licensingfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics/collectors" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/agent/agentfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/configfakes" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime/runtimefakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/graph" @@ -37,17 +35,16 @@ import ( var _ = Describe("eventHandler", func() { var ( - handler *eventHandlerImpl - fakeProcessor *statefakes.FakeChangeProcessor - fakeGenerator *configfakes.FakeGenerator - fakeNginxFileMgr *filefakes.FakeManager - fakeNginxRuntimeMgr *runtimefakes.FakeManager - fakeStatusUpdater *statusfakes.FakeGroupUpdater - fakeEventRecorder *record.FakeRecorder - fakeK8sClient client.WithWatch - namespace = "nginx-gateway" - configName = "nginx-gateway-config" - zapLogLevelSetter zapLogLevelSetter + handler *eventHandlerImpl + fakeProcessor *statefakes.FakeChangeProcessor + fakeGenerator *configfakes.FakeGenerator + fakeNginxUpdater *agentfakes.FakeNginxUpdater + fakeStatusUpdater *statusfakes.FakeGroupUpdater + fakeEventRecorder *record.FakeRecorder + fakeK8sClient client.WithWatch + namespace = "nginx-gateway" + configName = "nginx-gateway-config" + zapLogLevelSetter zapLogLevelSetter ) const nginxGatewayServiceName = "nginx-gateway" @@ -67,11 +64,9 @@ var _ = Describe("eventHandler", func() { Expect(fakeGenerator.GenerateCallCount()).Should(Equal(1)) Expect(fakeGenerator.GenerateArgsForCall(0)).Should(Equal(expectedConf)) - Expect(fakeNginxFileMgr.ReplaceFilesCallCount()).Should(Equal(1)) - files := fakeNginxFileMgr.ReplaceFilesArgsForCall(0) - Expect(files).Should(Equal(expectedFiles)) - - Expect(fakeNginxRuntimeMgr.ReloadCallCount()).Should(Equal(1)) + Expect(fakeNginxUpdater.UpdateConfigCallCount()).Should(Equal(1)) + lenFiles := fakeNginxUpdater.UpdateConfigArgsForCall(0) + Expect(expectedFiles).To(HaveLen(lenFiles)) Expect(fakeStatusUpdater.UpdateGroupCallCount()).Should(Equal(2)) _, name, reqs := fakeStatusUpdater.UpdateGroupArgsForCall(0) @@ -87,8 +82,7 @@ var _ = Describe("eventHandler", func() { fakeProcessor = &statefakes.FakeChangeProcessor{} fakeProcessor.ProcessReturns(state.NoChange, &graph.Graph{}) fakeGenerator = &configfakes.FakeGenerator{} - fakeNginxFileMgr = &filefakes.FakeManager{} - fakeNginxRuntimeMgr = &runtimefakes.FakeManager{} + fakeNginxUpdater = &agentfakes.FakeNginxUpdater{} fakeStatusUpdater = &statusfakes.FakeGroupUpdater{} fakeEventRecorder = record.NewFakeRecorder(1) zapLogLevelSetter = newZapLogLevelSetter(zap.NewAtomicLevel()) @@ -98,17 +92,16 @@ var _ = Describe("eventHandler", func() { Expect(fakeK8sClient.Create(context.Background(), createService(nginxGatewayServiceName))).To(Succeed()) handler = newEventHandlerImpl(eventHandlerConfig{ - k8sClient: fakeK8sClient, - processor: fakeProcessor, - generator: fakeGenerator, - logLevelSetter: zapLogLevelSetter, - nginxFileMgr: fakeNginxFileMgr, - nginxRuntimeMgr: fakeNginxRuntimeMgr, - statusUpdater: fakeStatusUpdater, - eventRecorder: fakeEventRecorder, - deployCtxCollector: &licensingfakes.FakeCollector{}, - nginxConfiguredOnStartChecker: newNginxConfiguredOnStartChecker(), - controlConfigNSName: types.NamespacedName{Namespace: namespace, Name: configName}, + k8sClient: fakeK8sClient, + processor: fakeProcessor, + generator: fakeGenerator, + logLevelSetter: zapLogLevelSetter, + nginxUpdater: fakeNginxUpdater, + statusUpdater: fakeStatusUpdater, + eventRecorder: fakeEventRecorder, + deployCtxCollector: &licensingfakes.FakeCollector{}, + graphBuiltHealthChecker: newGraphBuiltHealthChecker(), + controlConfigNSName: types.NamespacedName{Namespace: namespace, Name: configName}, gatewayPodConfig: config.GatewayPodConfig{ ServiceName: "nginx-gateway", Namespace: "nginx-gateway", @@ -116,7 +109,7 @@ var _ = Describe("eventHandler", func() { metricsCollector: collectors.NewControllerNoopCollector(), updateGatewayClassStatus: true, }) - Expect(handler.cfg.nginxConfiguredOnStartChecker.ready).To(BeFalse()) + Expect(handler.cfg.graphBuiltHealthChecker.ready).To(BeFalse()) }) Describe("Process the Gateway API resources events", func() { @@ -146,7 +139,7 @@ var _ = Describe("eventHandler", func() { }) AfterEach(func() { - Expect(handler.cfg.nginxConfiguredOnStartChecker.ready).To(BeTrue()) + Expect(handler.cfg.graphBuiltHealthChecker.ready).To(BeTrue()) }) When("a batch has one event", func() { @@ -416,23 +409,6 @@ var _ = Describe("eventHandler", func() { BeforeEach(func() { fakeProcessor.ProcessReturns(state.EndpointsOnlyChange, &graph.Graph{}) - upstreams := ngxclient.Upstreams{ - "one": ngxclient.Upstream{ - Peers: []ngxclient.Peer{ - {Server: "server1"}, - }, - }, - } - - streamUpstreams := ngxclient.StreamUpstreams{ - "two": ngxclient.StreamUpstream{ - Peers: []ngxclient.StreamPeer{ - {Server: "server2"}, - }, - }, - } - - fakeNginxRuntimeMgr.GetUpstreamsReturns(upstreams, streamUpstreams, nil) }) When("running NGINX Plus", func() { @@ -445,8 +421,7 @@ var _ = Describe("eventHandler", func() { Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty()) Expect(fakeGenerator.GenerateCallCount()).To(Equal(0)) - Expect(fakeNginxFileMgr.ReplaceFilesCallCount()).To(Equal(0)) - Expect(fakeNginxRuntimeMgr.GetUpstreamsCallCount()).To(Equal(1)) + Expect(fakeNginxUpdater.UpdateUpstreamServersCallCount()).To(Equal(1)) }) }) @@ -458,90 +433,20 @@ var _ = Describe("eventHandler", func() { Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty()) Expect(fakeGenerator.GenerateCallCount()).To(Equal(1)) - Expect(fakeNginxFileMgr.ReplaceFilesCallCount()).To(Equal(1)) - Expect(fakeNginxRuntimeMgr.GetUpstreamsCallCount()).To(Equal(0)) - Expect(fakeNginxRuntimeMgr.ReloadCallCount()).To(Equal(1)) + Expect(fakeNginxUpdater.UpdateConfigCallCount()).To(Equal(1)) + Expect(fakeNginxUpdater.UpdateUpstreamServersCallCount()).To(Equal(0)) }) }) }) - When("updating upstream servers", func() { - conf := dataplane.Configuration{ - Upstreams: []dataplane.Upstream{ - { - Name: "one", - }, - }, - StreamUpstreams: []dataplane.Upstream{ - { - Name: "two", - }, - }, - } - - BeforeEach(func() { - upstreams := ngxclient.Upstreams{ - "one": ngxclient.Upstream{ - Peers: []ngxclient.Peer{ - {Server: "server1"}, - }, - }, - } - - streamUpstreams := ngxclient.StreamUpstreams{ - "two": ngxclient.StreamUpstream{ - Peers: []ngxclient.StreamPeer{ - {Server: "server2"}, - }, - }, - } - - fakeNginxRuntimeMgr.GetUpstreamsReturns(upstreams, streamUpstreams, nil) - }) - - When("running NGINX Plus", func() { - BeforeEach(func() { - handler.cfg.plus = true - }) - - It("should update servers using the NGINX Plus API", func() { - Expect(handler.updateUpstreamServers(conf)).To(Succeed()) - Expect(fakeNginxRuntimeMgr.UpdateHTTPServersCallCount()).To(Equal(1)) - }) - - It("should return error when GET API returns an error", func() { - fakeNginxRuntimeMgr.GetUpstreamsReturns(nil, nil, errors.New("error")) - Expect(handler.updateUpstreamServers(conf)).ToNot(Succeed()) - }) - - It("should return error when UpdateHTTPServers API returns an error", func() { - fakeNginxRuntimeMgr.UpdateHTTPServersReturns(errors.New("error")) - Expect(handler.updateUpstreamServers(conf)).ToNot(Succeed()) - }) - - It("should return error when UpdateStreamServers API returns an error", func() { - fakeNginxRuntimeMgr.UpdateStreamServersReturns(errors.New("error")) - Expect(handler.updateUpstreamServers(conf)).ToNot(Succeed()) - }) - }) - - When("not running NGINX Plus", func() { - It("should not do anything", func() { - Expect(handler.updateUpstreamServers(conf)).To(Succeed()) - - Expect(fakeNginxRuntimeMgr.UpdateHTTPServersCallCount()).To(Equal(0)) - }) - }) - }) - - It("should set the health checker status properly when there are changes", func() { + It("should set the health checker status properly", func() { e := &events.UpsertEvent{Resource: &gatewayv1.HTTPRoute{}} batch := []interface{}{e} - readyChannel := handler.cfg.nginxConfiguredOnStartChecker.getReadyCh() + readyChannel := handler.cfg.graphBuiltHealthChecker.getReadyCh() fakeProcessor.ProcessReturns(state.ClusterStateChange, &graph.Graph{}) - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).ToNot(Succeed()) + Expect(handler.cfg.graphBuiltHealthChecker.readyCheck(nil)).ToNot(Succeed()) handler.HandleEventBatch(context.Background(), ctlrZap.New(), batch) dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 1) @@ -549,55 +454,7 @@ var _ = Describe("eventHandler", func() { Expect(readyChannel).To(BeClosed()) - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).To(Succeed()) - }) - - It("should set the health checker status properly when there are no changes or errors", func() { - e := &events.UpsertEvent{Resource: &gatewayv1.HTTPRoute{}} - batch := []interface{}{e} - readyChannel := handler.cfg.nginxConfiguredOnStartChecker.getReadyCh() - - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).ToNot(Succeed()) - handler.HandleEventBatch(context.Background(), ctlrZap.New(), batch) - - Expect(handler.GetLatestConfiguration()).To(BeNil()) - - Expect(readyChannel).To(BeClosed()) - - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).To(Succeed()) - }) - - It("should set the health checker status properly when there is an error", func() { - e := &events.UpsertEvent{Resource: &gatewayv1.HTTPRoute{}} - batch := []interface{}{e} - readyChannel := handler.cfg.nginxConfiguredOnStartChecker.getReadyCh() - - fakeProcessor.ProcessReturns(state.ClusterStateChange, &graph.Graph{}) - fakeNginxRuntimeMgr.ReloadReturns(errors.New("reload error")) - - handler.HandleEventBatch(context.Background(), ctlrZap.New(), batch) - - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).ToNot(Succeed()) - - // now send an update with no changes; should still return an error - fakeProcessor.ProcessReturns(state.NoChange, &graph.Graph{}) - - handler.HandleEventBatch(context.Background(), ctlrZap.New(), batch) - - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).ToNot(Succeed()) - - // error goes away - fakeProcessor.ProcessReturns(state.ClusterStateChange, &graph.Graph{}) - fakeNginxRuntimeMgr.ReloadReturns(nil) - - handler.HandleEventBatch(context.Background(), ctlrZap.New(), batch) - - dcfg := dataplane.GetDefaultConfiguration(&graph.Graph{}, 2) - Expect(helpers.Diff(handler.GetLatestConfiguration(), &dcfg)).To(BeEmpty()) - - Expect(readyChannel).To(BeClosed()) - - Expect(handler.cfg.nginxConfiguredOnStartChecker.readyCheck(nil)).To(Succeed()) + Expect(handler.cfg.graphBuiltHealthChecker.readyCheck(nil)).To(Succeed()) }) It("should panic for an unknown event type", func() { @@ -614,83 +471,6 @@ var _ = Describe("eventHandler", func() { }) }) -var _ = Describe("serversEqual", func() { - DescribeTable("determines if HTTP server lists are equal", - func(newServers []ngxclient.UpstreamServer, oldServers []ngxclient.Peer, equal bool) { - Expect(serversEqual(newServers, oldServers)).To(Equal(equal)) - }, - Entry("different length", - []ngxclient.UpstreamServer{ - {Server: "server1"}, - }, - []ngxclient.Peer{ - {Server: "server1"}, - {Server: "server2"}, - }, - false, - ), - Entry("differing elements", - []ngxclient.UpstreamServer{ - {Server: "server1"}, - {Server: "server2"}, - }, - []ngxclient.Peer{ - {Server: "server1"}, - {Server: "server3"}, - }, - false, - ), - Entry("same elements", - []ngxclient.UpstreamServer{ - {Server: "server1"}, - {Server: "server2"}, - }, - []ngxclient.Peer{ - {Server: "server1"}, - {Server: "server2"}, - }, - true, - ), - ) - DescribeTable("determines if stream server lists are equal", - func(newServers []ngxclient.StreamUpstreamServer, oldServers []ngxclient.StreamPeer, equal bool) { - Expect(serversEqual(newServers, oldServers)).To(Equal(equal)) - }, - Entry("different length", - []ngxclient.StreamUpstreamServer{ - {Server: "server1"}, - }, - []ngxclient.StreamPeer{ - {Server: "server1"}, - {Server: "server2"}, - }, - false, - ), - Entry("differing elements", - []ngxclient.StreamUpstreamServer{ - {Server: "server1"}, - {Server: "server2"}, - }, - []ngxclient.StreamPeer{ - {Server: "server1"}, - {Server: "server3"}, - }, - false, - ), - Entry("same elements", - []ngxclient.StreamUpstreamServer{ - {Server: "server1"}, - {Server: "server2"}, - }, - []ngxclient.StreamPeer{ - {Server: "server1"}, - {Server: "server2"}, - }, - true, - ), - ) -}) - var _ = Describe("getGatewayAddresses", func() { It("gets gateway addresses from a Service", func() { fakeClient := fake.NewFakeClient() diff --git a/internal/mode/static/health.go b/internal/mode/static/health.go index 180c67d643..a0fe4e9b59 100644 --- a/internal/mode/static/health.go +++ b/internal/mode/static/health.go @@ -6,49 +6,44 @@ import ( "sync" ) -// newNginxConfiguredOnStartChecker creates a new nginxConfiguredOnStartChecker. -func newNginxConfiguredOnStartChecker() *nginxConfiguredOnStartChecker { - return &nginxConfiguredOnStartChecker{ +// newGraphBuiltHealthChecker creates a new graphBuiltHealthChecker. +func newGraphBuiltHealthChecker() *graphBuiltHealthChecker { + return &graphBuiltHealthChecker{ readyCh: make(chan struct{}), } } -// nginxConfiguredOnStartChecker is used to check if nginx is successfully configured and if the NGF Pod is ready. -type nginxConfiguredOnStartChecker struct { - // firstBatchError is set when the first batch fails to configure nginx - // and we don't want to set ourselves as ready on the next batch if nothing changes - firstBatchError error - // readyCh is a channel that is initialized in newNginxConfiguredOnStartChecker and represents if the NGF Pod is ready. +// graphBuiltHealthChecker is used to check if the initial graph is built and the NGF Pod is ready. +type graphBuiltHealthChecker struct { + // readyCh is a channel that is initialized in newGraphBuiltHealthChecker and represents if the NGF Pod is ready. readyCh chan struct{} lock sync.RWMutex ready bool } // readyCheck returns the ready-state of the Pod. It satisfies the controller-runtime Checker type. -// We are considered ready after the handler processed the first batch. In case there is NGINX configuration -// to write, it must be written and NGINX must be reloaded successfully. -func (h *nginxConfiguredOnStartChecker) readyCheck(_ *http.Request) error { +// We are considered ready after the first graph is built. +func (h *graphBuiltHealthChecker) readyCheck(_ *http.Request) error { h.lock.RLock() defer h.lock.RUnlock() if !h.ready { - return errors.New("nginx has not yet become ready to accept traffic") + return errors.New("control plane is not yet ready") } return nil } // setAsReady marks the health check as ready. -func (h *nginxConfiguredOnStartChecker) setAsReady() { +func (h *graphBuiltHealthChecker) setAsReady() { h.lock.Lock() defer h.lock.Unlock() h.ready = true - h.firstBatchError = nil close(h.readyCh) } // getReadyCh returns a read-only channel, which determines if the NGF Pod is ready. -func (h *nginxConfiguredOnStartChecker) getReadyCh() <-chan struct{} { +func (h *graphBuiltHealthChecker) getReadyCh() <-chan struct{} { return h.readyCh } diff --git a/internal/mode/static/health_test.go b/internal/mode/static/health_test.go index 5bfd7aab73..7246283ed9 100644 --- a/internal/mode/static/health_test.go +++ b/internal/mode/static/health_test.go @@ -9,9 +9,9 @@ import ( func TestReadyCheck(t *testing.T) { t.Parallel() g := NewWithT(t) - nginxChecker := newNginxConfiguredOnStartChecker() - g.Expect(nginxChecker.readyCheck(nil)).ToNot(Succeed()) + healthChecker := newGraphBuiltHealthChecker() + g.Expect(healthChecker.readyCheck(nil)).ToNot(Succeed()) - nginxChecker.ready = true - g.Expect(nginxChecker.readyCheck(nil)).To(Succeed()) + healthChecker.ready = true + g.Expect(healthChecker.readyCheck(nil)).To(Succeed()) } diff --git a/internal/mode/static/manager.go b/internal/mode/static/manager.go index afb0560179..fc2ced95f2 100644 --- a/internal/mode/static/manager.go +++ b/internal/mode/static/manager.go @@ -3,7 +3,6 @@ package static import ( "context" "fmt" - "os" "time" "github.com/go-logr/logr" @@ -49,14 +48,13 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics/collectors" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/agent" ngxcfg "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/clientsettings" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/observability" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/upstreamsettings" ngxvalidation "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/validation" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" - ngxruntime "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/graph" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver" @@ -88,10 +86,9 @@ func init() { utilruntime.Must(appsv1.AddToScheme(scheme)) } -//nolint:gocyclo func StartManager(cfg config.Config) error { - nginxChecker := newNginxConfiguredOnStartChecker() - mgr, err := createManager(cfg, nginxChecker) + healthChecker := newGraphBuiltHealthChecker() + mgr, err := createManager(cfg, healthChecker) if err != nil { return fmt.Errorf("cannot build runtime manager: %w", err) } @@ -148,64 +145,20 @@ func StartManager(cfg config.Config) error { PlusSecrets: plusSecrets, }) - // Clear the configuration folders to ensure that no files are left over in case the control plane was restarted - // (this assumes the folders are in a shared volume). - removedPaths, err := file.ClearFolders(file.NewStdLibOSFileManager(), ngxcfg.ConfigFolders) - for _, path := range removedPaths { - cfg.Logger.Info("removed configuration file", "path", path) - } - if err != nil { - return fmt.Errorf("cannot clear NGINX configuration folders: %w", err) - } - - processHandler := ngxruntime.NewProcessHandlerImpl(os.ReadFile, os.Stat) - - // Ensure NGINX is running before registering metrics & starting the manager. - p, err := processHandler.FindMainProcess(ctx, ngxruntime.PidFileTimeout) - if err != nil { - return fmt.Errorf("NGINX is not running: %w", err) - } - cfg.Logger.V(1).Info("NGINX is running with PID", "pid", p) - - var ( - ngxruntimeCollector ngxruntime.MetricsCollector = collectors.NewManagerNoopCollector() - handlerCollector handlerMetricsCollector = collectors.NewControllerNoopCollector() - ) - - var ngxPlusClient ngxruntime.NginxPlusClient - if cfg.Plus { - ngxPlusClient, err = ngxruntime.CreatePlusClient() - if err != nil { - return fmt.Errorf("error creating NGINX plus client: %w", err) - } - } + var handlerCollector handlerMetricsCollector = collectors.NewControllerNoopCollector() if cfg.MetricsConfig.Enabled { constLabels := map[string]string{"class": cfg.GatewayClassName} - var ngxCollector prometheus.Collector - if cfg.Plus { - ngxCollector, err = collectors.NewNginxPlusMetricsCollector(ngxPlusClient, constLabels, promLogger) - } else { - ngxCollector = collectors.NewNginxMetricsCollector(constLabels, promLogger) - } - if err != nil { - return fmt.Errorf("cannot create nginx metrics collector: %w", err) - } - ngxruntimeCollector = collectors.NewManagerMetricsCollector(constLabels) + ngxruntimeCollector := collectors.NewManagerMetricsCollector(constLabels) handlerCollector = collectors.NewControllerCollector(constLabels) - ngxruntimeCollector, ok := ngxruntimeCollector.(prometheus.Collector) - if !ok { - return fmt.Errorf("ngxruntimeCollector is not a prometheus.Collector: %w", status.ErrFailedAssert) - } handlerCollector, ok := handlerCollector.(prometheus.Collector) if !ok { return fmt.Errorf("handlerCollector is not a prometheus.Collector: %w", status.ErrFailedAssert) } metrics.Registry.MustRegister( - ngxCollector, ngxruntimeCollector, handlerCollector, ) @@ -224,37 +177,30 @@ func StartManager(cfg config.Config) error { }) eventHandler := newEventHandlerImpl(eventHandlerConfig{ - nginxFileMgr: file.NewManagerImpl( - cfg.Logger.WithName("nginxFileManager"), - file.NewStdLibOSFileManager(), - ), + nginxUpdater: &agent.NginxUpdaterImpl{ + Logger: cfg.Logger.WithName("nginxUpdater"), + Plus: cfg.Plus, + }, metricsCollector: handlerCollector, - nginxRuntimeMgr: ngxruntime.NewManagerImpl( - ngxPlusClient, - ngxruntimeCollector, - cfg.Logger.WithName("nginxRuntimeManager"), - processHandler, - ngxruntime.NewVerifyClient(ngxruntime.NginxReloadTimeout), - ), - statusUpdater: groupStatusUpdater, - processor: processor, - serviceResolver: resolver.NewServiceResolverImpl(mgr.GetClient()), + statusUpdater: groupStatusUpdater, + processor: processor, + serviceResolver: resolver.NewServiceResolverImpl(mgr.GetClient()), generator: ngxcfg.NewGeneratorImpl( cfg.Plus, &cfg.UsageReportConfig, cfg.Logger.WithName("generator"), ), - k8sClient: mgr.GetClient(), - k8sReader: mgr.GetAPIReader(), - logLevelSetter: logLevelSetter, - eventRecorder: recorder, - deployCtxCollector: deployCtxCollector, - nginxConfiguredOnStartChecker: nginxChecker, - gatewayPodConfig: cfg.GatewayPodConfig, - controlConfigNSName: controlConfigNSName, - gatewayCtlrName: cfg.GatewayCtlrName, - updateGatewayClassStatus: cfg.UpdateGatewayClassStatus, - plus: cfg.Plus, + k8sClient: mgr.GetClient(), + k8sReader: mgr.GetAPIReader(), + logLevelSetter: logLevelSetter, + eventRecorder: recorder, + deployCtxCollector: deployCtxCollector, + graphBuiltHealthChecker: healthChecker, + gatewayPodConfig: cfg.GatewayPodConfig, + controlConfigNSName: controlConfigNSName, + gatewayCtlrName: cfg.GatewayCtlrName, + updateGatewayClassStatus: cfg.UpdateGatewayClassStatus, + plus: cfg.Plus, }) objects, objectLists := prepareFirstEventBatchPreparerArgs(cfg) @@ -289,7 +235,7 @@ func StartManager(cfg config.Config) error { Flags: cfg.Flags, }) - job, err := createTelemetryJob(cfg, dataCollector, nginxChecker.getReadyCh()) + job, err := createTelemetryJob(cfg, dataCollector, healthChecker.getReadyCh()) if err != nil { return fmt.Errorf("cannot create telemetry job: %w", err) } @@ -330,7 +276,7 @@ func createPolicyManager( return policies.NewManager(mustExtractGVK, cfgs...) } -func createManager(cfg config.Config, nginxChecker *nginxConfiguredOnStartChecker) (manager.Manager, error) { +func createManager(cfg config.Config, healthChecker *graphBuiltHealthChecker) (manager.Manager, error) { options := manager.Options{ Scheme: scheme, Logger: cfg.Logger.V(1), @@ -365,7 +311,7 @@ func createManager(cfg config.Config, nginxChecker *nginxConfiguredOnStartChecke } if cfg.HealthConfig.Enabled { - if err := mgr.AddReadyzCheck("readyz", nginxChecker.readyCheck); err != nil { + if err := mgr.AddReadyzCheck("readyz", healthChecker.readyCheck); err != nil { return nil, fmt.Errorf("error adding ready check: %w", err) } } diff --git a/internal/mode/static/metrics/collectors/nginx.go b/internal/mode/static/metrics/collectors/nginx.go deleted file mode 100644 index f8ce60b26a..0000000000 --- a/internal/mode/static/metrics/collectors/nginx.go +++ /dev/null @@ -1,48 +0,0 @@ -package collectors - -import ( - "fmt" - - "github.com/go-kit/log" - "github.com/nginxinc/nginx-plus-go-client/client" - prometheusClient "github.com/nginxinc/nginx-prometheus-exporter/client" - nginxCollector "github.com/nginxinc/nginx-prometheus-exporter/collector" - "github.com/prometheus/client_golang/prometheus" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" -) - -const ( - nginxStatusSock = "/var/run/nginx/nginx-status.sock" - nginxStatusURI = "http://config-status/stub_status" -) - -// NewNginxMetricsCollector creates an NginxCollector which fetches stats from NGINX over a unix socket. -func NewNginxMetricsCollector(constLabels map[string]string, logger log.Logger) prometheus.Collector { - httpClient := runtime.GetSocketClient(nginxStatusSock) - ngxClient := prometheusClient.NewNginxClient(&httpClient, nginxStatusURI) - - return nginxCollector.NewNginxCollector(ngxClient, metrics.Namespace, constLabels, logger) -} - -// NewNginxPlusMetricsCollector creates an NginxCollector which fetches stats from NGINX Plus API over a unix socket. -func NewNginxPlusMetricsCollector( - plusClient runtime.NginxPlusClient, - constLabels map[string]string, - logger log.Logger, -) (prometheus.Collector, error) { - nc, ok := plusClient.(*client.NginxClient) - if !ok { - panic(fmt.Sprintf("expected *client.NginxClient, got %T", plusClient)) - } - collector := nginxCollector.NewNginxPlusCollector( - nc, - metrics.Namespace, - nginxCollector.VariableLabelNames{}, - constLabels, - logger, - ) - - return collector, nil -} diff --git a/internal/mode/static/metrics/collectors/nginx_runtime.go b/internal/mode/static/metrics/collectors/nginx_runtime.go index 5195e603d6..0ff2dea509 100644 --- a/internal/mode/static/metrics/collectors/nginx_runtime.go +++ b/internal/mode/static/metrics/collectors/nginx_runtime.go @@ -8,6 +8,15 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics" ) +// MetricsCollector is an interface for the metrics of the NGINX runtime manager. +// +//counterfeiter:generate . MetricsCollector +type MetricsCollector interface { + IncReloadCount() + IncReloadErrors() + ObserveLastReloadTime(ms time.Duration) +} + // NginxRuntimeCollector implements runtime.Collector interface and prometheus.Collector interface. type NginxRuntimeCollector struct { // Metrics @@ -97,20 +106,3 @@ func (c *NginxRuntimeCollector) Collect(ch chan<- prometheus.Metric) { c.configStale.Collect(ch) c.reloadsDuration.Collect(ch) } - -// ManagerNoopCollector used to initialize the ManagerCollector when metrics are disabled to avoid nil pointer errors. -type ManagerNoopCollector struct{} - -// NewManagerNoopCollector creates a no-op collector that implements ManagerCollector interface. -func NewManagerNoopCollector() *ManagerNoopCollector { - return &ManagerNoopCollector{} -} - -// IncReloadCount implements a no-op IncReloadCount. -func (c *ManagerNoopCollector) IncReloadCount() {} - -// IncReloadErrors implements a no-op IncReloadErrors. -func (c *ManagerNoopCollector) IncReloadErrors() {} - -// ObserveLastReloadTime implements a no-op ObserveLastReloadTime. -func (c *ManagerNoopCollector) ObserveLastReloadTime(_ time.Duration) {} diff --git a/internal/mode/static/nginx/agent/agent.go b/internal/mode/static/nginx/agent/agent.go new file mode 100644 index 0000000000..93777628f2 --- /dev/null +++ b/internal/mode/static/nginx/agent/agent.go @@ -0,0 +1,36 @@ +package agent + +import ( + "github.com/go-logr/logr" +) + +//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate + +//counterfeiter:generate . NginxUpdater + +// NginxUpdater is an interface for updating NGINX using the NGINX agent. +type NginxUpdater interface { + UpdateConfig(int) + UpdateUpstreamServers() +} + +// NginxUpdaterImpl implements the NginxUpdater interface. +type NginxUpdaterImpl struct { + Logger logr.Logger + Plus bool +} + +// UpdateConfig sends the nginx configuration to the agent. +func (n *NginxUpdaterImpl) UpdateConfig(files int) { + n.Logger.Info("Sending nginx configuration to agent", "numFiles", files) +} + +// UpdateUpstreamServers sends an APIRequest to the agent to update upstream servers using the NGINX Plus API. +// Only applicable when using NGINX Plus. +func (n *NginxUpdaterImpl) UpdateUpstreamServers() { + if !n.Plus { + return + } + + n.Logger.Info("Updating upstream servers using NGINX Plus API") +} diff --git a/internal/mode/static/nginx/agent/agentfakes/fake_nginx_updater.go b/internal/mode/static/nginx/agent/agentfakes/fake_nginx_updater.go new file mode 100644 index 0000000000..0133814151 --- /dev/null +++ b/internal/mode/static/nginx/agent/agentfakes/fake_nginx_updater.go @@ -0,0 +1,106 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package agentfakes + +import ( + "sync" + + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/agent" +) + +type FakeNginxUpdater struct { + UpdateConfigStub func(int) + updateConfigMutex sync.RWMutex + updateConfigArgsForCall []struct { + arg1 int + } + UpdateUpstreamServersStub func() + updateUpstreamServersMutex sync.RWMutex + updateUpstreamServersArgsForCall []struct { + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeNginxUpdater) UpdateConfig(arg1 int) { + fake.updateConfigMutex.Lock() + fake.updateConfigArgsForCall = append(fake.updateConfigArgsForCall, struct { + arg1 int + }{arg1}) + stub := fake.UpdateConfigStub + fake.recordInvocation("UpdateConfig", []interface{}{arg1}) + fake.updateConfigMutex.Unlock() + if stub != nil { + fake.UpdateConfigStub(arg1) + } +} + +func (fake *FakeNginxUpdater) UpdateConfigCallCount() int { + fake.updateConfigMutex.RLock() + defer fake.updateConfigMutex.RUnlock() + return len(fake.updateConfigArgsForCall) +} + +func (fake *FakeNginxUpdater) UpdateConfigCalls(stub func(int)) { + fake.updateConfigMutex.Lock() + defer fake.updateConfigMutex.Unlock() + fake.UpdateConfigStub = stub +} + +func (fake *FakeNginxUpdater) UpdateConfigArgsForCall(i int) int { + fake.updateConfigMutex.RLock() + defer fake.updateConfigMutex.RUnlock() + argsForCall := fake.updateConfigArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeNginxUpdater) UpdateUpstreamServers() { + fake.updateUpstreamServersMutex.Lock() + fake.updateUpstreamServersArgsForCall = append(fake.updateUpstreamServersArgsForCall, struct { + }{}) + stub := fake.UpdateUpstreamServersStub + fake.recordInvocation("UpdateUpstreamServers", []interface{}{}) + fake.updateUpstreamServersMutex.Unlock() + if stub != nil { + fake.UpdateUpstreamServersStub() + } +} + +func (fake *FakeNginxUpdater) UpdateUpstreamServersCallCount() int { + fake.updateUpstreamServersMutex.RLock() + defer fake.updateUpstreamServersMutex.RUnlock() + return len(fake.updateUpstreamServersArgsForCall) +} + +func (fake *FakeNginxUpdater) UpdateUpstreamServersCalls(stub func()) { + fake.updateUpstreamServersMutex.Lock() + defer fake.updateUpstreamServersMutex.Unlock() + fake.UpdateUpstreamServersStub = stub +} + +func (fake *FakeNginxUpdater) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.updateConfigMutex.RLock() + defer fake.updateConfigMutex.RUnlock() + fake.updateUpstreamServersMutex.RLock() + defer fake.updateUpstreamServersMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeNginxUpdater) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ agent.NginxUpdater = new(FakeNginxUpdater) diff --git a/internal/mode/static/nginx/agent/doc.go b/internal/mode/static/nginx/agent/doc.go new file mode 100644 index 0000000000..8ffe4381f3 --- /dev/null +++ b/internal/mode/static/nginx/agent/doc.go @@ -0,0 +1,4 @@ +/* +Package agent contains the functions for sending nginx configuration to the agent. +*/ +package agent diff --git a/internal/mode/static/nginx/config/configfakes/fake_generator.go b/internal/mode/static/nginx/config/configfakes/fake_generator.go index d2b3a6e7b7..9746df5178 100644 --- a/internal/mode/static/nginx/config/configfakes/fake_generator.go +++ b/internal/mode/static/nginx/config/configfakes/fake_generator.go @@ -4,8 +4,8 @@ package configfakes import ( "sync" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "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" ) diff --git a/internal/mode/static/nginx/config/convert.go b/internal/mode/static/nginx/config/convert.go deleted file mode 100644 index 3038149a0e..0000000000 --- a/internal/mode/static/nginx/config/convert.go +++ /dev/null @@ -1,58 +0,0 @@ -package config - -import ( - "fmt" - - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver" -) - -// ConvertEndpoints converts a list of Endpoints into a list of NGINX Plus SDK UpstreamServers. -func ConvertEndpoints(eps []resolver.Endpoint) []ngxclient.UpstreamServer { - servers := make([]ngxclient.UpstreamServer, 0, len(eps)) - - for _, ep := range eps { - port, format := getPortAndIPFormat(ep) - - server := ngxclient.UpstreamServer{ - Server: fmt.Sprintf(format, ep.Address, port), - } - - servers = append(servers, server) - } - - return servers -} - -// ConvertStreamEndpoints converts a list of Endpoints into a list of NGINX Plus SDK StreamUpstreamServers. -func ConvertStreamEndpoints(eps []resolver.Endpoint) []ngxclient.StreamUpstreamServer { - servers := make([]ngxclient.StreamUpstreamServer, 0, len(eps)) - - for _, ep := range eps { - port, format := getPortAndIPFormat(ep) - - server := ngxclient.StreamUpstreamServer{ - Server: fmt.Sprintf(format, ep.Address, port), - } - - servers = append(servers, server) - } - - return servers -} - -func getPortAndIPFormat(ep resolver.Endpoint) (string, string) { - var port string - - if ep.Port != 0 { - port = fmt.Sprintf(":%d", ep.Port) - } - - format := "%s%s" - if ep.IPv6 { - format = "[%s]%s" - } - - return port, format -} diff --git a/internal/mode/static/nginx/config/convert_test.go b/internal/mode/static/nginx/config/convert_test.go deleted file mode 100644 index 68520dfd78..0000000000 --- a/internal/mode/static/nginx/config/convert_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package config - -import ( - "testing" - - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" - . "github.com/onsi/gomega" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver" -) - -func TestConvertEndpoints(t *testing.T) { - t.Parallel() - endpoints := []resolver.Endpoint{ - { - Address: "1.2.3.4", - Port: 80, - }, - { - Address: "5.6.7.8", - Port: 0, - }, - { - Address: "2001:db8::1", - Port: 443, - IPv6: true, - }, - } - - expUpstreams := []ngxclient.UpstreamServer{ - { - Server: "1.2.3.4:80", - }, - { - Server: "5.6.7.8", - }, - { - Server: "[2001:db8::1]:443", - }, - } - - g := NewWithT(t) - g.Expect(ConvertEndpoints(endpoints)).To(Equal(expUpstreams)) -} - -func TestConvertStreamEndpoints(t *testing.T) { - t.Parallel() - endpoints := []resolver.Endpoint{ - { - Address: "1.2.3.4", - Port: 80, - }, - { - Address: "5.6.7.8", - Port: 0, - }, - { - Address: "2001:db8::1", - Port: 443, - IPv6: true, - }, - } - - expUpstreams := []ngxclient.StreamUpstreamServer{ - { - Server: "1.2.3.4:80", - }, - { - Server: "5.6.7.8", - }, - { - Server: "[2001:db8::1]:443", - }, - } - - g := NewWithT(t) - g.Expect(ConvertStreamEndpoints(endpoints)).To(Equal(expUpstreams)) -} diff --git a/internal/mode/static/nginx/config/generator.go b/internal/mode/static/nginx/config/generator.go index a408cffd6a..df43d0fb5c 100644 --- a/internal/mode/static/nginx/config/generator.go +++ b/internal/mode/static/nginx/config/generator.go @@ -7,13 +7,13 @@ import ( "github.com/go-logr/logr" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" ngfConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/http" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/clientsettings" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/observability" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies/upstreamsettings" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" ) @@ -47,9 +47,6 @@ const ( // streamConfigFile is the path to the configuration file with Stream configuration. streamConfigFile = streamFolder + "/stream.conf" - // configVersionFile is the path to the config version configuration file. - configVersionFile = httpFolder + "/config-version.conf" - // httpMatchVarsFile is the path to the http_match pairs configuration file. httpMatchVarsFile = httpFolder + "/matches.json" @@ -60,10 +57,6 @@ const ( mgmtIncludesFile = mainIncludesFolder + "/mgmt.conf" ) -// ConfigFolders is a list of folders where NGINX configuration files are stored. -// Volumes here also need to be added to our crossplane ephemeral test container. -var ConfigFolders = []string{httpFolder, secretsFolder, includesFolder, mainIncludesFolder, streamFolder} - // Generator generates NGINX configuration files. // This interface is used for testing purposes only. type Generator interface { @@ -198,7 +191,6 @@ func (g GeneratorImpl) getExecuteFuncs( g.executeStreamServers, g.executeStreamUpstreams, executeStreamMaps, - executeVersion, } } diff --git a/internal/mode/static/nginx/config/generator_test.go b/internal/mode/static/nginx/config/generator_test.go index a0a5670c26..a6f4540adb 100644 --- a/internal/mode/static/nginx/config/generator_test.go +++ b/internal/mode/static/nginx/config/generator_test.go @@ -1,7 +1,6 @@ package config_test import ( - "fmt" "sort" "testing" @@ -9,10 +8,10 @@ import ( "k8s.io/apimachinery/pkg/types" ctlrZap "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" ngfConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "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/graph" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver" @@ -144,7 +143,7 @@ func TestGenerate(t *testing.T) { files := generator.Generate(conf) - g.Expect(files).To(HaveLen(17)) + g.Expect(files).To(HaveLen(16)) arrange := func(i, j int) bool { return files[i].Path < files[j].Path } @@ -152,7 +151,6 @@ func TestGenerate(t *testing.T) { /* Order of files: - /etc/nginx/conf.d/config-version.conf /etc/nginx/conf.d/http.conf /etc/nginx/conf.d/matches.json /etc/nginx/includes/http_snippet1.conf @@ -172,13 +170,8 @@ func TestGenerate(t *testing.T) { */ g.Expect(files[0].Type).To(Equal(file.TypeRegular)) - g.Expect(files[0].Path).To(Equal("/etc/nginx/conf.d/config-version.conf")) - configVersion := string(files[0].Content) - g.Expect(configVersion).To(ContainSubstring(fmt.Sprintf("return 200 %d", conf.Version))) - - g.Expect(files[1].Type).To(Equal(file.TypeRegular)) - g.Expect(files[1].Path).To(Equal("/etc/nginx/conf.d/http.conf")) - httpCfg := string(files[1].Content) // converting to string so that on failure gomega prints strings not byte arrays + g.Expect(files[0].Path).To(Equal("/etc/nginx/conf.d/http.conf")) + httpCfg := string(files[0].Content) // converting to string so that on failure gomega prints strings not byte arrays // Note: this only verifies that Generate() returns a byte array with upstream, server, and split_client blocks. // It does not test the correctness of those blocks. That functionality is covered by other tests in this package. g.Expect(httpCfg).To(ContainSubstring("listen 80")) @@ -195,34 +188,34 @@ func TestGenerate(t *testing.T) { g.Expect(httpCfg).To(ContainSubstring("include /etc/nginx/includes/http_snippet1.conf;")) g.Expect(httpCfg).To(ContainSubstring("include /etc/nginx/includes/http_snippet2.conf;")) - g.Expect(files[2].Path).To(Equal("/etc/nginx/conf.d/matches.json")) + g.Expect(files[1].Path).To(Equal("/etc/nginx/conf.d/matches.json")) - g.Expect(files[2].Type).To(Equal(file.TypeRegular)) + g.Expect(files[1].Type).To(Equal(file.TypeRegular)) expString := "{}" - g.Expect(string(files[2].Content)).To(Equal(expString)) + g.Expect(string(files[1].Content)).To(Equal(expString)) // snippet include files // content is not checked in this test. - g.Expect(files[3].Path).To(Equal("/etc/nginx/includes/http_snippet1.conf")) - g.Expect(files[4].Path).To(Equal("/etc/nginx/includes/http_snippet2.conf")) - g.Expect(files[5].Path).To(Equal("/etc/nginx/includes/main_snippet1.conf")) - g.Expect(files[6].Path).To(Equal("/etc/nginx/includes/main_snippet2.conf")) + g.Expect(files[2].Path).To(Equal("/etc/nginx/includes/http_snippet1.conf")) + g.Expect(files[3].Path).To(Equal("/etc/nginx/includes/http_snippet2.conf")) + g.Expect(files[4].Path).To(Equal("/etc/nginx/includes/main_snippet1.conf")) + g.Expect(files[5].Path).To(Equal("/etc/nginx/includes/main_snippet2.conf")) - g.Expect(files[7].Path).To(Equal("/etc/nginx/main-includes/deployment_ctx.json")) - deploymentCtx := string(files[7].Content) + g.Expect(files[6].Path).To(Equal("/etc/nginx/main-includes/deployment_ctx.json")) + deploymentCtx := string(files[6].Content) g.Expect(deploymentCtx).To(ContainSubstring("\"integration\":\"ngf\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"cluster_id\":\"test-uid\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"installation_id\":\"test-uid-replicaSet\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"cluster_node_count\":1")) - g.Expect(files[8].Path).To(Equal("/etc/nginx/main-includes/main.conf")) - mainConfStr := string(files[8].Content) + g.Expect(files[7].Path).To(Equal("/etc/nginx/main-includes/main.conf")) + mainConfStr := string(files[7].Content) g.Expect(mainConfStr).To(ContainSubstring("load_module modules/ngx_otel_module.so;")) g.Expect(mainConfStr).To(ContainSubstring("include /etc/nginx/includes/main_snippet1.conf;")) g.Expect(mainConfStr).To(ContainSubstring("include /etc/nginx/includes/main_snippet2.conf;")) - g.Expect(files[9].Path).To(Equal("/etc/nginx/main-includes/mgmt.conf")) - mgmtConf := string(files[9].Content) + g.Expect(files[8].Path).To(Equal("/etc/nginx/main-includes/mgmt.conf")) + mgmtConf := string(files[8].Content) g.Expect(mgmtConf).To(ContainSubstring("usage_report endpoint=test-endpoint")) g.Expect(mgmtConf).To(ContainSubstring("license_token /etc/nginx/secrets/license.jwt")) g.Expect(mgmtConf).To(ContainSubstring("deployment_context /etc/nginx/main-includes/deployment_ctx.json")) @@ -230,31 +223,31 @@ func TestGenerate(t *testing.T) { g.Expect(mgmtConf).To(ContainSubstring("ssl_certificate /etc/nginx/secrets/mgmt-tls.crt")) g.Expect(mgmtConf).To(ContainSubstring("ssl_certificate_key /etc/nginx/secrets/mgmt-tls.key")) - g.Expect(files[10].Path).To(Equal("/etc/nginx/secrets/license.jwt")) - g.Expect(string(files[10].Content)).To(Equal("license")) + g.Expect(files[9].Path).To(Equal("/etc/nginx/secrets/license.jwt")) + g.Expect(string(files[9].Content)).To(Equal("license")) - g.Expect(files[11].Path).To(Equal("/etc/nginx/secrets/mgmt-ca.crt")) - g.Expect(string(files[11].Content)).To(Equal("ca")) + g.Expect(files[10].Path).To(Equal("/etc/nginx/secrets/mgmt-ca.crt")) + g.Expect(string(files[10].Content)).To(Equal("ca")) - g.Expect(files[12].Path).To(Equal("/etc/nginx/secrets/mgmt-tls.crt")) - g.Expect(string(files[12].Content)).To(Equal("cert")) + g.Expect(files[11].Path).To(Equal("/etc/nginx/secrets/mgmt-tls.crt")) + g.Expect(string(files[11].Content)).To(Equal("cert")) - g.Expect(files[13].Path).To(Equal("/etc/nginx/secrets/mgmt-tls.key")) - g.Expect(string(files[13].Content)).To(Equal("key")) + g.Expect(files[12].Path).To(Equal("/etc/nginx/secrets/mgmt-tls.key")) + g.Expect(string(files[12].Content)).To(Equal("key")) - g.Expect(files[14].Path).To(Equal("/etc/nginx/secrets/test-certbundle.crt")) - certBundle := string(files[14].Content) + g.Expect(files[13].Path).To(Equal("/etc/nginx/secrets/test-certbundle.crt")) + certBundle := string(files[13].Content) g.Expect(certBundle).To(Equal("test-cert")) - g.Expect(files[15]).To(Equal(file.File{ + g.Expect(files[14]).To(Equal(file.File{ Type: file.TypeSecret, Path: "/etc/nginx/secrets/test-keypair.pem", Content: []byte("test-cert\ntest-key"), })) - g.Expect(files[16].Path).To(Equal("/etc/nginx/stream-conf.d/stream.conf")) - g.Expect(files[16].Type).To(Equal(file.TypeRegular)) - streamCfg := string(files[16].Content) + g.Expect(files[15].Path).To(Equal("/etc/nginx/stream-conf.d/stream.conf")) + g.Expect(files[15].Type).To(Equal(file.TypeRegular)) + streamCfg := string(files[15].Content) g.Expect(streamCfg).To(ContainSubstring("listen unix:/var/run/nginx/app.example.com-443.sock")) g.Expect(streamCfg).To(ContainSubstring("listen 443")) g.Expect(streamCfg).To(ContainSubstring("app.example.com unix:/var/run/nginx/app.example.com-443.sock")) diff --git a/internal/mode/static/nginx/config/main_config.go b/internal/mode/static/nginx/config/main_config.go index 58cdef68cb..bd6f2256f9 100644 --- a/internal/mode/static/nginx/config/main_config.go +++ b/internal/mode/static/nginx/config/main_config.go @@ -3,9 +3,9 @@ package config import ( gotemplate "text/template" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/file" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/shared" - "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/graph" ) diff --git a/internal/mode/static/nginx/config/version.go b/internal/mode/static/nginx/config/version.go deleted file mode 100644 index 6e29f36056..0000000000 --- a/internal/mode/static/nginx/config/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package config - -import ( - gotemplate "text/template" - - "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" -) - -var versionTemplate = gotemplate.Must(gotemplate.New("version").Parse(versionTemplateText)) - -func executeVersion(conf dataplane.Configuration) []executeResult { - result := executeResult{ - dest: configVersionFile, - data: helpers.MustExecuteTemplate(versionTemplate, conf.Version), - } - - return []executeResult{result} -} diff --git a/internal/mode/static/nginx/config/version_template.go b/internal/mode/static/nginx/config/version_template.go deleted file mode 100644 index ccf46e02cc..0000000000 --- a/internal/mode/static/nginx/config/version_template.go +++ /dev/null @@ -1,12 +0,0 @@ -package config - -const versionTemplateText = ` -server { - listen unix:/var/run/nginx/nginx-config-version.sock; - access_log off; - - location /version { - return 200 {{.}}; - } -} -` diff --git a/internal/mode/static/nginx/config/version_test.go b/internal/mode/static/nginx/config/version_test.go deleted file mode 100644 index 3d30c6c3b2..0000000000 --- a/internal/mode/static/nginx/config/version_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package config - -import ( - "testing" - - . "github.com/onsi/gomega" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" -) - -func TestExecuteVersion(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - conf := dataplane.Configuration{Version: 42} - res := executeVersion(conf) - g.Expect(res).To(HaveLen(1)) - g.Expect(res[0].dest).To(Equal(configVersionFile)) - g.Expect(string(res[0].data)).To(ContainSubstring("return 200 42;")) -} diff --git a/internal/mode/static/nginx/file/filefakes/fake_clear_folders_osfile_manager.go b/internal/mode/static/nginx/file/filefakes/fake_clear_folders_osfile_manager.go deleted file mode 100644 index 15f57b79e3..0000000000 --- a/internal/mode/static/nginx/file/filefakes/fake_clear_folders_osfile_manager.go +++ /dev/null @@ -1,191 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package filefakes - -import ( - "os" - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" -) - -type FakeClearFoldersOSFileManager struct { - ReadDirStub func(string) ([]os.DirEntry, error) - readDirMutex sync.RWMutex - readDirArgsForCall []struct { - arg1 string - } - readDirReturns struct { - result1 []os.DirEntry - result2 error - } - readDirReturnsOnCall map[int]struct { - result1 []os.DirEntry - result2 error - } - RemoveStub func(string) error - removeMutex sync.RWMutex - removeArgsForCall []struct { - arg1 string - } - removeReturns struct { - result1 error - } - removeReturnsOnCall map[int]struct { - result1 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeClearFoldersOSFileManager) ReadDir(arg1 string) ([]os.DirEntry, error) { - fake.readDirMutex.Lock() - ret, specificReturn := fake.readDirReturnsOnCall[len(fake.readDirArgsForCall)] - fake.readDirArgsForCall = append(fake.readDirArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.ReadDirStub - fakeReturns := fake.readDirReturns - fake.recordInvocation("ReadDir", []interface{}{arg1}) - fake.readDirMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClearFoldersOSFileManager) ReadDirCallCount() int { - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - return len(fake.readDirArgsForCall) -} - -func (fake *FakeClearFoldersOSFileManager) ReadDirCalls(stub func(string) ([]os.DirEntry, error)) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = stub -} - -func (fake *FakeClearFoldersOSFileManager) ReadDirArgsForCall(i int) string { - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - argsForCall := fake.readDirArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeClearFoldersOSFileManager) ReadDirReturns(result1 []os.DirEntry, result2 error) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = nil - fake.readDirReturns = struct { - result1 []os.DirEntry - result2 error - }{result1, result2} -} - -func (fake *FakeClearFoldersOSFileManager) ReadDirReturnsOnCall(i int, result1 []os.DirEntry, result2 error) { - fake.readDirMutex.Lock() - defer fake.readDirMutex.Unlock() - fake.ReadDirStub = nil - if fake.readDirReturnsOnCall == nil { - fake.readDirReturnsOnCall = make(map[int]struct { - result1 []os.DirEntry - result2 error - }) - } - fake.readDirReturnsOnCall[i] = struct { - result1 []os.DirEntry - result2 error - }{result1, result2} -} - -func (fake *FakeClearFoldersOSFileManager) Remove(arg1 string) error { - fake.removeMutex.Lock() - ret, specificReturn := fake.removeReturnsOnCall[len(fake.removeArgsForCall)] - fake.removeArgsForCall = append(fake.removeArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.RemoveStub - fakeReturns := fake.removeReturns - fake.recordInvocation("Remove", []interface{}{arg1}) - fake.removeMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeClearFoldersOSFileManager) RemoveCallCount() int { - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() - return len(fake.removeArgsForCall) -} - -func (fake *FakeClearFoldersOSFileManager) RemoveCalls(stub func(string) error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = stub -} - -func (fake *FakeClearFoldersOSFileManager) RemoveArgsForCall(i int) string { - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() - argsForCall := fake.removeArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeClearFoldersOSFileManager) RemoveReturns(result1 error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = nil - fake.removeReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeClearFoldersOSFileManager) RemoveReturnsOnCall(i int, result1 error) { - fake.removeMutex.Lock() - defer fake.removeMutex.Unlock() - fake.RemoveStub = nil - if fake.removeReturnsOnCall == nil { - fake.removeReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.removeReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeClearFoldersOSFileManager) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.readDirMutex.RLock() - defer fake.readDirMutex.RUnlock() - fake.removeMutex.RLock() - defer fake.removeMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeClearFoldersOSFileManager) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ file.ClearFoldersOSFileManager = new(FakeClearFoldersOSFileManager) diff --git a/internal/mode/static/nginx/file/filefakes/fake_dir_entry.go b/internal/mode/static/nginx/file/filefakes/fake_dir_entry.go deleted file mode 100644 index b51ecd7579..0000000000 --- a/internal/mode/static/nginx/file/filefakes/fake_dir_entry.go +++ /dev/null @@ -1,301 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package filefakes - -import ( - "io/fs" - "sync" -) - -type FakeDirEntry struct { - InfoStub func() (fs.FileInfo, error) - infoMutex sync.RWMutex - infoArgsForCall []struct { - } - infoReturns struct { - result1 fs.FileInfo - result2 error - } - infoReturnsOnCall map[int]struct { - result1 fs.FileInfo - result2 error - } - IsDirStub func() bool - isDirMutex sync.RWMutex - isDirArgsForCall []struct { - } - isDirReturns struct { - result1 bool - } - isDirReturnsOnCall map[int]struct { - result1 bool - } - NameStub func() string - nameMutex sync.RWMutex - nameArgsForCall []struct { - } - nameReturns struct { - result1 string - } - nameReturnsOnCall map[int]struct { - result1 string - } - TypeStub func() fs.FileMode - typeMutex sync.RWMutex - typeArgsForCall []struct { - } - typeReturns struct { - result1 fs.FileMode - } - typeReturnsOnCall map[int]struct { - result1 fs.FileMode - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeDirEntry) Info() (fs.FileInfo, error) { - fake.infoMutex.Lock() - ret, specificReturn := fake.infoReturnsOnCall[len(fake.infoArgsForCall)] - fake.infoArgsForCall = append(fake.infoArgsForCall, struct { - }{}) - stub := fake.InfoStub - fakeReturns := fake.infoReturns - fake.recordInvocation("Info", []interface{}{}) - fake.infoMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeDirEntry) InfoCallCount() int { - fake.infoMutex.RLock() - defer fake.infoMutex.RUnlock() - return len(fake.infoArgsForCall) -} - -func (fake *FakeDirEntry) InfoCalls(stub func() (fs.FileInfo, error)) { - fake.infoMutex.Lock() - defer fake.infoMutex.Unlock() - fake.InfoStub = stub -} - -func (fake *FakeDirEntry) InfoReturns(result1 fs.FileInfo, result2 error) { - fake.infoMutex.Lock() - defer fake.infoMutex.Unlock() - fake.InfoStub = nil - fake.infoReturns = struct { - result1 fs.FileInfo - result2 error - }{result1, result2} -} - -func (fake *FakeDirEntry) InfoReturnsOnCall(i int, result1 fs.FileInfo, result2 error) { - fake.infoMutex.Lock() - defer fake.infoMutex.Unlock() - fake.InfoStub = nil - if fake.infoReturnsOnCall == nil { - fake.infoReturnsOnCall = make(map[int]struct { - result1 fs.FileInfo - result2 error - }) - } - fake.infoReturnsOnCall[i] = struct { - result1 fs.FileInfo - result2 error - }{result1, result2} -} - -func (fake *FakeDirEntry) IsDir() bool { - fake.isDirMutex.Lock() - ret, specificReturn := fake.isDirReturnsOnCall[len(fake.isDirArgsForCall)] - fake.isDirArgsForCall = append(fake.isDirArgsForCall, struct { - }{}) - stub := fake.IsDirStub - fakeReturns := fake.isDirReturns - fake.recordInvocation("IsDir", []interface{}{}) - fake.isDirMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeDirEntry) IsDirCallCount() int { - fake.isDirMutex.RLock() - defer fake.isDirMutex.RUnlock() - return len(fake.isDirArgsForCall) -} - -func (fake *FakeDirEntry) IsDirCalls(stub func() bool) { - fake.isDirMutex.Lock() - defer fake.isDirMutex.Unlock() - fake.IsDirStub = stub -} - -func (fake *FakeDirEntry) IsDirReturns(result1 bool) { - fake.isDirMutex.Lock() - defer fake.isDirMutex.Unlock() - fake.IsDirStub = nil - fake.isDirReturns = struct { - result1 bool - }{result1} -} - -func (fake *FakeDirEntry) IsDirReturnsOnCall(i int, result1 bool) { - fake.isDirMutex.Lock() - defer fake.isDirMutex.Unlock() - fake.IsDirStub = nil - if fake.isDirReturnsOnCall == nil { - fake.isDirReturnsOnCall = make(map[int]struct { - result1 bool - }) - } - fake.isDirReturnsOnCall[i] = struct { - result1 bool - }{result1} -} - -func (fake *FakeDirEntry) Name() string { - fake.nameMutex.Lock() - ret, specificReturn := fake.nameReturnsOnCall[len(fake.nameArgsForCall)] - fake.nameArgsForCall = append(fake.nameArgsForCall, struct { - }{}) - stub := fake.NameStub - fakeReturns := fake.nameReturns - fake.recordInvocation("Name", []interface{}{}) - fake.nameMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeDirEntry) NameCallCount() int { - fake.nameMutex.RLock() - defer fake.nameMutex.RUnlock() - return len(fake.nameArgsForCall) -} - -func (fake *FakeDirEntry) NameCalls(stub func() string) { - fake.nameMutex.Lock() - defer fake.nameMutex.Unlock() - fake.NameStub = stub -} - -func (fake *FakeDirEntry) NameReturns(result1 string) { - fake.nameMutex.Lock() - defer fake.nameMutex.Unlock() - fake.NameStub = nil - fake.nameReturns = struct { - result1 string - }{result1} -} - -func (fake *FakeDirEntry) NameReturnsOnCall(i int, result1 string) { - fake.nameMutex.Lock() - defer fake.nameMutex.Unlock() - fake.NameStub = nil - if fake.nameReturnsOnCall == nil { - fake.nameReturnsOnCall = make(map[int]struct { - result1 string - }) - } - fake.nameReturnsOnCall[i] = struct { - result1 string - }{result1} -} - -func (fake *FakeDirEntry) Type() fs.FileMode { - fake.typeMutex.Lock() - ret, specificReturn := fake.typeReturnsOnCall[len(fake.typeArgsForCall)] - fake.typeArgsForCall = append(fake.typeArgsForCall, struct { - }{}) - stub := fake.TypeStub - fakeReturns := fake.typeReturns - fake.recordInvocation("Type", []interface{}{}) - fake.typeMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeDirEntry) TypeCallCount() int { - fake.typeMutex.RLock() - defer fake.typeMutex.RUnlock() - return len(fake.typeArgsForCall) -} - -func (fake *FakeDirEntry) TypeCalls(stub func() fs.FileMode) { - fake.typeMutex.Lock() - defer fake.typeMutex.Unlock() - fake.TypeStub = stub -} - -func (fake *FakeDirEntry) TypeReturns(result1 fs.FileMode) { - fake.typeMutex.Lock() - defer fake.typeMutex.Unlock() - fake.TypeStub = nil - fake.typeReturns = struct { - result1 fs.FileMode - }{result1} -} - -func (fake *FakeDirEntry) TypeReturnsOnCall(i int, result1 fs.FileMode) { - fake.typeMutex.Lock() - defer fake.typeMutex.Unlock() - fake.TypeStub = nil - if fake.typeReturnsOnCall == nil { - fake.typeReturnsOnCall = make(map[int]struct { - result1 fs.FileMode - }) - } - fake.typeReturnsOnCall[i] = struct { - result1 fs.FileMode - }{result1} -} - -func (fake *FakeDirEntry) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.infoMutex.RLock() - defer fake.infoMutex.RUnlock() - fake.isDirMutex.RLock() - defer fake.isDirMutex.RUnlock() - fake.nameMutex.RLock() - defer fake.nameMutex.RUnlock() - fake.typeMutex.RLock() - defer fake.typeMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeDirEntry) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ fs.DirEntry = new(FakeDirEntry) diff --git a/internal/mode/static/nginx/file/filefakes/fake_manager.go b/internal/mode/static/nginx/file/filefakes/fake_manager.go deleted file mode 100644 index 557202ae1d..0000000000 --- a/internal/mode/static/nginx/file/filefakes/fake_manager.go +++ /dev/null @@ -1,116 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package filefakes - -import ( - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" -) - -type FakeManager struct { - ReplaceFilesStub func([]file.File) error - replaceFilesMutex sync.RWMutex - replaceFilesArgsForCall []struct { - arg1 []file.File - } - replaceFilesReturns struct { - result1 error - } - replaceFilesReturnsOnCall map[int]struct { - result1 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeManager) ReplaceFiles(arg1 []file.File) error { - var arg1Copy []file.File - if arg1 != nil { - arg1Copy = make([]file.File, len(arg1)) - copy(arg1Copy, arg1) - } - fake.replaceFilesMutex.Lock() - ret, specificReturn := fake.replaceFilesReturnsOnCall[len(fake.replaceFilesArgsForCall)] - fake.replaceFilesArgsForCall = append(fake.replaceFilesArgsForCall, struct { - arg1 []file.File - }{arg1Copy}) - stub := fake.ReplaceFilesStub - fakeReturns := fake.replaceFilesReturns - fake.recordInvocation("ReplaceFiles", []interface{}{arg1Copy}) - fake.replaceFilesMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeManager) ReplaceFilesCallCount() int { - fake.replaceFilesMutex.RLock() - defer fake.replaceFilesMutex.RUnlock() - return len(fake.replaceFilesArgsForCall) -} - -func (fake *FakeManager) ReplaceFilesCalls(stub func([]file.File) error) { - fake.replaceFilesMutex.Lock() - defer fake.replaceFilesMutex.Unlock() - fake.ReplaceFilesStub = stub -} - -func (fake *FakeManager) ReplaceFilesArgsForCall(i int) []file.File { - fake.replaceFilesMutex.RLock() - defer fake.replaceFilesMutex.RUnlock() - argsForCall := fake.replaceFilesArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeManager) ReplaceFilesReturns(result1 error) { - fake.replaceFilesMutex.Lock() - defer fake.replaceFilesMutex.Unlock() - fake.ReplaceFilesStub = nil - fake.replaceFilesReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) ReplaceFilesReturnsOnCall(i int, result1 error) { - fake.replaceFilesMutex.Lock() - defer fake.replaceFilesMutex.Unlock() - fake.ReplaceFilesStub = nil - if fake.replaceFilesReturnsOnCall == nil { - fake.replaceFilesReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.replaceFilesReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.replaceFilesMutex.RLock() - defer fake.replaceFilesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeManager) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ file.Manager = new(FakeManager) diff --git a/internal/mode/static/nginx/file/folders.go b/internal/mode/static/nginx/file/folders.go deleted file mode 100644 index 847ca6312a..0000000000 --- a/internal/mode/static/nginx/file/folders.go +++ /dev/null @@ -1,56 +0,0 @@ -package file - -import ( - "fmt" - "os" - "path/filepath" - "slices" -) - -//counterfeiter:generate io/fs.DirEntry - -//counterfeiter:generate . ClearFoldersOSFileManager - -// ClearFoldersOSFileManager is an interface that exposes File I/O operations for ClearFolders. -// Used for unit testing. -type ClearFoldersOSFileManager interface { - // ReadDir returns the directory entries for the directory. - ReadDir(dirname string) ([]os.DirEntry, error) - // Remove removes the file with given name. - Remove(name string) error -} - -// These files are needed on startup, so skip deleting them. -const ( - mainConf = "/etc/nginx/main-includes/main.conf" - mgmtConf = "/etc/nginx/main-includes/mgmt.conf" - deployCtx = "/etc/nginx/main-includes/deployment_ctx.json" -) - -var ignoreFilePaths = []string{mainConf, mgmtConf, deployCtx} - -// ClearFolders removes all files in the given folders and returns the removed files' full paths. -func ClearFolders(fileMgr ClearFoldersOSFileManager, paths []string) (removedFiles []string, e error) { - for _, path := range paths { - entries, err := fileMgr.ReadDir(path) - if err != nil { - return removedFiles, fmt.Errorf("failed to read directory %q: %w", path, err) - } - - for _, entry := range entries { - entryPath := filepath.Join(path, entry.Name()) - - if slices.Contains(ignoreFilePaths, entryPath) { - continue - } - - if err := fileMgr.Remove(entryPath); err != nil { - return removedFiles, fmt.Errorf("failed to remove %q: %w", entryPath, err) - } - - removedFiles = append(removedFiles, entryPath) - } - } - - return removedFiles, nil -} diff --git a/internal/mode/static/nginx/file/folders_test.go b/internal/mode/static/nginx/file/folders_test.go deleted file mode 100644 index beefd76dd1..0000000000 --- a/internal/mode/static/nginx/file/folders_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package file_test - -import ( - "errors" - "os" - "path/filepath" - "testing" - - . "github.com/onsi/gomega" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes" -) - -func writeFile(t *testing.T, name string, data []byte) { - t.Helper() - g := NewWithT(t) - - //nolint:gosec // the file permission is ok for unit testing - g.Expect(os.WriteFile(name, data, 0o644)).To(Succeed()) -} - -func TestClearFoldersRemoves(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - tempDir := t.TempDir() - - path1 := filepath.Join(tempDir, "path1") - writeFile(t, path1, []byte("test")) - path2 := filepath.Join(tempDir, "path2") - writeFile(t, path2, []byte("test")) - - removedFiles, err := file.ClearFolders(file.NewStdLibOSFileManager(), []string{tempDir}) - - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(removedFiles).To(ConsistOf(path1, path2)) - - entries, err := os.ReadDir(tempDir) - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(entries).To(BeEmpty()) -} - -func TestClearFoldersIgnoresPaths(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - fakeFileMgr := &filefakes.FakeClearFoldersOSFileManager{ - ReadDirStub: func(_ string) ([]os.DirEntry, error) { - return []os.DirEntry{ - &filefakes.FakeDirEntry{ - NameStub: func() string { - return "deployment_ctx.json" - }, - }, - &filefakes.FakeDirEntry{ - NameStub: func() string { - return "mgmt.conf" - }, - }, - &filefakes.FakeDirEntry{ - NameStub: func() string { - return "main.conf" - }, - }, - &filefakes.FakeDirEntry{ - NameStub: func() string { - return "can-be-removed.conf" - }, - }, - }, nil - }, - } - - removed, err := file.ClearFolders(fakeFileMgr, []string{"/etc/nginx/main-includes"}) - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(removed).To(HaveLen(1)) - g.Expect(removed[0]).To(Equal("/etc/nginx/main-includes/can-be-removed.conf")) -} - -func TestClearFoldersFails(t *testing.T) { - t.Parallel() - files := []string{"file"} - - testErr := errors.New("test error") - - tests := []struct { - fileMgr *filefakes.FakeClearFoldersOSFileManager - name string - }{ - { - fileMgr: &filefakes.FakeClearFoldersOSFileManager{ - ReadDirStub: func(_ string) ([]os.DirEntry, error) { - return nil, testErr - }, - }, - name: "ReadDir fails", - }, - { - fileMgr: &filefakes.FakeClearFoldersOSFileManager{ - ReadDirStub: func(_ string) ([]os.DirEntry, error) { - return []os.DirEntry{ - &filefakes.FakeDirEntry{ - NameStub: func() string { - return "file" - }, - }, - }, nil - }, - RemoveStub: func(_ string) error { - return testErr - }, - }, - name: "Remove fails", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - removedFiles, err := file.ClearFolders(test.fileMgr, files) - - g.Expect(err).To(MatchError(testErr)) - g.Expect(removedFiles).To(BeNil()) - }) - } -} diff --git a/internal/mode/static/nginx/file/manager_test.go b/internal/mode/static/nginx/file/manager_test.go deleted file mode 100644 index 5a2d5d57bc..0000000000 --- a/internal/mode/static/nginx/file/manager_test.go +++ /dev/null @@ -1,225 +0,0 @@ -package file_test - -import ( - "errors" - "os" - "path/filepath" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes" -) - -var _ = Describe("EventHandler", func() { - Describe("Replace files", Ordered, func() { - var ( - mgr *file.ManagerImpl - tmpDir string - regular1, regular2, regular3, secret file.File - ) - - ensureFiles := func(files []file.File) { - entries, err := os.ReadDir(tmpDir) - Expect(err).ToNot(HaveOccurred()) - Expect(entries).Should(HaveLen(len(files))) - - entriesMap := make(map[string]os.DirEntry) - for _, entry := range entries { - entriesMap[entry.Name()] = entry - } - - for _, f := range files { - _, ok := entriesMap[filepath.Base(f.Path)] - Expect(ok).Should(BeTrue()) - - info, err := os.Stat(f.Path) - Expect(err).ToNot(HaveOccurred()) - - Expect(info.IsDir()).To(BeFalse()) - - if f.Type == file.TypeRegular { - Expect(info.Mode()).To(Equal(os.FileMode(0o644))) - } else { - Expect(info.Mode()).To(Equal(os.FileMode(0o640))) - } - - bytes, err := os.ReadFile(f.Path) - Expect(err).ToNot(HaveOccurred()) - Expect(bytes).To(Equal(f.Content)) - } - } - - ensureNotExist := func(files ...file.File) { - for _, f := range files { - _, err := os.Stat(f.Path) - Expect(os.IsNotExist(err)).To(BeTrue()) - } - } - - BeforeAll(func() { - mgr = file.NewManagerImpl(zap.New(), file.NewStdLibOSFileManager()) - tmpDir = GinkgoT().TempDir() - - regular1 = file.File{ - Type: file.TypeRegular, - Path: filepath.Join(tmpDir, "regular-1.conf"), - Content: []byte("regular-1"), - } - regular2 = file.File{ - Type: file.TypeRegular, - Path: filepath.Join(tmpDir, "regular-2.conf"), - Content: []byte("regular-2"), - } - regular3 = file.File{ - Type: file.TypeRegular, - Path: filepath.Join(tmpDir, "regular-3.conf"), - Content: []byte("regular-3"), - } - secret = file.File{ - Type: file.TypeSecret, - Path: filepath.Join(tmpDir, "secret.conf"), - Content: []byte("secret"), - } - }) - - It("should write initial config", func() { - files := []file.File{regular1, regular2, secret} - - err := mgr.ReplaceFiles(files) - Expect(err).ToNot(HaveOccurred()) - - ensureFiles(files) - }) - - It("should write subsequent config", func() { - files := []file.File{ - regular2, // overwriting - regular3, // adding - secret, // overwriting - } - - err := mgr.ReplaceFiles(files) - Expect(err).ToNot(HaveOccurred()) - - ensureFiles(files) - ensureNotExist(regular1) - }) - - It("should remove all files", func() { - err := mgr.ReplaceFiles(nil) - Expect(err).ToNot(HaveOccurred()) - - ensureNotExist(regular2, regular3, secret) - }) - }) - - When("file does not exist", func() { - It("should not error", func() { - fakeOSMgr := &filefakes.FakeOSFileManager{} - mgr := file.NewManagerImpl(zap.New(), fakeOSMgr) - - files := []file.File{ - { - Type: file.TypeRegular, - Path: "regular-1.conf", - Content: []byte("regular-1"), - }, - } - - Expect(mgr.ReplaceFiles(files)).ToNot(HaveOccurred()) - - fakeOSMgr.RemoveReturns(os.ErrNotExist) - Expect(mgr.ReplaceFiles(files)).ToNot(HaveOccurred()) - }) - }) - - When("file type is not supported", func() { - It("should panic", func() { - mgr := file.NewManagerImpl(zap.New(), nil) - - files := []file.File{ - { - Type: 123, - Path: "unsupported.conf", - }, - } - - replace := func() { - _ = mgr.ReplaceFiles(files) - } - - Expect(replace).Should(Panic()) - }) - }) - - Describe("Edge cases with IO errors", func() { - var ( - files = []file.File{ - { - Type: file.TypeRegular, - Path: "regular.conf", - Content: []byte("regular"), - }, - { - Type: file.TypeSecret, - Path: "secret.conf", - Content: []byte("secret"), - }, - } - errTest = errors.New("test error") - ) - - DescribeTable( - "should return error on file IO error", - func(fakeOSMgr *filefakes.FakeOSFileManager) { - mgr := file.NewManagerImpl(zap.New(), fakeOSMgr) - - // special case for Remove - // to kick off removing, we need to successfully write files beforehand - if fakeOSMgr.RemoveStub != nil { - err := mgr.ReplaceFiles(files) - Expect(err).ToNot(HaveOccurred()) - } - - err := mgr.ReplaceFiles(files) - Expect(err).Should(HaveOccurred()) - Expect(err).To(MatchError(errTest)) - }, - Entry( - "Remove", - &filefakes.FakeOSFileManager{ - RemoveStub: func(_ string) error { - return errTest - }, - }, - ), - Entry( - "Create", - &filefakes.FakeOSFileManager{ - CreateStub: func(_ string) (*os.File, error) { - return nil, errTest - }, - }, - ), - Entry( - "Chmod", - &filefakes.FakeOSFileManager{ - ChmodStub: func(_ *os.File, _ os.FileMode) error { - return errTest - }, - }, - ), - Entry( - "Write", - &filefakes.FakeOSFileManager{ - WriteStub: func(_ *os.File, _ []byte) error { - return errTest - }, - }, - ), - ) - }) -}) diff --git a/internal/mode/static/nginx/runtime/clients.go b/internal/mode/static/nginx/runtime/clients.go deleted file mode 100644 index a01a8ef09f..0000000000 --- a/internal/mode/static/nginx/runtime/clients.go +++ /dev/null @@ -1,39 +0,0 @@ -package runtime - -import ( - "context" - "fmt" - "net" - "net/http" - - "github.com/nginxinc/nginx-plus-go-client/client" -) - -const ( - nginxPlusAPISock = "/var/run/nginx/nginx-plus-api.sock" - nginxPlusAPIURI = "http://nginx-plus-api/api" -) - -// CreatePlusClient returns a client for communicating with the NGINX Plus API. -func CreatePlusClient() (*client.NginxClient, error) { - var plusClient *client.NginxClient - var err error - - httpClient := GetSocketClient(nginxPlusAPISock) - plusClient, err = client.NewNginxClient(nginxPlusAPIURI, client.WithHTTPClient(&httpClient)) - if err != nil { - return nil, fmt.Errorf("failed to create NginxClient for Plus: %w", err) - } - return plusClient, nil -} - -// GetSocketClient gets an http.Client with a unix socket transport. -func GetSocketClient(sockPath string) http.Client { - return http.Client{ - Transport: &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", sockPath) - }, - }, - } -} diff --git a/internal/mode/static/nginx/runtime/manager.go b/internal/mode/static/nginx/runtime/manager.go deleted file mode 100644 index afa641645f..0000000000 --- a/internal/mode/static/nginx/runtime/manager.go +++ /dev/null @@ -1,284 +0,0 @@ -package runtime - -import ( - "context" - "errors" - "fmt" - "io/fs" - "os" - "strconv" - "strings" - "syscall" - "time" - - "github.com/go-logr/logr" - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" - "k8s.io/apimachinery/pkg/util/wait" -) - -//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate - -const ( - // PidFile specifies the location of the PID file for the Nginx process. - PidFile = "/var/run/nginx/nginx.pid" - // PidFileTimeout defines the timeout duration for accessing the PID file. - PidFileTimeout = 10000 * time.Millisecond - // NginxReloadTimeout sets the timeout duration for reloading the Nginx configuration. - NginxReloadTimeout = 60000 * time.Millisecond -) - -type ( - ReadFileFunc func(string) ([]byte, error) - CheckFileFunc func(string) (fs.FileInfo, error) -) - -var childProcPathFmt = "/proc/%[1]v/task/%[1]v/children" - -//counterfeiter:generate . NginxPlusClient - -type NginxPlusClient interface { - UpdateHTTPServers( - upstream string, - servers []ngxclient.UpstreamServer, - ) ( - added []ngxclient.UpstreamServer, - deleted []ngxclient.UpstreamServer, - updated []ngxclient.UpstreamServer, - err error, - ) - GetUpstreams() (*ngxclient.Upstreams, error) - UpdateStreamServers( - upstream string, - servers []ngxclient.StreamUpstreamServer, - ) ( - added []ngxclient.StreamUpstreamServer, - deleted []ngxclient.StreamUpstreamServer, - updated []ngxclient.StreamUpstreamServer, - err error, - ) - GetStreamUpstreams() (*ngxclient.StreamUpstreams, error) -} - -//counterfeiter:generate . Manager - -// Manager manages the runtime of NGINX. -type Manager interface { - // Reload reloads NGINX configuration. It is a blocking operation. - Reload(ctx context.Context, configVersion int) error - // IsPlus returns whether or not we are running NGINX plus. - IsPlus() bool - // GetUpstreams uses the NGINX Plus API to get the upstreams. - // Only usable if running NGINX Plus. - GetUpstreams() (ngxclient.Upstreams, ngxclient.StreamUpstreams, error) - // UpdateHTTPServers uses the NGINX Plus API to update HTTP upstream servers. - // Only usable if running NGINX Plus. - UpdateHTTPServers(string, []ngxclient.UpstreamServer) error - // UpdateStreamServers uses the NGINX Plus API to update stream upstream servers. - // Only usable if running NGINX Plus. - UpdateStreamServers(string, []ngxclient.StreamUpstreamServer) error -} - -// MetricsCollector is an interface for the metrics of the NGINX runtime manager. -// -//counterfeiter:generate . MetricsCollector -type MetricsCollector interface { - IncReloadCount() - IncReloadErrors() - ObserveLastReloadTime(ms time.Duration) -} - -// ManagerImpl implements Manager. -type ManagerImpl struct { - processHandler ProcessHandler - metricsCollector MetricsCollector - verifyClient nginxConfigVerifier - ngxPlusClient NginxPlusClient - logger logr.Logger -} - -// NewManagerImpl creates a new ManagerImpl. -func NewManagerImpl( - ngxPlusClient NginxPlusClient, - collector MetricsCollector, - logger logr.Logger, - processHandler ProcessHandler, - verifyClient nginxConfigVerifier, -) *ManagerImpl { - return &ManagerImpl{ - processHandler: processHandler, - metricsCollector: collector, - verifyClient: verifyClient, - ngxPlusClient: ngxPlusClient, - logger: logger, - } -} - -// IsPlus returns whether or not we are running NGINX plus. -func (m *ManagerImpl) IsPlus() bool { - return m.ngxPlusClient != nil -} - -func (m *ManagerImpl) Reload(ctx context.Context, configVersion int) error { - start := time.Now() - // We find the main NGINX PID on every reload because it will change if the NGINX container is restarted. - pid, err := m.processHandler.FindMainProcess(ctx, PidFileTimeout) - if err != nil { - return fmt.Errorf("failed to find NGINX main process: %w", err) - } - - childProcFile := fmt.Sprintf(childProcPathFmt, pid) - previousChildProcesses, err := m.processHandler.ReadFile(childProcFile) - if err != nil { - return err - } - - // send HUP signal to the NGINX main process reload configuration - // See https://nginx.org/en/docs/control.html - if errP := m.processHandler.Kill(pid); errP != nil { - m.metricsCollector.IncReloadErrors() - return fmt.Errorf("failed to send the HUP signal to NGINX main: %w", errP) - } - - if err = m.verifyClient.WaitForCorrectVersion( - ctx, - configVersion, - childProcFile, - previousChildProcesses, - os.ReadFile, - ); err != nil { - m.metricsCollector.IncReloadErrors() - return err - } - m.metricsCollector.IncReloadCount() - - finish := time.Now() - m.metricsCollector.ObserveLastReloadTime(finish.Sub(start)) - return nil -} - -// GetUpstreams uses the NGINX Plus API to get the upstreams. -// Only usable if running NGINX Plus. -func (m *ManagerImpl) GetUpstreams() (ngxclient.Upstreams, ngxclient.StreamUpstreams, error) { - if !m.IsPlus() { - panic("cannot get upstream servers: NGINX Plus not enabled") - } - - upstreams, err := m.ngxPlusClient.GetUpstreams() - if err != nil { - return nil, nil, err - } - - if upstreams == nil { - return nil, nil, errors.New("GET upstreams returned nil value") - } - - streamUpstreams, err := m.ngxPlusClient.GetStreamUpstreams() - if err != nil { - return nil, nil, err - } - - if streamUpstreams == nil { - return nil, nil, errors.New("GET stream upstreams returned nil value") - } - - return *upstreams, *streamUpstreams, nil -} - -// UpdateHTTPServers uses the NGINX Plus API to update HTTP upstream servers. -// Only usable if running NGINX Plus. -func (m *ManagerImpl) UpdateHTTPServers(upstream string, servers []ngxclient.UpstreamServer) error { - if !m.IsPlus() { - panic("cannot update HTTP upstream servers: NGINX Plus not enabled") - } - - added, deleted, updated, err := m.ngxPlusClient.UpdateHTTPServers(upstream, servers) - m.logger.V(1).Info("Added upstream servers", "count", len(added)) - m.logger.V(1).Info("Deleted upstream servers", "count", len(deleted)) - m.logger.V(1).Info("Updated upstream servers", "count", len(updated)) - - return err -} - -// UpdateStreamServers uses the NGINX Plus API to update stream upstream servers. -// Only usable if running NGINX Plus. -func (m *ManagerImpl) UpdateStreamServers(upstream string, servers []ngxclient.StreamUpstreamServer) error { - if !m.IsPlus() { - panic("cannot update stream upstream servers: NGINX Plus not enabled") - } - - added, deleted, updated, err := m.ngxPlusClient.UpdateStreamServers(upstream, servers) - m.logger.V(1).Info("Added stream upstream servers", "count", len(added)) - m.logger.V(1).Info("Deleted stream upstream servers", "count", len(deleted)) - m.logger.V(1).Info("Updated stream upstream servers", "count", len(updated)) - - return err -} - -//counterfeiter:generate . ProcessHandler - -type ProcessHandler interface { - FindMainProcess( - ctx context.Context, - timeout time.Duration, - ) (int, error) - ReadFile(file string) ([]byte, error) - Kill(pid int) error -} - -type ProcessHandlerImpl struct { - readFile ReadFileFunc - checkFile CheckFileFunc -} - -func NewProcessHandlerImpl(readFile ReadFileFunc, checkFile CheckFileFunc) *ProcessHandlerImpl { - return &ProcessHandlerImpl{ - readFile: readFile, - checkFile: checkFile, - } -} - -func (p *ProcessHandlerImpl) FindMainProcess( - ctx context.Context, - timeout time.Duration, -) (int, error) { - ctx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - - err := wait.PollUntilContextCancel( - ctx, - 500*time.Millisecond, - true, /* poll immediately */ - func(_ context.Context) (bool, error) { - _, err := p.checkFile(PidFile) - if err == nil { - return true, nil - } - if !errors.Is(err, fs.ErrNotExist) { - return false, err - } - return false, nil - }) - if err != nil { - return 0, err - } - - content, err := p.readFile(PidFile) - if err != nil { - return 0, err - } - - pid, err := strconv.Atoi(strings.TrimSpace(string(content))) - if err != nil { - return 0, fmt.Errorf("invalid pid file content %q: %w", content, err) - } - - return pid, nil -} - -func (p *ProcessHandlerImpl) ReadFile(file string) ([]byte, error) { - return p.readFile(file) -} - -func (p *ProcessHandlerImpl) Kill(pid int) error { - return syscall.Kill(pid, syscall.SIGHUP) -} diff --git a/internal/mode/static/nginx/runtime/manager_test.go b/internal/mode/static/nginx/runtime/manager_test.go deleted file mode 100644 index 036731e1ea..0000000000 --- a/internal/mode/static/nginx/runtime/manager_test.go +++ /dev/null @@ -1,403 +0,0 @@ -package runtime_test - -import ( - "context" - "errors" - "fmt" - "io/fs" - "testing" - "time" - - ngxclient "github.com/nginxinc/nginx-plus-go-client/client" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime/runtimefakes" -) - -var _ = Describe("NGINX Runtime Manager", func() { - It("returns whether or not we're using NGINX Plus", func() { - mgr := runtime.NewManagerImpl(nil, nil, zap.New(), nil, nil) - Expect(mgr.IsPlus()).To(BeFalse()) - - mgr = runtime.NewManagerImpl(&ngxclient.NginxClient{}, nil, zap.New(), nil, nil) - Expect(mgr.IsPlus()).To(BeTrue()) - }) - - var ( - err error - manager runtime.Manager - upstreamServers []ngxclient.UpstreamServer - streamUpstreamServers []ngxclient.StreamUpstreamServer - ngxPlusClient *runtimefakes.FakeNginxPlusClient - process *runtimefakes.FakeProcessHandler - - metrics *runtimefakes.FakeMetricsCollector - verifyClient *runtimefakes.FakeVerifyClient - ) - - BeforeEach(func() { - upstreamServers = []ngxclient.UpstreamServer{ - {}, - } - streamUpstreamServers = []ngxclient.StreamUpstreamServer{ - {}, - } - }) - - Context("Reload", func() { - BeforeEach(func() { - ngxPlusClient = &runtimefakes.FakeNginxPlusClient{} - process = &runtimefakes.FakeProcessHandler{} - metrics = &runtimefakes.FakeMetricsCollector{} - verifyClient = &runtimefakes.FakeVerifyClient{} - manager = runtime.NewManagerImpl(ngxPlusClient, metrics, zap.New(), process, verifyClient) - }) - - It("Is successful", func() { - Expect(manager.Reload(context.Background(), 1)).To(Succeed()) - - Expect(process.FindMainProcessCallCount()).To(Equal(1)) - Expect(process.ReadFileCallCount()).To(Equal(1)) - Expect(process.KillCallCount()).To(Equal(1)) - Expect(metrics.IncReloadCountCallCount()).To(Equal(1)) - Expect(verifyClient.WaitForCorrectVersionCallCount()).To(Equal(1)) - Expect(metrics.ObserveLastReloadTimeCallCount()).To(Equal(1)) - Expect(metrics.IncReloadErrorsCallCount()).To(Equal(0)) - }) - - It("Fails to find the main process", func() { - process.FindMainProcessReturns(0, fmt.Errorf("failed to find process")) - - err := manager.Reload(context.Background(), 1) - - Expect(err).To(MatchError("failed to find NGINX main process: failed to find process")) - Expect(process.ReadFileCallCount()).To(Equal(0)) - Expect(process.KillCallCount()).To(Equal(0)) - Expect(verifyClient.WaitForCorrectVersionCallCount()).To(Equal(0)) - }) - - It("Fails to read file", func() { - process.FindMainProcessReturns(1234, nil) - process.ReadFileReturns(nil, fmt.Errorf("failed to read file")) - - err := manager.Reload(context.Background(), 1) - - Expect(err).To(MatchError("failed to read file")) - Expect(process.KillCallCount()).To(Equal(0)) - Expect(verifyClient.WaitForCorrectVersionCallCount()).To(Equal(0)) - }) - - It("Fails to send kill signal", func() { - process.FindMainProcessReturns(1234, nil) - process.ReadFileReturns([]byte("child1\nchild2"), nil) - process.KillReturns(fmt.Errorf("failed to send kill signal")) - - err := manager.Reload(context.Background(), 1) - - Expect(err).To(MatchError("failed to send the HUP signal to NGINX main: failed to send kill signal")) - Expect(metrics.IncReloadErrorsCallCount()).To(Equal(1)) - Expect(verifyClient.WaitForCorrectVersionCallCount()).To(Equal(0)) - }) - - It("times out waiting for correct version", func() { - process.FindMainProcessReturns(1234, nil) - process.ReadFileReturns([]byte("child1\nchild2"), nil) - process.KillReturns(nil) - verifyClient.WaitForCorrectVersionReturns(fmt.Errorf("timeout waiting for correct version")) - - err := manager.Reload(context.Background(), 1) - - Expect(err).To(MatchError("timeout waiting for correct version")) - Expect(metrics.IncReloadErrorsCallCount()).To(Equal(1)) - }) - - When("MetricsCollector is nil", func() { - It("panics", func() { - metrics = nil - manager = runtime.NewManagerImpl(ngxPlusClient, metrics, zap.New(), process, verifyClient) - - reload := func() { - err = manager.Reload(context.Background(), 0) - } - - Expect(reload).To(Panic()) - Expect(err).ToNot(HaveOccurred()) - }) - }) - - When("VerifyClient is nil", func() { - It("panics", func() { - metrics = &runtimefakes.FakeMetricsCollector{} - verifyClient = nil - manager = runtime.NewManagerImpl(ngxPlusClient, metrics, zap.New(), process, verifyClient) - - reload := func() { - err = manager.Reload(context.Background(), 0) - } - - Expect(reload).To(Panic()) - Expect(err).ToNot(HaveOccurred()) - }) - }) - }) - - When("running NGINX plus", func() { - BeforeEach(func() { - ngxPlusClient = &runtimefakes.FakeNginxPlusClient{} - manager = runtime.NewManagerImpl(ngxPlusClient, nil, zap.New(), nil, nil) - }) - - It("successfully updates HTTP server upstream", func() { - Expect(manager.UpdateHTTPServers("test", upstreamServers)).To(Succeed()) - }) - - It("successfully updates stream server upstream", func() { - Expect(manager.UpdateStreamServers("test", streamUpstreamServers)).To(Succeed()) - }) - - It("returns no upstreams from NGINX Plus API when upstreams are nil", func() { - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).To(HaveOccurred()) - Expect(upstreams).To(BeEmpty()) - Expect(streamUpstreams).To(BeEmpty()) - }) - - It("successfully returns server upstreams", func() { - expUpstreams := ngxclient.Upstreams{ - "upstream1": { - Zone: "zone1", - Peers: []ngxclient.Peer{ - {ID: 1, Name: "peer1-name"}, - }, - Queue: ngxclient.Queue{Size: 10}, - Zombies: 2, - }, - "upstream2": { - Zone: "zone2", - Peers: []ngxclient.Peer{ - {ID: 2, Name: "peer2-name"}, - }, - Queue: ngxclient.Queue{Size: 20}, - Zombies: 1, - }, - } - - expStreamUpstreams := ngxclient.StreamUpstreams{ - "upstream1": { - Zone: "zone1", - Peers: []ngxclient.StreamPeer{ - {ID: 1, Name: "peer1-name"}, - }, - Zombies: 2, - }, - "upstream2": { - Zone: "zone2", - Peers: []ngxclient.StreamPeer{ - {ID: 2, Name: "peer2-name"}, - }, - Zombies: 1, - }, - } - - ngxPlusClient.GetUpstreamsReturns(&expUpstreams, nil) - ngxPlusClient.GetStreamUpstreamsReturns(&expStreamUpstreams, nil) - - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).NotTo(HaveOccurred()) - Expect(expUpstreams).To(Equal(upstreams)) - Expect(expStreamUpstreams).To(Equal(streamUpstreams)) - }) - - It("returns an error when GetUpstreams fails", func() { - ngxPlusClient.GetUpstreamsReturns(nil, errors.New("failed to get upstreams")) - - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError("failed to get upstreams")) - Expect(upstreams).To(BeNil()) - Expect(streamUpstreams).To(BeNil()) - }) - - It("returns an error when GetUpstreams returns nil", func() { - ngxPlusClient.GetUpstreamsReturns(nil, nil) - - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError("GET upstreams returned nil value")) - Expect(upstreams).To(BeNil()) - Expect(streamUpstreams).To(BeNil()) - }) - - It("returns an error when GetStreamUpstreams fails", func() { - ngxPlusClient.GetUpstreamsReturns(&ngxclient.Upstreams{}, nil) - ngxPlusClient.GetStreamUpstreamsReturns(nil, errors.New("failed to get upstreams")) - - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError("failed to get upstreams")) - Expect(upstreams).To(BeNil()) - Expect(streamUpstreams).To(BeNil()) - }) - - It("returns an error when GetStreamUpstreams returns nil", func() { - ngxPlusClient.GetUpstreamsReturns(&ngxclient.Upstreams{}, nil) - ngxPlusClient.GetStreamUpstreamsReturns(nil, nil) - - upstreams, streamUpstreams, err := manager.GetUpstreams() - - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError("GET stream upstreams returned nil value")) - Expect(upstreams).To(BeNil()) - Expect(streamUpstreams).To(BeNil()) - }) - }) - - When("not running NGINX plus", func() { - BeforeEach(func() { - ngxPlusClient = nil - manager = runtime.NewManagerImpl(ngxPlusClient, nil, zap.New(), nil, nil) - }) - - It("should panic when fetching upstream servers", func() { - upstreams := func() { - _, _, err = manager.GetUpstreams() - } - - Expect(upstreams).To(Panic()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should panic when updating HTTP upstream servers", func() { - updateServers := func() { - err = manager.UpdateHTTPServers("test", upstreamServers) - } - - Expect(updateServers).To(Panic()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should panic when updating stream upstream servers", func() { - updateServers := func() { - err = manager.UpdateStreamServers("test", streamUpstreamServers) - } - - Expect(updateServers).To(Panic()) - Expect(err).ToNot(HaveOccurred()) - }) - }) -}) - -func TestFindMainProcess(t *testing.T) { - t.Parallel() - readFileFuncGen := func(content []byte) runtime.ReadFileFunc { - return func(name string) ([]byte, error) { - if name != runtime.PidFile { - return nil, errors.New("error") - } - return content, nil - } - } - readFileError := func(string) ([]byte, error) { - return nil, errors.New("error") - } - - checkFileFuncGen := func(content fs.FileInfo) runtime.CheckFileFunc { - return func(name string) (fs.FileInfo, error) { - if name != runtime.PidFile { - return nil, errors.New("error") - } - return content, nil - } - } - checkFileError := func(string) (fs.FileInfo, error) { - return nil, errors.New("error") - } - var testFileInfo fs.FileInfo - ctx := context.Background() - cancellingCtx, cancel := context.WithCancel(ctx) - time.AfterFunc(1*time.Millisecond, cancel) - - tests := []struct { - ctx context.Context - readFile runtime.ReadFileFunc - checkFile runtime.CheckFileFunc - name string - expected int - expectError bool - }{ - { - ctx: ctx, - readFile: readFileFuncGen([]byte("1\n")), - checkFile: checkFileFuncGen(testFileInfo), - expected: 1, - expectError: false, - name: "normal case", - }, - { - ctx: ctx, - readFile: readFileFuncGen([]byte("")), - checkFile: checkFileFuncGen(testFileInfo), - expected: 0, - expectError: true, - name: "empty file content", - }, - { - ctx: ctx, - readFile: readFileFuncGen([]byte("not a number")), - checkFile: checkFileFuncGen(testFileInfo), - expected: 0, - expectError: true, - name: "bad file content", - }, - { - ctx: ctx, - readFile: readFileError, - checkFile: checkFileFuncGen(testFileInfo), - expected: 0, - expectError: true, - name: "cannot read file", - }, - { - ctx: ctx, - readFile: readFileFuncGen([]byte("1\n")), - checkFile: checkFileError, - expected: 0, - expectError: true, - name: "cannot find pid file", - }, - { - ctx: cancellingCtx, - readFile: readFileFuncGen([]byte("1\n")), - checkFile: checkFileError, - expected: 0, - expectError: true, - name: "context canceled", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - t.Parallel() - g := NewWithT(t) - p := runtime.NewProcessHandlerImpl( - test.readFile, - test.checkFile) - result, err := p.FindMainProcess(test.ctx, 2*time.Millisecond) - - if test.expectError { - g.Expect(err).To(HaveOccurred()) - } else { - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(result).To(Equal(test.expected)) - } - }) - } -} diff --git a/internal/mode/static/nginx/runtime/runtime_suite_test.go b/internal/mode/static/nginx/runtime/runtime_suite_test.go deleted file mode 100644 index 8916c4bf14..0000000000 --- a/internal/mode/static/nginx/runtime/runtime_suite_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package runtime_test - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -func TestRuntime(t *testing.T) { - t.Parallel() - RegisterFailHandler(Fail) - RunSpecs(t, "Runtime Suite") -} diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_manager.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_manager.go deleted file mode 100644 index ea7504a762..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_manager.go +++ /dev/null @@ -1,417 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "context" - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" - "github.com/nginxinc/nginx-plus-go-client/client" -) - -type FakeManager struct { - GetUpstreamsStub func() (client.Upstreams, client.StreamUpstreams, error) - getUpstreamsMutex sync.RWMutex - getUpstreamsArgsForCall []struct { - } - getUpstreamsReturns struct { - result1 client.Upstreams - result2 client.StreamUpstreams - result3 error - } - getUpstreamsReturnsOnCall map[int]struct { - result1 client.Upstreams - result2 client.StreamUpstreams - result3 error - } - IsPlusStub func() bool - isPlusMutex sync.RWMutex - isPlusArgsForCall []struct { - } - isPlusReturns struct { - result1 bool - } - isPlusReturnsOnCall map[int]struct { - result1 bool - } - ReloadStub func(context.Context, int) error - reloadMutex sync.RWMutex - reloadArgsForCall []struct { - arg1 context.Context - arg2 int - } - reloadReturns struct { - result1 error - } - reloadReturnsOnCall map[int]struct { - result1 error - } - UpdateHTTPServersStub func(string, []client.UpstreamServer) error - updateHTTPServersMutex sync.RWMutex - updateHTTPServersArgsForCall []struct { - arg1 string - arg2 []client.UpstreamServer - } - updateHTTPServersReturns struct { - result1 error - } - updateHTTPServersReturnsOnCall map[int]struct { - result1 error - } - UpdateStreamServersStub func(string, []client.StreamUpstreamServer) error - updateStreamServersMutex sync.RWMutex - updateStreamServersArgsForCall []struct { - arg1 string - arg2 []client.StreamUpstreamServer - } - updateStreamServersReturns struct { - result1 error - } - updateStreamServersReturnsOnCall map[int]struct { - result1 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeManager) GetUpstreams() (client.Upstreams, client.StreamUpstreams, error) { - fake.getUpstreamsMutex.Lock() - ret, specificReturn := fake.getUpstreamsReturnsOnCall[len(fake.getUpstreamsArgsForCall)] - fake.getUpstreamsArgsForCall = append(fake.getUpstreamsArgsForCall, struct { - }{}) - stub := fake.GetUpstreamsStub - fakeReturns := fake.getUpstreamsReturns - fake.recordInvocation("GetUpstreams", []interface{}{}) - fake.getUpstreamsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeManager) GetUpstreamsCallCount() int { - fake.getUpstreamsMutex.RLock() - defer fake.getUpstreamsMutex.RUnlock() - return len(fake.getUpstreamsArgsForCall) -} - -func (fake *FakeManager) GetUpstreamsCalls(stub func() (client.Upstreams, client.StreamUpstreams, error)) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = stub -} - -func (fake *FakeManager) GetUpstreamsReturns(result1 client.Upstreams, result2 client.StreamUpstreams, result3 error) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = nil - fake.getUpstreamsReturns = struct { - result1 client.Upstreams - result2 client.StreamUpstreams - result3 error - }{result1, result2, result3} -} - -func (fake *FakeManager) GetUpstreamsReturnsOnCall(i int, result1 client.Upstreams, result2 client.StreamUpstreams, result3 error) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = nil - if fake.getUpstreamsReturnsOnCall == nil { - fake.getUpstreamsReturnsOnCall = make(map[int]struct { - result1 client.Upstreams - result2 client.StreamUpstreams - result3 error - }) - } - fake.getUpstreamsReturnsOnCall[i] = struct { - result1 client.Upstreams - result2 client.StreamUpstreams - result3 error - }{result1, result2, result3} -} - -func (fake *FakeManager) IsPlus() bool { - fake.isPlusMutex.Lock() - ret, specificReturn := fake.isPlusReturnsOnCall[len(fake.isPlusArgsForCall)] - fake.isPlusArgsForCall = append(fake.isPlusArgsForCall, struct { - }{}) - stub := fake.IsPlusStub - fakeReturns := fake.isPlusReturns - fake.recordInvocation("IsPlus", []interface{}{}) - fake.isPlusMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeManager) IsPlusCallCount() int { - fake.isPlusMutex.RLock() - defer fake.isPlusMutex.RUnlock() - return len(fake.isPlusArgsForCall) -} - -func (fake *FakeManager) IsPlusCalls(stub func() bool) { - fake.isPlusMutex.Lock() - defer fake.isPlusMutex.Unlock() - fake.IsPlusStub = stub -} - -func (fake *FakeManager) IsPlusReturns(result1 bool) { - fake.isPlusMutex.Lock() - defer fake.isPlusMutex.Unlock() - fake.IsPlusStub = nil - fake.isPlusReturns = struct { - result1 bool - }{result1} -} - -func (fake *FakeManager) IsPlusReturnsOnCall(i int, result1 bool) { - fake.isPlusMutex.Lock() - defer fake.isPlusMutex.Unlock() - fake.IsPlusStub = nil - if fake.isPlusReturnsOnCall == nil { - fake.isPlusReturnsOnCall = make(map[int]struct { - result1 bool - }) - } - fake.isPlusReturnsOnCall[i] = struct { - result1 bool - }{result1} -} - -func (fake *FakeManager) Reload(arg1 context.Context, arg2 int) error { - fake.reloadMutex.Lock() - ret, specificReturn := fake.reloadReturnsOnCall[len(fake.reloadArgsForCall)] - fake.reloadArgsForCall = append(fake.reloadArgsForCall, struct { - arg1 context.Context - arg2 int - }{arg1, arg2}) - stub := fake.ReloadStub - fakeReturns := fake.reloadReturns - fake.recordInvocation("Reload", []interface{}{arg1, arg2}) - fake.reloadMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeManager) ReloadCallCount() int { - fake.reloadMutex.RLock() - defer fake.reloadMutex.RUnlock() - return len(fake.reloadArgsForCall) -} - -func (fake *FakeManager) ReloadCalls(stub func(context.Context, int) error) { - fake.reloadMutex.Lock() - defer fake.reloadMutex.Unlock() - fake.ReloadStub = stub -} - -func (fake *FakeManager) ReloadArgsForCall(i int) (context.Context, int) { - fake.reloadMutex.RLock() - defer fake.reloadMutex.RUnlock() - argsForCall := fake.reloadArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeManager) ReloadReturns(result1 error) { - fake.reloadMutex.Lock() - defer fake.reloadMutex.Unlock() - fake.ReloadStub = nil - fake.reloadReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) ReloadReturnsOnCall(i int, result1 error) { - fake.reloadMutex.Lock() - defer fake.reloadMutex.Unlock() - fake.ReloadStub = nil - if fake.reloadReturnsOnCall == nil { - fake.reloadReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.reloadReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) UpdateHTTPServers(arg1 string, arg2 []client.UpstreamServer) error { - var arg2Copy []client.UpstreamServer - if arg2 != nil { - arg2Copy = make([]client.UpstreamServer, len(arg2)) - copy(arg2Copy, arg2) - } - fake.updateHTTPServersMutex.Lock() - ret, specificReturn := fake.updateHTTPServersReturnsOnCall[len(fake.updateHTTPServersArgsForCall)] - fake.updateHTTPServersArgsForCall = append(fake.updateHTTPServersArgsForCall, struct { - arg1 string - arg2 []client.UpstreamServer - }{arg1, arg2Copy}) - stub := fake.UpdateHTTPServersStub - fakeReturns := fake.updateHTTPServersReturns - fake.recordInvocation("UpdateHTTPServers", []interface{}{arg1, arg2Copy}) - fake.updateHTTPServersMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeManager) UpdateHTTPServersCallCount() int { - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - return len(fake.updateHTTPServersArgsForCall) -} - -func (fake *FakeManager) UpdateHTTPServersCalls(stub func(string, []client.UpstreamServer) error) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = stub -} - -func (fake *FakeManager) UpdateHTTPServersArgsForCall(i int) (string, []client.UpstreamServer) { - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - argsForCall := fake.updateHTTPServersArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeManager) UpdateHTTPServersReturns(result1 error) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = nil - fake.updateHTTPServersReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) UpdateHTTPServersReturnsOnCall(i int, result1 error) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = nil - if fake.updateHTTPServersReturnsOnCall == nil { - fake.updateHTTPServersReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.updateHTTPServersReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) UpdateStreamServers(arg1 string, arg2 []client.StreamUpstreamServer) error { - var arg2Copy []client.StreamUpstreamServer - if arg2 != nil { - arg2Copy = make([]client.StreamUpstreamServer, len(arg2)) - copy(arg2Copy, arg2) - } - fake.updateStreamServersMutex.Lock() - ret, specificReturn := fake.updateStreamServersReturnsOnCall[len(fake.updateStreamServersArgsForCall)] - fake.updateStreamServersArgsForCall = append(fake.updateStreamServersArgsForCall, struct { - arg1 string - arg2 []client.StreamUpstreamServer - }{arg1, arg2Copy}) - stub := fake.UpdateStreamServersStub - fakeReturns := fake.updateStreamServersReturns - fake.recordInvocation("UpdateStreamServers", []interface{}{arg1, arg2Copy}) - fake.updateStreamServersMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeManager) UpdateStreamServersCallCount() int { - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - return len(fake.updateStreamServersArgsForCall) -} - -func (fake *FakeManager) UpdateStreamServersCalls(stub func(string, []client.StreamUpstreamServer) error) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = stub -} - -func (fake *FakeManager) UpdateStreamServersArgsForCall(i int) (string, []client.StreamUpstreamServer) { - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - argsForCall := fake.updateStreamServersArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeManager) UpdateStreamServersReturns(result1 error) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = nil - fake.updateStreamServersReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) UpdateStreamServersReturnsOnCall(i int, result1 error) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = nil - if fake.updateStreamServersReturnsOnCall == nil { - fake.updateStreamServersReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.updateStreamServersReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeManager) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.getUpstreamsMutex.RLock() - defer fake.getUpstreamsMutex.RUnlock() - fake.isPlusMutex.RLock() - defer fake.isPlusMutex.RUnlock() - fake.reloadMutex.RLock() - defer fake.reloadMutex.RUnlock() - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeManager) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ runtime.Manager = new(FakeManager) diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_metrics_collector.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_metrics_collector.go deleted file mode 100644 index 4562c2c5c2..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_metrics_collector.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "sync" - "time" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" -) - -type FakeMetricsCollector struct { - IncReloadCountStub func() - incReloadCountMutex sync.RWMutex - incReloadCountArgsForCall []struct { - } - IncReloadErrorsStub func() - incReloadErrorsMutex sync.RWMutex - incReloadErrorsArgsForCall []struct { - } - ObserveLastReloadTimeStub func(time.Duration) - observeLastReloadTimeMutex sync.RWMutex - observeLastReloadTimeArgsForCall []struct { - arg1 time.Duration - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeMetricsCollector) IncReloadCount() { - fake.incReloadCountMutex.Lock() - fake.incReloadCountArgsForCall = append(fake.incReloadCountArgsForCall, struct { - }{}) - stub := fake.IncReloadCountStub - fake.recordInvocation("IncReloadCount", []interface{}{}) - fake.incReloadCountMutex.Unlock() - if stub != nil { - fake.IncReloadCountStub() - } -} - -func (fake *FakeMetricsCollector) IncReloadCountCallCount() int { - fake.incReloadCountMutex.RLock() - defer fake.incReloadCountMutex.RUnlock() - return len(fake.incReloadCountArgsForCall) -} - -func (fake *FakeMetricsCollector) IncReloadCountCalls(stub func()) { - fake.incReloadCountMutex.Lock() - defer fake.incReloadCountMutex.Unlock() - fake.IncReloadCountStub = stub -} - -func (fake *FakeMetricsCollector) IncReloadErrors() { - fake.incReloadErrorsMutex.Lock() - fake.incReloadErrorsArgsForCall = append(fake.incReloadErrorsArgsForCall, struct { - }{}) - stub := fake.IncReloadErrorsStub - fake.recordInvocation("IncReloadErrors", []interface{}{}) - fake.incReloadErrorsMutex.Unlock() - if stub != nil { - fake.IncReloadErrorsStub() - } -} - -func (fake *FakeMetricsCollector) IncReloadErrorsCallCount() int { - fake.incReloadErrorsMutex.RLock() - defer fake.incReloadErrorsMutex.RUnlock() - return len(fake.incReloadErrorsArgsForCall) -} - -func (fake *FakeMetricsCollector) IncReloadErrorsCalls(stub func()) { - fake.incReloadErrorsMutex.Lock() - defer fake.incReloadErrorsMutex.Unlock() - fake.IncReloadErrorsStub = stub -} - -func (fake *FakeMetricsCollector) ObserveLastReloadTime(arg1 time.Duration) { - fake.observeLastReloadTimeMutex.Lock() - fake.observeLastReloadTimeArgsForCall = append(fake.observeLastReloadTimeArgsForCall, struct { - arg1 time.Duration - }{arg1}) - stub := fake.ObserveLastReloadTimeStub - fake.recordInvocation("ObserveLastReloadTime", []interface{}{arg1}) - fake.observeLastReloadTimeMutex.Unlock() - if stub != nil { - fake.ObserveLastReloadTimeStub(arg1) - } -} - -func (fake *FakeMetricsCollector) ObserveLastReloadTimeCallCount() int { - fake.observeLastReloadTimeMutex.RLock() - defer fake.observeLastReloadTimeMutex.RUnlock() - return len(fake.observeLastReloadTimeArgsForCall) -} - -func (fake *FakeMetricsCollector) ObserveLastReloadTimeCalls(stub func(time.Duration)) { - fake.observeLastReloadTimeMutex.Lock() - defer fake.observeLastReloadTimeMutex.Unlock() - fake.ObserveLastReloadTimeStub = stub -} - -func (fake *FakeMetricsCollector) ObserveLastReloadTimeArgsForCall(i int) time.Duration { - fake.observeLastReloadTimeMutex.RLock() - defer fake.observeLastReloadTimeMutex.RUnlock() - argsForCall := fake.observeLastReloadTimeArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeMetricsCollector) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.incReloadCountMutex.RLock() - defer fake.incReloadCountMutex.RUnlock() - fake.incReloadErrorsMutex.RLock() - defer fake.incReloadErrorsMutex.RUnlock() - fake.observeLastReloadTimeMutex.RLock() - defer fake.observeLastReloadTimeMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeMetricsCollector) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ runtime.MetricsCollector = new(FakeMetricsCollector) diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_config_verifier.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_config_verifier.go deleted file mode 100644 index 23c5c67348..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_config_verifier.go +++ /dev/null @@ -1,269 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "context" - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" -) - -type FakeNginxConfigVerifier struct { - EnsureConfigVersionStub func(context.Context, int) error - ensureConfigVersionMutex sync.RWMutex - ensureConfigVersionArgsForCall []struct { - arg1 context.Context - arg2 int - } - ensureConfigVersionReturns struct { - result1 error - } - ensureConfigVersionReturnsOnCall map[int]struct { - result1 error - } - GetConfigVersionStub func() (int, error) - getConfigVersionMutex sync.RWMutex - getConfigVersionArgsForCall []struct { - } - getConfigVersionReturns struct { - result1 int - result2 error - } - getConfigVersionReturnsOnCall map[int]struct { - result1 int - result2 error - } - WaitForCorrectVersionStub func(context.Context, int, string, []byte, runtime.ReadFileFunc) error - waitForCorrectVersionMutex sync.RWMutex - waitForCorrectVersionArgsForCall []struct { - arg1 context.Context - arg2 int - arg3 string - arg4 []byte - arg5 runtime.ReadFileFunc - } - waitForCorrectVersionReturns struct { - result1 error - } - waitForCorrectVersionReturnsOnCall map[int]struct { - result1 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersion(arg1 context.Context, arg2 int) error { - fake.ensureConfigVersionMutex.Lock() - ret, specificReturn := fake.ensureConfigVersionReturnsOnCall[len(fake.ensureConfigVersionArgsForCall)] - fake.ensureConfigVersionArgsForCall = append(fake.ensureConfigVersionArgsForCall, struct { - arg1 context.Context - arg2 int - }{arg1, arg2}) - stub := fake.EnsureConfigVersionStub - fakeReturns := fake.ensureConfigVersionReturns - fake.recordInvocation("EnsureConfigVersion", []interface{}{arg1, arg2}) - fake.ensureConfigVersionMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersionCallCount() int { - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - return len(fake.ensureConfigVersionArgsForCall) -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersionCalls(stub func(context.Context, int) error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = stub -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersionArgsForCall(i int) (context.Context, int) { - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - argsForCall := fake.ensureConfigVersionArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersionReturns(result1 error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = nil - fake.ensureConfigVersionReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeNginxConfigVerifier) EnsureConfigVersionReturnsOnCall(i int, result1 error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = nil - if fake.ensureConfigVersionReturnsOnCall == nil { - fake.ensureConfigVersionReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.ensureConfigVersionReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeNginxConfigVerifier) GetConfigVersion() (int, error) { - fake.getConfigVersionMutex.Lock() - ret, specificReturn := fake.getConfigVersionReturnsOnCall[len(fake.getConfigVersionArgsForCall)] - fake.getConfigVersionArgsForCall = append(fake.getConfigVersionArgsForCall, struct { - }{}) - stub := fake.GetConfigVersionStub - fakeReturns := fake.getConfigVersionReturns - fake.recordInvocation("GetConfigVersion", []interface{}{}) - fake.getConfigVersionMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeNginxConfigVerifier) GetConfigVersionCallCount() int { - fake.getConfigVersionMutex.RLock() - defer fake.getConfigVersionMutex.RUnlock() - return len(fake.getConfigVersionArgsForCall) -} - -func (fake *FakeNginxConfigVerifier) GetConfigVersionCalls(stub func() (int, error)) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = stub -} - -func (fake *FakeNginxConfigVerifier) GetConfigVersionReturns(result1 int, result2 error) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = nil - fake.getConfigVersionReturns = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeNginxConfigVerifier) GetConfigVersionReturnsOnCall(i int, result1 int, result2 error) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = nil - if fake.getConfigVersionReturnsOnCall == nil { - fake.getConfigVersionReturnsOnCall = make(map[int]struct { - result1 int - result2 error - }) - } - fake.getConfigVersionReturnsOnCall[i] = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersion(arg1 context.Context, arg2 int, arg3 string, arg4 []byte, arg5 runtime.ReadFileFunc) error { - var arg4Copy []byte - if arg4 != nil { - arg4Copy = make([]byte, len(arg4)) - copy(arg4Copy, arg4) - } - fake.waitForCorrectVersionMutex.Lock() - ret, specificReturn := fake.waitForCorrectVersionReturnsOnCall[len(fake.waitForCorrectVersionArgsForCall)] - fake.waitForCorrectVersionArgsForCall = append(fake.waitForCorrectVersionArgsForCall, struct { - arg1 context.Context - arg2 int - arg3 string - arg4 []byte - arg5 runtime.ReadFileFunc - }{arg1, arg2, arg3, arg4Copy, arg5}) - stub := fake.WaitForCorrectVersionStub - fakeReturns := fake.waitForCorrectVersionReturns - fake.recordInvocation("WaitForCorrectVersion", []interface{}{arg1, arg2, arg3, arg4Copy, arg5}) - fake.waitForCorrectVersionMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersionCallCount() int { - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - return len(fake.waitForCorrectVersionArgsForCall) -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersionCalls(stub func(context.Context, int, string, []byte, runtime.ReadFileFunc) error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = stub -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersionArgsForCall(i int) (context.Context, int, string, []byte, runtime.ReadFileFunc) { - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - argsForCall := fake.waitForCorrectVersionArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersionReturns(result1 error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = nil - fake.waitForCorrectVersionReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeNginxConfigVerifier) WaitForCorrectVersionReturnsOnCall(i int, result1 error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = nil - if fake.waitForCorrectVersionReturnsOnCall == nil { - fake.waitForCorrectVersionReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.waitForCorrectVersionReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeNginxConfigVerifier) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - fake.getConfigVersionMutex.RLock() - defer fake.getConfigVersionMutex.RUnlock() - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeNginxConfigVerifier) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_plus_client.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_plus_client.go deleted file mode 100644 index 8001f7f8a7..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_nginx_plus_client.go +++ /dev/null @@ -1,370 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" - "github.com/nginxinc/nginx-plus-go-client/client" -) - -type FakeNginxPlusClient struct { - GetStreamUpstreamsStub func() (*client.StreamUpstreams, error) - getStreamUpstreamsMutex sync.RWMutex - getStreamUpstreamsArgsForCall []struct { - } - getStreamUpstreamsReturns struct { - result1 *client.StreamUpstreams - result2 error - } - getStreamUpstreamsReturnsOnCall map[int]struct { - result1 *client.StreamUpstreams - result2 error - } - GetUpstreamsStub func() (*client.Upstreams, error) - getUpstreamsMutex sync.RWMutex - getUpstreamsArgsForCall []struct { - } - getUpstreamsReturns struct { - result1 *client.Upstreams - result2 error - } - getUpstreamsReturnsOnCall map[int]struct { - result1 *client.Upstreams - result2 error - } - UpdateHTTPServersStub func(string, []client.UpstreamServer) ([]client.UpstreamServer, []client.UpstreamServer, []client.UpstreamServer, error) - updateHTTPServersMutex sync.RWMutex - updateHTTPServersArgsForCall []struct { - arg1 string - arg2 []client.UpstreamServer - } - updateHTTPServersReturns struct { - result1 []client.UpstreamServer - result2 []client.UpstreamServer - result3 []client.UpstreamServer - result4 error - } - updateHTTPServersReturnsOnCall map[int]struct { - result1 []client.UpstreamServer - result2 []client.UpstreamServer - result3 []client.UpstreamServer - result4 error - } - UpdateStreamServersStub func(string, []client.StreamUpstreamServer) ([]client.StreamUpstreamServer, []client.StreamUpstreamServer, []client.StreamUpstreamServer, error) - updateStreamServersMutex sync.RWMutex - updateStreamServersArgsForCall []struct { - arg1 string - arg2 []client.StreamUpstreamServer - } - updateStreamServersReturns struct { - result1 []client.StreamUpstreamServer - result2 []client.StreamUpstreamServer - result3 []client.StreamUpstreamServer - result4 error - } - updateStreamServersReturnsOnCall map[int]struct { - result1 []client.StreamUpstreamServer - result2 []client.StreamUpstreamServer - result3 []client.StreamUpstreamServer - result4 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeNginxPlusClient) GetStreamUpstreams() (*client.StreamUpstreams, error) { - fake.getStreamUpstreamsMutex.Lock() - ret, specificReturn := fake.getStreamUpstreamsReturnsOnCall[len(fake.getStreamUpstreamsArgsForCall)] - fake.getStreamUpstreamsArgsForCall = append(fake.getStreamUpstreamsArgsForCall, struct { - }{}) - stub := fake.GetStreamUpstreamsStub - fakeReturns := fake.getStreamUpstreamsReturns - fake.recordInvocation("GetStreamUpstreams", []interface{}{}) - fake.getStreamUpstreamsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeNginxPlusClient) GetStreamUpstreamsCallCount() int { - fake.getStreamUpstreamsMutex.RLock() - defer fake.getStreamUpstreamsMutex.RUnlock() - return len(fake.getStreamUpstreamsArgsForCall) -} - -func (fake *FakeNginxPlusClient) GetStreamUpstreamsCalls(stub func() (*client.StreamUpstreams, error)) { - fake.getStreamUpstreamsMutex.Lock() - defer fake.getStreamUpstreamsMutex.Unlock() - fake.GetStreamUpstreamsStub = stub -} - -func (fake *FakeNginxPlusClient) GetStreamUpstreamsReturns(result1 *client.StreamUpstreams, result2 error) { - fake.getStreamUpstreamsMutex.Lock() - defer fake.getStreamUpstreamsMutex.Unlock() - fake.GetStreamUpstreamsStub = nil - fake.getStreamUpstreamsReturns = struct { - result1 *client.StreamUpstreams - result2 error - }{result1, result2} -} - -func (fake *FakeNginxPlusClient) GetStreamUpstreamsReturnsOnCall(i int, result1 *client.StreamUpstreams, result2 error) { - fake.getStreamUpstreamsMutex.Lock() - defer fake.getStreamUpstreamsMutex.Unlock() - fake.GetStreamUpstreamsStub = nil - if fake.getStreamUpstreamsReturnsOnCall == nil { - fake.getStreamUpstreamsReturnsOnCall = make(map[int]struct { - result1 *client.StreamUpstreams - result2 error - }) - } - fake.getStreamUpstreamsReturnsOnCall[i] = struct { - result1 *client.StreamUpstreams - result2 error - }{result1, result2} -} - -func (fake *FakeNginxPlusClient) GetUpstreams() (*client.Upstreams, error) { - fake.getUpstreamsMutex.Lock() - ret, specificReturn := fake.getUpstreamsReturnsOnCall[len(fake.getUpstreamsArgsForCall)] - fake.getUpstreamsArgsForCall = append(fake.getUpstreamsArgsForCall, struct { - }{}) - stub := fake.GetUpstreamsStub - fakeReturns := fake.getUpstreamsReturns - fake.recordInvocation("GetUpstreams", []interface{}{}) - fake.getUpstreamsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeNginxPlusClient) GetUpstreamsCallCount() int { - fake.getUpstreamsMutex.RLock() - defer fake.getUpstreamsMutex.RUnlock() - return len(fake.getUpstreamsArgsForCall) -} - -func (fake *FakeNginxPlusClient) GetUpstreamsCalls(stub func() (*client.Upstreams, error)) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = stub -} - -func (fake *FakeNginxPlusClient) GetUpstreamsReturns(result1 *client.Upstreams, result2 error) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = nil - fake.getUpstreamsReturns = struct { - result1 *client.Upstreams - result2 error - }{result1, result2} -} - -func (fake *FakeNginxPlusClient) GetUpstreamsReturnsOnCall(i int, result1 *client.Upstreams, result2 error) { - fake.getUpstreamsMutex.Lock() - defer fake.getUpstreamsMutex.Unlock() - fake.GetUpstreamsStub = nil - if fake.getUpstreamsReturnsOnCall == nil { - fake.getUpstreamsReturnsOnCall = make(map[int]struct { - result1 *client.Upstreams - result2 error - }) - } - fake.getUpstreamsReturnsOnCall[i] = struct { - result1 *client.Upstreams - result2 error - }{result1, result2} -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServers(arg1 string, arg2 []client.UpstreamServer) ([]client.UpstreamServer, []client.UpstreamServer, []client.UpstreamServer, error) { - var arg2Copy []client.UpstreamServer - if arg2 != nil { - arg2Copy = make([]client.UpstreamServer, len(arg2)) - copy(arg2Copy, arg2) - } - fake.updateHTTPServersMutex.Lock() - ret, specificReturn := fake.updateHTTPServersReturnsOnCall[len(fake.updateHTTPServersArgsForCall)] - fake.updateHTTPServersArgsForCall = append(fake.updateHTTPServersArgsForCall, struct { - arg1 string - arg2 []client.UpstreamServer - }{arg1, arg2Copy}) - stub := fake.UpdateHTTPServersStub - fakeReturns := fake.updateHTTPServersReturns - fake.recordInvocation("UpdateHTTPServers", []interface{}{arg1, arg2Copy}) - fake.updateHTTPServersMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3, ret.result4 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3, fakeReturns.result4 -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServersCallCount() int { - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - return len(fake.updateHTTPServersArgsForCall) -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServersCalls(stub func(string, []client.UpstreamServer) ([]client.UpstreamServer, []client.UpstreamServer, []client.UpstreamServer, error)) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = stub -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServersArgsForCall(i int) (string, []client.UpstreamServer) { - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - argsForCall := fake.updateHTTPServersArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServersReturns(result1 []client.UpstreamServer, result2 []client.UpstreamServer, result3 []client.UpstreamServer, result4 error) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = nil - fake.updateHTTPServersReturns = struct { - result1 []client.UpstreamServer - result2 []client.UpstreamServer - result3 []client.UpstreamServer - result4 error - }{result1, result2, result3, result4} -} - -func (fake *FakeNginxPlusClient) UpdateHTTPServersReturnsOnCall(i int, result1 []client.UpstreamServer, result2 []client.UpstreamServer, result3 []client.UpstreamServer, result4 error) { - fake.updateHTTPServersMutex.Lock() - defer fake.updateHTTPServersMutex.Unlock() - fake.UpdateHTTPServersStub = nil - if fake.updateHTTPServersReturnsOnCall == nil { - fake.updateHTTPServersReturnsOnCall = make(map[int]struct { - result1 []client.UpstreamServer - result2 []client.UpstreamServer - result3 []client.UpstreamServer - result4 error - }) - } - fake.updateHTTPServersReturnsOnCall[i] = struct { - result1 []client.UpstreamServer - result2 []client.UpstreamServer - result3 []client.UpstreamServer - result4 error - }{result1, result2, result3, result4} -} - -func (fake *FakeNginxPlusClient) UpdateStreamServers(arg1 string, arg2 []client.StreamUpstreamServer) ([]client.StreamUpstreamServer, []client.StreamUpstreamServer, []client.StreamUpstreamServer, error) { - var arg2Copy []client.StreamUpstreamServer - if arg2 != nil { - arg2Copy = make([]client.StreamUpstreamServer, len(arg2)) - copy(arg2Copy, arg2) - } - fake.updateStreamServersMutex.Lock() - ret, specificReturn := fake.updateStreamServersReturnsOnCall[len(fake.updateStreamServersArgsForCall)] - fake.updateStreamServersArgsForCall = append(fake.updateStreamServersArgsForCall, struct { - arg1 string - arg2 []client.StreamUpstreamServer - }{arg1, arg2Copy}) - stub := fake.UpdateStreamServersStub - fakeReturns := fake.updateStreamServersReturns - fake.recordInvocation("UpdateStreamServers", []interface{}{arg1, arg2Copy}) - fake.updateStreamServersMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3, ret.result4 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3, fakeReturns.result4 -} - -func (fake *FakeNginxPlusClient) UpdateStreamServersCallCount() int { - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - return len(fake.updateStreamServersArgsForCall) -} - -func (fake *FakeNginxPlusClient) UpdateStreamServersCalls(stub func(string, []client.StreamUpstreamServer) ([]client.StreamUpstreamServer, []client.StreamUpstreamServer, []client.StreamUpstreamServer, error)) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = stub -} - -func (fake *FakeNginxPlusClient) UpdateStreamServersArgsForCall(i int) (string, []client.StreamUpstreamServer) { - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - argsForCall := fake.updateStreamServersArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeNginxPlusClient) UpdateStreamServersReturns(result1 []client.StreamUpstreamServer, result2 []client.StreamUpstreamServer, result3 []client.StreamUpstreamServer, result4 error) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = nil - fake.updateStreamServersReturns = struct { - result1 []client.StreamUpstreamServer - result2 []client.StreamUpstreamServer - result3 []client.StreamUpstreamServer - result4 error - }{result1, result2, result3, result4} -} - -func (fake *FakeNginxPlusClient) UpdateStreamServersReturnsOnCall(i int, result1 []client.StreamUpstreamServer, result2 []client.StreamUpstreamServer, result3 []client.StreamUpstreamServer, result4 error) { - fake.updateStreamServersMutex.Lock() - defer fake.updateStreamServersMutex.Unlock() - fake.UpdateStreamServersStub = nil - if fake.updateStreamServersReturnsOnCall == nil { - fake.updateStreamServersReturnsOnCall = make(map[int]struct { - result1 []client.StreamUpstreamServer - result2 []client.StreamUpstreamServer - result3 []client.StreamUpstreamServer - result4 error - }) - } - fake.updateStreamServersReturnsOnCall[i] = struct { - result1 []client.StreamUpstreamServer - result2 []client.StreamUpstreamServer - result3 []client.StreamUpstreamServer - result4 error - }{result1, result2, result3, result4} -} - -func (fake *FakeNginxPlusClient) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.getStreamUpstreamsMutex.RLock() - defer fake.getStreamUpstreamsMutex.RUnlock() - fake.getUpstreamsMutex.RLock() - defer fake.getUpstreamsMutex.RUnlock() - fake.updateHTTPServersMutex.RLock() - defer fake.updateHTTPServersMutex.RUnlock() - fake.updateStreamServersMutex.RLock() - defer fake.updateStreamServersMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeNginxPlusClient) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ runtime.NginxPlusClient = new(FakeNginxPlusClient) diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_process_handler.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_process_handler.go deleted file mode 100644 index bae52e2fa7..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_process_handler.go +++ /dev/null @@ -1,273 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "context" - "sync" - "time" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" -) - -type FakeProcessHandler struct { - FindMainProcessStub func(context.Context, time.Duration) (int, error) - findMainProcessMutex sync.RWMutex - findMainProcessArgsForCall []struct { - arg1 context.Context - arg2 time.Duration - } - findMainProcessReturns struct { - result1 int - result2 error - } - findMainProcessReturnsOnCall map[int]struct { - result1 int - result2 error - } - KillStub func(int) error - killMutex sync.RWMutex - killArgsForCall []struct { - arg1 int - } - killReturns struct { - result1 error - } - killReturnsOnCall map[int]struct { - result1 error - } - ReadFileStub func(string) ([]byte, error) - readFileMutex sync.RWMutex - readFileArgsForCall []struct { - arg1 string - } - readFileReturns struct { - result1 []byte - result2 error - } - readFileReturnsOnCall map[int]struct { - result1 []byte - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeProcessHandler) FindMainProcess(arg1 context.Context, arg2 time.Duration) (int, error) { - fake.findMainProcessMutex.Lock() - ret, specificReturn := fake.findMainProcessReturnsOnCall[len(fake.findMainProcessArgsForCall)] - fake.findMainProcessArgsForCall = append(fake.findMainProcessArgsForCall, struct { - arg1 context.Context - arg2 time.Duration - }{arg1, arg2}) - stub := fake.FindMainProcessStub - fakeReturns := fake.findMainProcessReturns - fake.recordInvocation("FindMainProcess", []interface{}{arg1, arg2}) - fake.findMainProcessMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeProcessHandler) FindMainProcessCallCount() int { - fake.findMainProcessMutex.RLock() - defer fake.findMainProcessMutex.RUnlock() - return len(fake.findMainProcessArgsForCall) -} - -func (fake *FakeProcessHandler) FindMainProcessCalls(stub func(context.Context, time.Duration) (int, error)) { - fake.findMainProcessMutex.Lock() - defer fake.findMainProcessMutex.Unlock() - fake.FindMainProcessStub = stub -} - -func (fake *FakeProcessHandler) FindMainProcessArgsForCall(i int) (context.Context, time.Duration) { - fake.findMainProcessMutex.RLock() - defer fake.findMainProcessMutex.RUnlock() - argsForCall := fake.findMainProcessArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeProcessHandler) FindMainProcessReturns(result1 int, result2 error) { - fake.findMainProcessMutex.Lock() - defer fake.findMainProcessMutex.Unlock() - fake.FindMainProcessStub = nil - fake.findMainProcessReturns = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeProcessHandler) FindMainProcessReturnsOnCall(i int, result1 int, result2 error) { - fake.findMainProcessMutex.Lock() - defer fake.findMainProcessMutex.Unlock() - fake.FindMainProcessStub = nil - if fake.findMainProcessReturnsOnCall == nil { - fake.findMainProcessReturnsOnCall = make(map[int]struct { - result1 int - result2 error - }) - } - fake.findMainProcessReturnsOnCall[i] = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeProcessHandler) Kill(arg1 int) error { - fake.killMutex.Lock() - ret, specificReturn := fake.killReturnsOnCall[len(fake.killArgsForCall)] - fake.killArgsForCall = append(fake.killArgsForCall, struct { - arg1 int - }{arg1}) - stub := fake.KillStub - fakeReturns := fake.killReturns - fake.recordInvocation("Kill", []interface{}{arg1}) - fake.killMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeProcessHandler) KillCallCount() int { - fake.killMutex.RLock() - defer fake.killMutex.RUnlock() - return len(fake.killArgsForCall) -} - -func (fake *FakeProcessHandler) KillCalls(stub func(int) error) { - fake.killMutex.Lock() - defer fake.killMutex.Unlock() - fake.KillStub = stub -} - -func (fake *FakeProcessHandler) KillArgsForCall(i int) int { - fake.killMutex.RLock() - defer fake.killMutex.RUnlock() - argsForCall := fake.killArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeProcessHandler) KillReturns(result1 error) { - fake.killMutex.Lock() - defer fake.killMutex.Unlock() - fake.KillStub = nil - fake.killReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeProcessHandler) KillReturnsOnCall(i int, result1 error) { - fake.killMutex.Lock() - defer fake.killMutex.Unlock() - fake.KillStub = nil - if fake.killReturnsOnCall == nil { - fake.killReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.killReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeProcessHandler) ReadFile(arg1 string) ([]byte, error) { - fake.readFileMutex.Lock() - ret, specificReturn := fake.readFileReturnsOnCall[len(fake.readFileArgsForCall)] - fake.readFileArgsForCall = append(fake.readFileArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.ReadFileStub - fakeReturns := fake.readFileReturns - fake.recordInvocation("ReadFile", []interface{}{arg1}) - fake.readFileMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeProcessHandler) ReadFileCallCount() int { - fake.readFileMutex.RLock() - defer fake.readFileMutex.RUnlock() - return len(fake.readFileArgsForCall) -} - -func (fake *FakeProcessHandler) ReadFileCalls(stub func(string) ([]byte, error)) { - fake.readFileMutex.Lock() - defer fake.readFileMutex.Unlock() - fake.ReadFileStub = stub -} - -func (fake *FakeProcessHandler) ReadFileArgsForCall(i int) string { - fake.readFileMutex.RLock() - defer fake.readFileMutex.RUnlock() - argsForCall := fake.readFileArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeProcessHandler) ReadFileReturns(result1 []byte, result2 error) { - fake.readFileMutex.Lock() - defer fake.readFileMutex.Unlock() - fake.ReadFileStub = nil - fake.readFileReturns = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *FakeProcessHandler) ReadFileReturnsOnCall(i int, result1 []byte, result2 error) { - fake.readFileMutex.Lock() - defer fake.readFileMutex.Unlock() - fake.ReadFileStub = nil - if fake.readFileReturnsOnCall == nil { - fake.readFileReturnsOnCall = make(map[int]struct { - result1 []byte - result2 error - }) - } - fake.readFileReturnsOnCall[i] = struct { - result1 []byte - result2 error - }{result1, result2} -} - -func (fake *FakeProcessHandler) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.findMainProcessMutex.RLock() - defer fake.findMainProcessMutex.RUnlock() - fake.killMutex.RLock() - defer fake.killMutex.RUnlock() - fake.readFileMutex.RLock() - defer fake.readFileMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeProcessHandler) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ runtime.ProcessHandler = new(FakeProcessHandler) diff --git a/internal/mode/static/nginx/runtime/runtimefakes/fake_verify_client.go b/internal/mode/static/nginx/runtime/runtimefakes/fake_verify_client.go deleted file mode 100644 index 13c5f78224..0000000000 --- a/internal/mode/static/nginx/runtime/runtimefakes/fake_verify_client.go +++ /dev/null @@ -1,269 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package runtimefakes - -import ( - "context" - "sync" - - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" -) - -type FakeVerifyClient struct { - EnsureConfigVersionStub func(context.Context, int) error - ensureConfigVersionMutex sync.RWMutex - ensureConfigVersionArgsForCall []struct { - arg1 context.Context - arg2 int - } - ensureConfigVersionReturns struct { - result1 error - } - ensureConfigVersionReturnsOnCall map[int]struct { - result1 error - } - GetConfigVersionStub func() (int, error) - getConfigVersionMutex sync.RWMutex - getConfigVersionArgsForCall []struct { - } - getConfigVersionReturns struct { - result1 int - result2 error - } - getConfigVersionReturnsOnCall map[int]struct { - result1 int - result2 error - } - WaitForCorrectVersionStub func(context.Context, int, string, []byte, runtime.ReadFileFunc) error - waitForCorrectVersionMutex sync.RWMutex - waitForCorrectVersionArgsForCall []struct { - arg1 context.Context - arg2 int - arg3 string - arg4 []byte - arg5 runtime.ReadFileFunc - } - waitForCorrectVersionReturns struct { - result1 error - } - waitForCorrectVersionReturnsOnCall map[int]struct { - result1 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeVerifyClient) EnsureConfigVersion(arg1 context.Context, arg2 int) error { - fake.ensureConfigVersionMutex.Lock() - ret, specificReturn := fake.ensureConfigVersionReturnsOnCall[len(fake.ensureConfigVersionArgsForCall)] - fake.ensureConfigVersionArgsForCall = append(fake.ensureConfigVersionArgsForCall, struct { - arg1 context.Context - arg2 int - }{arg1, arg2}) - stub := fake.EnsureConfigVersionStub - fakeReturns := fake.ensureConfigVersionReturns - fake.recordInvocation("EnsureConfigVersion", []interface{}{arg1, arg2}) - fake.ensureConfigVersionMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeVerifyClient) EnsureConfigVersionCallCount() int { - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - return len(fake.ensureConfigVersionArgsForCall) -} - -func (fake *FakeVerifyClient) EnsureConfigVersionCalls(stub func(context.Context, int) error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = stub -} - -func (fake *FakeVerifyClient) EnsureConfigVersionArgsForCall(i int) (context.Context, int) { - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - argsForCall := fake.ensureConfigVersionArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeVerifyClient) EnsureConfigVersionReturns(result1 error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = nil - fake.ensureConfigVersionReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeVerifyClient) EnsureConfigVersionReturnsOnCall(i int, result1 error) { - fake.ensureConfigVersionMutex.Lock() - defer fake.ensureConfigVersionMutex.Unlock() - fake.EnsureConfigVersionStub = nil - if fake.ensureConfigVersionReturnsOnCall == nil { - fake.ensureConfigVersionReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.ensureConfigVersionReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeVerifyClient) GetConfigVersion() (int, error) { - fake.getConfigVersionMutex.Lock() - ret, specificReturn := fake.getConfigVersionReturnsOnCall[len(fake.getConfigVersionArgsForCall)] - fake.getConfigVersionArgsForCall = append(fake.getConfigVersionArgsForCall, struct { - }{}) - stub := fake.GetConfigVersionStub - fakeReturns := fake.getConfigVersionReturns - fake.recordInvocation("GetConfigVersion", []interface{}{}) - fake.getConfigVersionMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeVerifyClient) GetConfigVersionCallCount() int { - fake.getConfigVersionMutex.RLock() - defer fake.getConfigVersionMutex.RUnlock() - return len(fake.getConfigVersionArgsForCall) -} - -func (fake *FakeVerifyClient) GetConfigVersionCalls(stub func() (int, error)) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = stub -} - -func (fake *FakeVerifyClient) GetConfigVersionReturns(result1 int, result2 error) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = nil - fake.getConfigVersionReturns = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeVerifyClient) GetConfigVersionReturnsOnCall(i int, result1 int, result2 error) { - fake.getConfigVersionMutex.Lock() - defer fake.getConfigVersionMutex.Unlock() - fake.GetConfigVersionStub = nil - if fake.getConfigVersionReturnsOnCall == nil { - fake.getConfigVersionReturnsOnCall = make(map[int]struct { - result1 int - result2 error - }) - } - fake.getConfigVersionReturnsOnCall[i] = struct { - result1 int - result2 error - }{result1, result2} -} - -func (fake *FakeVerifyClient) WaitForCorrectVersion(arg1 context.Context, arg2 int, arg3 string, arg4 []byte, arg5 runtime.ReadFileFunc) error { - var arg4Copy []byte - if arg4 != nil { - arg4Copy = make([]byte, len(arg4)) - copy(arg4Copy, arg4) - } - fake.waitForCorrectVersionMutex.Lock() - ret, specificReturn := fake.waitForCorrectVersionReturnsOnCall[len(fake.waitForCorrectVersionArgsForCall)] - fake.waitForCorrectVersionArgsForCall = append(fake.waitForCorrectVersionArgsForCall, struct { - arg1 context.Context - arg2 int - arg3 string - arg4 []byte - arg5 runtime.ReadFileFunc - }{arg1, arg2, arg3, arg4Copy, arg5}) - stub := fake.WaitForCorrectVersionStub - fakeReturns := fake.waitForCorrectVersionReturns - fake.recordInvocation("WaitForCorrectVersion", []interface{}{arg1, arg2, arg3, arg4Copy, arg5}) - fake.waitForCorrectVersionMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeVerifyClient) WaitForCorrectVersionCallCount() int { - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - return len(fake.waitForCorrectVersionArgsForCall) -} - -func (fake *FakeVerifyClient) WaitForCorrectVersionCalls(stub func(context.Context, int, string, []byte, runtime.ReadFileFunc) error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = stub -} - -func (fake *FakeVerifyClient) WaitForCorrectVersionArgsForCall(i int) (context.Context, int, string, []byte, runtime.ReadFileFunc) { - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - argsForCall := fake.waitForCorrectVersionArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeVerifyClient) WaitForCorrectVersionReturns(result1 error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = nil - fake.waitForCorrectVersionReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeVerifyClient) WaitForCorrectVersionReturnsOnCall(i int, result1 error) { - fake.waitForCorrectVersionMutex.Lock() - defer fake.waitForCorrectVersionMutex.Unlock() - fake.WaitForCorrectVersionStub = nil - if fake.waitForCorrectVersionReturnsOnCall == nil { - fake.waitForCorrectVersionReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.waitForCorrectVersionReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeVerifyClient) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.ensureConfigVersionMutex.RLock() - defer fake.ensureConfigVersionMutex.RUnlock() - fake.getConfigVersionMutex.RLock() - defer fake.getConfigVersionMutex.RUnlock() - fake.waitForCorrectVersionMutex.RLock() - defer fake.waitForCorrectVersionMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeVerifyClient) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} diff --git a/internal/mode/static/nginx/runtime/verify.go b/internal/mode/static/nginx/runtime/verify.go deleted file mode 100644 index 9dc64d4e34..0000000000 --- a/internal/mode/static/nginx/runtime/verify.go +++ /dev/null @@ -1,155 +0,0 @@ -package runtime - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "net" - "net/http" - "strconv" - "time" - - "k8s.io/apimachinery/pkg/util/wait" -) - -const configVersionURI = "/var/run/nginx/nginx-config-version.sock" - -var noNewWorkersErrFmt = "reload unsuccessful: no new NGINX worker processes started for config version %d." + - " Please check the NGINX container logs for possible configuration issues: %w" - -//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . nginxConfigVerifier - -type nginxConfigVerifier interface { - GetConfigVersion() (int, error) - WaitForCorrectVersion( - ctx context.Context, - expectedVersion int, - childProcFile string, - previousChildProcesses []byte, - readFile ReadFileFunc, - ) error - EnsureConfigVersion(ctx context.Context, expectedVersion int) error -} - -// VerifyClient is a client for verifying the config version. -type VerifyClient struct { - client *http.Client - timeout time.Duration -} - -// NewVerifyClient returns a new client pointed at the config version socket. -func NewVerifyClient(timeout time.Duration) *VerifyClient { - return &VerifyClient{ - client: &http.Client{ - Transport: &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", configVersionURI) - }, - }, - }, - timeout: timeout, - } -} - -// GetConfigVersion gets the version number that we put in the nginx config to verify that we're using -// the correct config. -func (c *VerifyClient) GetConfigVersion() (int, error) { - ctx, cancel := context.WithTimeout(context.Background(), c.timeout) - defer cancel() - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://config-version/version", nil) - if err != nil { - return 0, fmt.Errorf("error creating request: %w", err) - } - - resp, err := c.client.Do(req) - if err != nil { - return 0, fmt.Errorf("error getting client: %w", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return 0, fmt.Errorf("non-200 response: %v", resp.StatusCode) - } - - body, err := io.ReadAll(resp.Body) - if err != nil { - return 0, fmt.Errorf("failed to read the response body: %w", err) - } - v, err := strconv.Atoi(string(body)) - if err != nil { - return 0, fmt.Errorf("error converting string to int: %w", err) - } - return v, nil -} - -// WaitForCorrectVersion first ensures any new worker processes have been started, and then calls the config version -// endpoint until it gets the expectedVersion, which ensures that a new worker process has been started for that config -// version. -func (c *VerifyClient) WaitForCorrectVersion( - ctx context.Context, - expectedVersion int, - childProcFile string, - previousChildProcesses []byte, - readFile ReadFileFunc, -) error { - ctx, cancel := context.WithTimeout(ctx, c.timeout) - defer cancel() - - if err := ensureNewNginxWorkers( - ctx, - childProcFile, - previousChildProcesses, - readFile, - ); err != nil { - return fmt.Errorf(noNewWorkersErrFmt, expectedVersion, err) - } - - if err := c.EnsureConfigVersion(ctx, expectedVersion); err != nil { - if errors.Is(err, context.DeadlineExceeded) { - err = fmt.Errorf( - "config version check didn't return expected version %d within the deadline", - expectedVersion, - ) - } - return fmt.Errorf("could not get expected config version %d: %w", expectedVersion, err) - } - return nil -} - -func (c *VerifyClient) EnsureConfigVersion(ctx context.Context, expectedVersion int) error { - return wait.PollUntilContextCancel( - ctx, - 25*time.Millisecond, - true, /* poll immediately */ - func(_ context.Context) (bool, error) { - version, err := c.GetConfigVersion() - return version == expectedVersion, err - }, - ) -} - -func ensureNewNginxWorkers( - ctx context.Context, - childProcFile string, - previousContents []byte, - readFile ReadFileFunc, -) error { - return wait.PollUntilContextCancel( - ctx, - 25*time.Millisecond, - true, /* poll immediately */ - func(_ context.Context) (bool, error) { - content, err := readFile(childProcFile) - if err != nil { - return false, err - } - if !bytes.Equal(previousContents, content) { - return true, nil - } - return false, nil - }, - ) -} diff --git a/internal/mode/static/nginx/runtime/verify_test.go b/internal/mode/static/nginx/runtime/verify_test.go deleted file mode 100644 index d20844a410..0000000000 --- a/internal/mode/static/nginx/runtime/verify_test.go +++ /dev/null @@ -1,186 +0,0 @@ -package runtime - -import ( - "bytes" - "context" - "errors" - "io" - "net/http" - "testing" - "time" - - . "github.com/onsi/gomega" -) - -type transport struct{} - -func (c transport) RoundTrip(_ *http.Request) (*http.Response, error) { - return &http.Response{ - StatusCode: http.StatusOK, - Body: io.NopCloser(bytes.NewBufferString("42")), - Header: make(http.Header), - }, nil -} - -func getTestHTTPClient() *http.Client { - ts := transport{} - return &http.Client{ - Transport: ts, - } -} - -func TestVerifyClient(t *testing.T) { - t.Parallel() - c := VerifyClient{ - client: getTestHTTPClient(), - timeout: 25 * time.Millisecond, - } - - ctx := context.Background() - cancellingCtx, cancel := context.WithCancel(ctx) - time.AfterFunc(1*time.Millisecond, cancel) - - newContents := []byte("4 5 6") - - readFileNew := func(string) ([]byte, error) { - return newContents, nil - } - readFileError := func(string) ([]byte, error) { - return nil, errors.New("error") - } - - tests := []struct { - ctx context.Context - readFile ReadFileFunc - name string - expectedVersion int - expectError bool - }{ - { - ctx: ctx, - expectedVersion: 42, - readFile: readFileNew, - expectError: false, - name: "normal case", - }, - { - ctx: ctx, - expectedVersion: 43, - readFile: readFileNew, - expectError: true, - name: "wrong version", - }, - { - ctx: ctx, - expectedVersion: 0, - readFile: readFileError, - expectError: true, - name: "no new workers", - }, - { - ctx: cancellingCtx, - expectedVersion: 0, - readFile: readFileNew, - expectError: true, - name: "context canceled", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - err := c.WaitForCorrectVersion(test.ctx, test.expectedVersion, "/childfile", []byte("1 2 3"), test.readFile) - - if test.expectError { - g.Expect(err).To(HaveOccurred()) - } else { - g.Expect(err).ToNot(HaveOccurred()) - } - }) - } -} - -func TestEnsureNewNginxWorkers(t *testing.T) { - t.Parallel() - previousContents := []byte("1 2 3") - newContents := []byte("4 5 6") - - readFileError := func(string) ([]byte, error) { - return nil, errors.New("error") - } - - readFilePrevious := func(string) ([]byte, error) { - return previousContents, nil - } - - readFileNew := func(string) ([]byte, error) { - return newContents, nil - } - - ctx := context.Background() - - cancellingCtx, cancel := context.WithCancel(ctx) - time.AfterFunc(100*time.Millisecond, cancel) - - cancellingCtx2, cancel2 := context.WithCancel(ctx) - time.AfterFunc(1*time.Millisecond, cancel2) - - tests := []struct { - ctx context.Context - readFile ReadFileFunc - name string - previousContents []byte - expectError bool - }{ - { - ctx: ctx, - readFile: readFileNew, - previousContents: previousContents, - expectError: false, - name: "normal case", - }, - { - ctx: ctx, - readFile: readFileError, - previousContents: previousContents, - expectError: true, - name: "cannot read file", - }, - { - ctx: cancellingCtx, - readFile: readFilePrevious, - previousContents: previousContents, - expectError: true, - name: "timed out waiting for new workers", - }, - { - ctx: cancellingCtx2, - readFile: readFilePrevious, - previousContents: previousContents, - expectError: true, - name: "context canceled", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - err := ensureNewNginxWorkers( - test.ctx, - "/childfile", - test.previousContents, - test.readFile, - ) - - if test.expectError { - g.Expect(err).To(HaveOccurred()) - } else { - g.Expect(err).ToNot(HaveOccurred()) - } - }) - } -}