diff --git a/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml b/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml index 87b62ae7..ef716e4d 100644 --- a/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml +++ b/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml @@ -38,7 +38,7 @@ nginxGateway: image: ## The NGINX Gateway Fabric image to use repository: ghcr.io/nginxinc/nginx-gateway-fabric - tag: 1.1.0 + tag: 1.3.0 pullPolicy: IfNotPresent securityContext: @@ -55,7 +55,7 @@ nginx: ## The NGINX image to use image: repository: ghcr.io/nginxinc/nginx-gateway-fabric/nginx - tag: 1.1.0 + tag: 1.3.0 pullPolicy: IfNotPresent ## The lifecycle of the nginx container. @@ -85,7 +85,7 @@ service: ## The type of service to create for the NGINX Gateway Fabric. type: LoadBalancer ## The externalTrafficPolicy of the service. The value Local preserves the client source IP. - externalTrafficPolicy: Local + externalTrafficPolicy: Cluster ## The annotations of the NGINX Gateway Fabric service. annotations: "metallb.universe.tf/address-pool": "openstack-external" diff --git a/base-kustomize/barbican/base/barbican-routes.yaml b/base-kustomize/barbican/base/barbican-routes.yaml new file mode 100644 index 00000000..a35577d7 --- /dev/null +++ b/base-kustomize/barbican/base/barbican-routes.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: barbican-route + namespace: openstack +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "barbican.cluster.local" + rules: + - backendRefs: + - name: barbican-api + port: 9311 diff --git a/base-kustomize/barbican/base/kustomization.yaml b/base-kustomize/barbican/base/kustomization.yaml index e8002296..62728a7f 100644 --- a/base-kustomize/barbican/base/kustomization.yaml +++ b/base-kustomize/barbican/base/kustomization.yaml @@ -3,3 +3,4 @@ resources: - barbican-rabbitmq-queue.yaml - all.yaml - hpa-barbican-api.yaml + - barbican-routes.yaml diff --git a/base-kustomize/cinder/base/cinder-routes.yaml b/base-kustomize/cinder/base/cinder-routes.yaml new file mode 100644 index 00000000..4f477904 --- /dev/null +++ b/base-kustomize/cinder/base/cinder-routes.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: cinder-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: cinder +spec: + parentRefs: + - name: flex-gateway + sectionName: cinder-tls + namespace: nginx-gateway + hostnames: + - "cinder.cluster.local" + rules: + - backendRefs: + - name: cinder-api + port: 8776 diff --git a/base-kustomize/cinder/base/kustomization.yaml b/base-kustomize/cinder/base/kustomization.yaml index 7489cc40..9c6b8c2b 100644 --- a/base-kustomize/cinder/base/kustomization.yaml +++ b/base-kustomize/cinder/base/kustomization.yaml @@ -4,3 +4,4 @@ resources: - all.yaml - hpa-cinder-scheduler.yaml - hpa-cinder-api.yaml + - cinder-routes.yaml diff --git a/base-kustomize/gateway/grafana-routes.yaml b/base-kustomize/gateway/grafana-routes.yaml index bff3976a..00e4838d 100644 --- a/base-kustomize/gateway/grafana-routes.yaml +++ b/base-kustomize/gateway/grafana-routes.yaml @@ -6,10 +6,13 @@ metadata: spec: parentRefs: - name: flex-gateway - sectionName: graf-https + sectionName: cluster-tls namespace: nginx-gateway hostnames: - - "grafana.sjc3.rackspacecloud.com" + - "grafana.cluster.local" + - "grafana" + - "grafana.grafana" + - "grafana.grafana.svc.cluster.local" rules: - backendRefs: - name: grafana diff --git a/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-api.yaml b/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-api.yaml index 8cb90192..b04224d1 100644 --- a/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-api.yaml +++ b/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-api.yaml @@ -3,54 +3,23 @@ kind: Gateway metadata: name: flex-gateway namespace: nginx-gateway - annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod-gw + annotations: # This is the name of the ClusterIssuer created in the previous step + cert-manager.io/cluster-issuer: flex-gateway-issuer acme.cert-manager.io/http01-edit-in-place: "true" spec: gatewayClassName: nginx listeners: - - name: o3-http + - name: cluster-http port: 80 protocol: HTTP - hostname: "*.sjc.ohthree.com" + hostname: "*.cluster.local" allowedRoutes: namespaces: from: All - - name: rackspacecloud-http - port: 80 - protocol: HTTP - hostname: "*.sjc3.rackspacecloud.com" - allowedRoutes: - namespaces: - from: All - - name: am-https - hostname: "alertmanager.sjc.ohthree.com" - port: 443 - protocol: HTTPS - allowedRoutes: - namespaces: - from: All - tls: - mode: Terminate - certificateRefs: - - kind: Secret - name: alertmanager-gw-tls-secret - - name: prom-https - hostname: "prometheus.sjc.ohthree.com" - port: 443 - protocol: HTTPS - allowedRoutes: - namespaces: - from: All - tls: - mode: Terminate - certificateRefs: - - kind: Secret - name: prometheus-gw-tls-secret - - name: graf-https - hostname: "grafana.sjc3.rackspacecloud.com" + - name: cluster-tls port: 443 protocol: HTTPS + hostname: "*.cluster.local" allowedRoutes: namespaces: from: All @@ -58,4 +27,4 @@ spec: mode: Terminate certificateRefs: - kind: Secret - name: grafana-gw-tls-secret + name: wildcard-cluster-tls-secret diff --git a/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-issuer.yaml b/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-issuer.yaml new file mode 100644 index 00000000..7291f608 --- /dev/null +++ b/base-kustomize/gateway/nginx-gateway-fabric/internal-gateway-issuer.yaml @@ -0,0 +1,7 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: flex-gateway-issuer + namespace: nginx-gateway +spec: + selfSigned: {} diff --git a/base-kustomize/gateway/nginx-gateway-fabric/kustomization.yaml b/base-kustomize/gateway/nginx-gateway-fabric/kustomization.yaml index eeb4fb4f..ecbb1c4f 100644 --- a/base-kustomize/gateway/nginx-gateway-fabric/kustomization.yaml +++ b/base-kustomize/gateway/nginx-gateway-fabric/kustomization.yaml @@ -1,4 +1,5 @@ resources: - internal-gateway-api.yaml # namespace: nginx-gateway (common gateway) + - internal-gateway-issuer.yaml #namespace: nginx-gateway - alertmanager-routes.yaml # namespace: prometheus - prometheus-routes.yaml # namespace: prometheus diff --git a/base-kustomize/glance/base/client-settings.yaml b/base-kustomize/glance/base/client-settings.yaml new file mode 100644 index 00000000..b6e2831a --- /dev/null +++ b/base-kustomize/glance/base/client-settings.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: gateway.nginx.org/v1alpha1 +kind: ClientSettingsPolicy +metadata: + name: gateway-client-settings + namespace: nginx-gateway +spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: flex-gateway + body: + maxSize: "120g" # sizes without a unit are bytes. diff --git a/base-kustomize/glance/base/glance-routes.yaml b/base-kustomize/glance/base/glance-routes.yaml new file mode 100644 index 00000000..43650a3d --- /dev/null +++ b/base-kustomize/glance/base/glance-routes.yaml @@ -0,0 +1,20 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: glance-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: glance +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "glance.cluster.local" + rules: + - backendRefs: + - name: glance-api + port: 9292 diff --git a/base-kustomize/glance/base/kustomization.yaml b/base-kustomize/glance/base/kustomization.yaml index 69fce788..ca369db6 100644 --- a/base-kustomize/glance/base/kustomization.yaml +++ b/base-kustomize/glance/base/kustomization.yaml @@ -3,6 +3,8 @@ resources: - glance-rabbitmq-queue.yaml - all.yaml - hpa-glance-api.yaml + - glance-routes.yaml + - client-settings.yaml patches: - target: diff --git a/base-kustomize/heat/base/heat-routes.yaml b/base-kustomize/heat/base/heat-routes.yaml new file mode 100644 index 00000000..b0e6936c --- /dev/null +++ b/base-kustomize/heat/base/heat-routes.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: cloudformation-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: cloudformation +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "cloudformation.cluster.local" + rules: + - backendRefs: + - name: heat-cfn + port: 8000 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: heat-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: heat +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "heat.cluster.local" + rules: + - backendRefs: + - name: heat-api + port: 8004 diff --git a/base-kustomize/heat/base/kustomization.yaml b/base-kustomize/heat/base/kustomization.yaml index 82aec430..16534499 100644 --- a/base-kustomize/heat/base/kustomization.yaml +++ b/base-kustomize/heat/base/kustomization.yaml @@ -5,3 +5,4 @@ resources: - hpa-heat-api.yaml - hpa-heat-cfn.yaml - hpa-heat-engine.yaml + - heat-routes.yaml diff --git a/base-kustomize/keystone/base/keystone-routes.yaml b/base-kustomize/keystone/base/keystone-routes.yaml new file mode 100644 index 00000000..d4c02148 --- /dev/null +++ b/base-kustomize/keystone/base/keystone-routes.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: keystone-gateway-route + namespace: openstack +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "keystone.cluster.local" + rules: + - backendRefs: + - name: keystone-api + port: 5000 diff --git a/base-kustomize/keystone/base/kustomization.yaml b/base-kustomize/keystone/base/kustomization.yaml index 0105ae67..30838c7c 100644 --- a/base-kustomize/keystone/base/kustomization.yaml +++ b/base-kustomize/keystone/base/kustomization.yaml @@ -3,3 +3,4 @@ resources: - keystone-rabbitmq-queue.yaml - all.yaml - hpa-keystone-api.yaml + - keystone-routes.yaml diff --git a/base-kustomize/neutron/base/kustomization.yaml b/base-kustomize/neutron/base/kustomization.yaml index aa9cd85b..ccea29fd 100644 --- a/base-kustomize/neutron/base/kustomization.yaml +++ b/base-kustomize/neutron/base/kustomization.yaml @@ -3,6 +3,7 @@ resources: - neutron-rabbitmq-queue.yaml - all.yaml - hpa-neutron-server.yaml + - neutron-routes.yaml patches: - target: diff --git a/base-kustomize/neutron/base/neutron-routes.yaml b/base-kustomize/neutron/base/neutron-routes.yaml new file mode 100644 index 00000000..ea3e0a63 --- /dev/null +++ b/base-kustomize/neutron/base/neutron-routes.yaml @@ -0,0 +1,20 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: neutron-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: neutron +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "neutron.cluster.local" + rules: + - backendRefs: + - name: neutron-server + port: 9696 diff --git a/base-kustomize/octavia/base/kustomization.yaml b/base-kustomize/octavia/base/kustomization.yaml index cb325669..b4f6c326 100644 --- a/base-kustomize/octavia/base/kustomization.yaml +++ b/base-kustomize/octavia/base/kustomization.yaml @@ -4,6 +4,7 @@ resources: - all.yaml - hpa-octavia-api.yaml - hpa-octavia-worker.yaml + - octavia-routes.yaml # To run the OVN driver, the octavia-api container must have an agent container within the same pod. patches: diff --git a/base-kustomize/octavia/base/octavia-routes.yaml b/base-kustomize/octavia/base/octavia-routes.yaml new file mode 100644 index 00000000..ed6fddf1 --- /dev/null +++ b/base-kustomize/octavia/base/octavia-routes.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: octavia-api + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: octavia +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "octavia.cluster.local" + rules: + - backendRefs: + - name: octavia-api + port: 9876 diff --git a/base-kustomize/placement/base/kustomization.yaml b/base-kustomize/placement/base/kustomization.yaml index 6c7d855a..5f0a6efd 100644 --- a/base-kustomize/placement/base/kustomization.yaml +++ b/base-kustomize/placement/base/kustomization.yaml @@ -2,3 +2,4 @@ resources: - placement-mariadb-database.yaml - all.yaml - hpa-placement-api.yaml + - placement-nova-routes.yaml diff --git a/base-kustomize/placement/base/placement-nova-routes.yaml b/base-kustomize/placement/base/placement-nova-routes.yaml new file mode 100644 index 00000000..1cb594db --- /dev/null +++ b/base-kustomize/placement/base/placement-nova-routes.yaml @@ -0,0 +1,84 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: placement-api + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: placement +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "placement.cluster.local" + rules: + - backendRefs: + - name: placement-api + port: 8778 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: metadata-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: nova-metadata +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "metadata.cluster.local" + rules: + - backendRefs: + - name: nova-metadata + port: 8775 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: nova-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: nova +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "nova.cluster.local" + rules: + - backendRefs: + - name: nova-api + port: 8774 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: novnc-gateway-route + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: novnc +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "novnc.cluster.local" + rules: + - backendRefs: + - name: nova-novncproxy + port: 6080 diff --git a/base-kustomize/skyline/base/kustomization.yaml b/base-kustomize/skyline/base/kustomization.yaml index adbc440e..b98ec8f4 100644 --- a/base-kustomize/skyline/base/kustomization.yaml +++ b/base-kustomize/skyline/base/kustomization.yaml @@ -6,3 +6,4 @@ resources: - ingress-apiserver.yaml - hpa-skyline-apiserver.yaml - pdb-apiserver.yaml + - skyline-routes.yaml diff --git a/base-kustomize/skyline/base/skyline-routes.yaml b/base-kustomize/skyline/base/skyline-routes.yaml new file mode 100644 index 00000000..cba783dd --- /dev/null +++ b/base-kustomize/skyline/base/skyline-routes.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: skyline-api + namespace: openstack + labels: + application: gateway-api + service: HTTPRoute + route: skyline +spec: + parentRefs: + - name: flex-gateway + sectionName: cluster-tls + namespace: nginx-gateway + hostnames: + - "skyline.cluster.local" + rules: + - backendRefs: + - name: skyline-apiserver + port: 9999 diff --git a/docs/infrastructure-gateway-api.md b/docs/infrastructure-gateway-api.md index d21da0ef..af99801b 100644 --- a/docs/infrastructure-gateway-api.md +++ b/docs/infrastructure-gateway-api.md @@ -24,84 +24,86 @@ From the gateway api sig: Most Gateway API implementations are API Gateways to some extent, but not all API Gateways are Gateway API implementations. +### Controller Selection + There are various implementations of the Gateway API. In this document, we will cover two of them: -- [NGINX Gateway Fabric](https://github.com/nginxinc/nginx-gateway-fabric) -- [Envoyproxy](https://gateway.envoyproxy.io/) -### Controller: NGINX Gateway Fabric +* [NGINX Gateway Fabric](https://github.com/nginxinc/nginx-gateway-fabric) +* [Envoyproxy](https://gateway.envoyproxy.io/) +=== "NGINX Gateway Fabric" -[NGINX Gateway Fabric](https://github.com/nginxinc/nginx-gateway-fabric) is an open-source project that provides an implementation of the Gateway API using nginx as the data plane. + [NGINX Gateway Fabric](https://github.com/nginxinc/nginx-gateway-fabric) is an open-source project that provides an implementation of the Gateway API using nginx as the data plane. -Chart Install: https://github.com/nginxinc/nginx-gateway-fabric/blob/main/deploy/helm-chart/values.yaml + Chart Install: https://github.com/nginxinc/nginx-gateway-fabric/blob/main/deploy/helm-chart/values.yaml -Create the Namespace -```shell -kubectl create ns nginx-gateway -``` + Create the Namespace + ```shell + kubectl create ns nginx-gateway + ``` -First Install the Gateway API Resource from Kubernetes -```shell -kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml -``` + First Install the Gateway API Resource from Kubernetes + ```shell + kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.3.0" | kubectl apply -f - + ``` -Next, Install the NGINX Gateway Fabric controller -```shell -cd /opt/genestack/submodules/nginx-gateway-fabric/deploy/helm-chart + Next, Install the NGINX Gateway Fabric controller + ```shell + cd /opt/genestack/submodules/nginx-gateway-fabric/deploy/helm-chart -helm upgrade --install nginx-gateway-fabric . --namespace=nginx-gateway -f /opt/genestack/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml -``` - -Helm install does not automatically upgrade the crds for this resource. To upgrade the crds you will have to manually install them. Follow the process from : [Upgrade CRDs](https://docs.nginx.com/nginx-gateway-fabric/installation/installing-ngf/helm/#upgrade-nginx-gateway-fabric-crds) + helm upgrade --install nginx-gateway-fabric . --namespace=nginx-gateway -f /opt/genestack/base-helm-configs/nginx-gateway-fabric/helm-overrides.yaml + ``` -### Controller: Envoyproxy + Helm install does not automatically upgrade the crds for this resource. To upgrade the crds you will have to manually install them. Follow the process from : [Upgrade CRDs](https://docs.nginx.com/nginx-gateway-fabric/installation/installing-ngf/helm/#upgrade-nginx-gateway-fabric-crds) -[Envoyproxy](https://gateway.envoyproxy.io/) is an open-source project that provides an implementation of the Gateway API using Envoyproxy as the data plane. +=== "Envoyproxy" -#### Installation + [Envoyproxy](https://gateway.envoyproxy.io/) is an open-source project that provides an implementation of the Gateway API using Envoyproxy as the data plane. -- Update the `/opt/genestack/base-kustomize/envoyproxy-gateway/base/values.yaml` file according to your requirements. + #### Installation -- Apply the configuration using the following command: + - Update the `/opt/genestack/base-kustomize/envoyproxy-gateway/base/values.yaml` file according to your requirements. -```shell -kubectl kustomize --enable-helm /opt/genestack/base-kustomize/envoyproxy-gateway/base | kubectl apply -f - -``` + - Apply the configuration using the following command: -After installation, you need to create Gateway and HTTPRoute resources based on your requirements. + ```shell + kubectl kustomize --enable-helm /opt/genestack/base-kustomize/envoyproxy-gateway/base | kubectl apply -f - + ``` -### Example to expose an application using Gateway API (Envoyproxy) + After installation, you need to create Gateway and HTTPRoute resources based on your requirements. -- In this example, we will demonstrate how to expose an application through a gateway. + ### Example to expose an application using Gateway API (Envoyproxy) -- Apply the Kustomize configuration which will create `Gateway` resource: + - In this example, we will demonstrate how to expose an application through a gateway. -```shell -kubectl kustomize /opt/genestack/base-kustomize/gateway/envoyproxy | kubectl apply -f - -``` + - Apply the Kustomize configuration which will create `Gateway` resource: -- Once gateway is created, user can expose an application by creating `HTTPRoute` resource. - - Sample `HTTPRoute` resource: - - ```shell - apiVersion: gateway.networking.k8s.io/v1 - kind: HTTPRoute - metadata: - name: test_application - namespace: test_app - spec: - parentRefs: - - name: flex-gateway - sectionName: http - namespace: envoy-gateway-system - hostnames: - - "test_application.sjc.ohthree.com" - rules: - - backendRefs: - - name: test_application - port: 8774 + ```shell + kubectl kustomize /opt/genestack/base-kustomize/gateway/envoyproxy | kubectl apply -f - ``` + - Once gateway is created, user can expose an application by creating `HTTPRoute` resource. + - Sample `HTTPRoute` resource: + + ```shell + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: test_application + namespace: test_app + spec: + parentRefs: + - name: flex-gateway + sectionName: http + namespace: envoy-gateway-system + hostnames: + - "test_application.sjc.ohthree.com" + rules: + - backendRefs: + - name: test_application + port: 8774 + ``` + ### Example Implementation with Prometheus UI (NGINX Gateway Fabric) In this example we will look at how Prometheus UI is exposed through the gateway. For other services the gateway kustomization file for the service. diff --git a/submodules/nginx-gateway-fabric b/submodules/nginx-gateway-fabric index 4e3d9c4b..3a372747 160000 --- a/submodules/nginx-gateway-fabric +++ b/submodules/nginx-gateway-fabric @@ -1 +1 @@ -Subproject commit 4e3d9c4bcc7f65fc2671beffa92ca081644325f6 +Subproject commit 3a372747333fb1db372af7cf0b18ed7eef7c91f7