Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ For a detailed look at the architecture, see [docs/emitters.md](docs/emitters.md
### Supported Providers

* [ingress-nginx](pkg/i2gw/providers/ingressnginx/README.md)

* [gloo-edge](pkg/i2gw/providers/glooedge/README.md)
If your provider, or a specific feature, is not currently supported, please open
an issue and describe your use case.

Expand Down Expand Up @@ -81,6 +81,11 @@ all ingresses from the ingress-nginx provider:
```shell
./ingress2gateway print --providers=ingress-nginx --emitter=kgateway
```
to convert Gloo Edge VirtualService

```shell
./ingress2gateway print --providers=gloo-edge --emitter=kgateway
```

The above command will:

Expand Down Expand Up @@ -113,7 +118,7 @@ The above command will:
| input-file | | No | Path to the manifest file. When set, the tool will read ingresses from the file instead of reading from the cluster. Supported files are yaml and json. |
| namespace | | No | If present, the namespace scope for the invocation. |
| output | yaml | No | The output format, either yaml or json. |
| providers | | Yes | Comma-separated list of providers (only ingress-nginx is supported in this downstream). |
| providers | | Yes | Comma-separated list of providers (ingress-nginx and Gloo-edge is supported). |
| emitter | standard | No | The emitter to use for generating Gateway API resources (supported values: standard, kgateway). |
| kubeconfig | | No | The kubeconfig file to use when talking to the cluster. If the flag is not set, a set of standard locations can be searched for an existing kubeconfig file. |

Expand All @@ -135,20 +140,30 @@ one that sorted later.
Since the Ingress v1 spec does not itself have a conflict resolution guide, we have
adopted this one. These rules are similar to the [Gateway API conflict resolution
guidelines](https://gateway-api.sigs.k8s.io/concepts/guidelines/#conflicts).
# Provider-Specific Conversions

### Ingress resource fields to Gateway API fields
## Ingress-Nginx

Given a set of Ingress resources, `ingress2gateway` will generate a Gateway with
various HTTP and HTTPS Listeners as well as HTTPRoutes that should represent equivalent
routing rules.
Ingress resources will be converted to Gateway API resources as follows:

| Ingress Field | Gateway API configuration |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ingressClassName` | If configured on an Ingress resource, this value will be translated to `kgateway`. |
| `ingressClassName` | If configured on an Ingress resource, this value will be translated to the corresponding Gateway class. |
| `defaultBackend` | If present, this configuration will generate a Gateway Listener with no `hostname` specified as well as a catchall HTTPRoute that references this listener. The backend specified here will be translated to a HTTPRoute `rules[].backendRefs[]` element. |
| `tls[].hosts` | Each host in an IngressTLS will result in a HTTPS Listener on the generated Gateway with the following: `listeners[].hostname` = host as described, `listeners[].port` = `443`, `listeners[].protocol` = `HTTPS`, `listeners[].tls.mode` = `Terminate` |
| `tls[].secretName` | The secret specified here will be referenced in the Gateway HTTPS Listeners mentioned above with the field `listeners[].tls.certificateRefs`. Each Listener for each host in an IngressTLS will get this secret. |
| `rules[].host` | If non-empty, each distinct value for this field in the provided Ingress resources will result in a separate Gateway HTTP Listener with matching `listeners[].hostname`. `listeners[].port` will be set to `80` and `listeners[].protocol` set to `HTTPS`. In addition, Ingress rules with the same hostname will generate HTTPRoute rules in a HTTPRoute with `hostnames` containing it as the single element. If empty, similar to the `defaultBackend`, a Gateway Listener with no hostname configuration will be generated (if it doesn't exist) and routing rules will be generated in a catchall HTTPRoute. |
| `rules[].http.paths[].path` | This field translates to a HTTPRoute `rules[].matches[].path.value` configuration. |
| `rules[].http.paths[].pathType` | This field translates to a HTTPRoute `rules[].matches[].path.type` configuration. Ingress `Exact` = HTTPRoute `Exact` match. Ingress `Prefix` = HTTPRoute `PathPrefix` match. |
| `rules[].http.paths[].backend` | The backend specified here will be translated to a HTTPRoute `rules[].backendRefs[]` element. |
| `rules[].host` | If non-empty, each distinct value for this field in the provided Ingress resources will result in a separate Gateway HTTP Listener with matching `listeners[].hostname`. `listeners[].port` will be set to `80` and `listeners[].protocol` set to `HTTP`. In addition, Ingress rules with the same hostname will generate HTTPRoute rules in a HTTPRoute with `hostnames` containing it as the single element. If empty, similar to the `defaultBackend`, a Gateway Listener with no hostname configuration will be generated (if it doesn't exist) and routing rules will be generated in a catchall HTTPRoute. |
| `rules[].http.paths[].path` | This field translates to a HTTPRoute `rules[].matches[].path.value` configuration. |
| `rules[].http.paths[].pathType` | This field translates to a HTTPRoute `rules[].matches[].path.type` configuration. Ingress `Exact` = HTTPRoute `Exact` match. Ingress `Prefix` = HTTPRoute `PathPrefix` match. |
| `rules[].http.paths[].backend` | The backend specified here will be translated to a HTTPRoute `rules[].backendRefs[]` element. |

## Gloo Edge

Gloo Edge VirtualServices will be converted to Gateway API resources as follows:

| VirtualService Field | Gateway API configuration |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec.hosts` | Each host in the VirtualService hosts list will result in a separate Gateway HTTP Listener with matching `listeners[].hostname`. `listeners[].port` will be set to `80` and `listeners[].protocol` set to `HTTP`. HTTPRoute resources will be created with `hostnames` containing the corresponding host as the single element. |
| `spec.virtualHost.routes[].matchers[].prefix` | This field translates to a HTTPRoute `rules[].matches[].path.value` configuration with `type` set to `PathPrefix`. |
| `spec.virtualHost.routes[].routeAction.single.upstream` | The upstream specified here will be translated to a HTTPRoute `rules[].backendRefs[]` element with the upstream name as the backend Service name. |
| `spec.virtualHost.routes[].routeAction.single.upstream.port` | The port specified on the upstream will be translated to the HTTPRoute backend ref `port` field. |
1 change: 1 addition & 0 deletions cmd/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (

// Call init function for the providers
_ "github.com/kgateway-dev/ingress2gateway/pkg/i2gw/providers/ingressnginx"
_ "github.com/kgateway-dev/ingress2gateway/pkg/i2gw/providers/glooedge"

// Call init for emitters
_ "github.com/kgateway-dev/ingress2gateway/pkg/i2gw/emitters/agentgateway"
Expand Down
46 changes: 46 additions & 0 deletions examples/glooedge/multi-namespace-virtualservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: prod-api-vs
namespace: production
spec:
virtualHost:
domains:
- api.production.example.com
routes:
- matchers:
- prefix: /users
routeAction:
single:
upstream:
name: user-service
namespace: production
- matchers:
- prefix: /orders
routeAction:
single:
upstream:
name: order-service
namespace: production
---
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: user-service
namespace: production
spec:
kube:
serviceName: users-api
serviceNamespace: production
servicePort: 9090
---
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: order-service
namespace: production
spec:
kube:
serviceName: orders-api
serviceNamespace: production
servicePort: 9091
47 changes: 47 additions & 0 deletions examples/glooedge/real-virtualservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: petstore-vs
namespace: default
spec:
virtualHost:
domains:
- petstore.example.com
- api.petstore.example.com
routes:
- matchers:
- prefix: /api/v1
routeAction:
single:
upstream:
name: petstore-api
namespace: default
- matchers:
- prefix: /swagger
routeAction:
single:
upstream:
name: swagger-ui
namespace: default
---
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: petstore-api
namespace: default
spec:
kube:
serviceName: petstore
serviceNamespace: default
servicePort: 8080
---
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: swagger-ui
namespace: default
spec:
kube:
serviceName: swagger
serviceNamespace: default
servicePort: 3000
17 changes: 17 additions & 0 deletions examples/glooedge/test_virtualservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: example-vs
namespace: default
spec:
hosts:
- example.com
virtualHost:
routes:
- matchers:
- prefix: /api
routeAction:
single:
upstream:
name: my-service
namespace: default
47 changes: 47 additions & 0 deletions examples/glooedge/upstream-fixture.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: petstore-api
namespace: default
spec:
kube:
serviceName: petstore-api
serviceNamespace: default
servicePort: 8080
---
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: swagger-ui
namespace: default
spec:
kube:
serviceName: swagger-ui
serviceNamespace: default
servicePort: 3000
---
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: petstore-vs
namespace: default
spec:
virtualHost:
domains:
- api.petstore.example.com
- petstore.example.com
routes:
- matchers:
- prefix: /api/v1
routeAction:
single:
upstream:
name: petstore-api
namespace: default
- matchers:
- prefix: /swagger
routeAction:
single:
upstream:
name: swagger-ui
namespace: default
Loading