diff --git a/provider.md b/PROVIDER.md similarity index 100% rename from provider.md rename to PROVIDER.md diff --git a/README.md b/README.md index 460e6ca7..3303a4d9 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ # Ingress to Gateway -This project helps translate Ingress resources to Gateway API resources, -specifically HTTPRoutes. This project is managed by the [Gateway +Ingress2gateway helps translate Ingress resources to Gateway API resources, +specifically HTTPRoutes. Ingress2gateway is managed by the [Gateway API](https://gateway-api.sigs.k8s.io/) SIG-Network subproject. -## Status - -This project is early in the development phase and is still experimental in -nature. Both bugs and breaking changes are likely. - ## Scope -This project is primarily focused on translating Ingress resources to Gateway -API resources. Some widely used annotations and/or CRDs _may_ be supported, as -long as they can be translated to Gateway API directly. This project is not -intended to copy annotations from Ingress to Gateway API. +Ingress2gateway is primarily focused on translating Ingress and provider-specific +resources(CRDs) to Gateway API resources. Widely used provider-specific annotations +and/or CRDs _may_ still not be supported. Please refer to +[supported providers](#current-supported-providers) for the current supported +providers and their documentation. Contributions for provider-specific +annotations and/or CRDs support are mostly welcomed as long as they can be +translated to [Gateway API](https://gateway-api.sigs.k8s.io/) directly. + +Note: Ingress2gateway is not intended to copy annotations from Ingress to Gateway API. ## Build from Source @@ -34,15 +34,27 @@ make build ## Usage -This project reads Ingress resources from a Kubernetes cluster based on your -current Kube Config. It will output YAML for equivalent Gateway API resources -to stdout. Until this project is released, the best way to use this is to run -the following within the repo: +Ingress2gateway reads Ingress resources and/or provider-specifc CRDs from a Kubernetes cluster or a file. It will output the equivalent Gateway API resources in a YAML/JSON format +to stdout. To run ingress2gateway with default options simply run: ``` -go run . print +ingress2gateway print ``` +This above command will: +1. Read your Kube config file to extract the cluster credentials and the current active namespace. +2. Search for ingresses and provider-specific resources in that namespace. +3. Convert them to Gateway-API resources (Currently only Gateways and HTTPRoutes). + +## Options + +| Flag | Default Value | Required | Description | +| ----------------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| namespace | | No | If present, the namespace scope for the invocation | +| all-namespaces | False | No | If present, list the requested object(s) across all namespaces. Namespace in the current context is ignored even if specified with --namespace | +| output | yaml | No | The output format, either yaml or json | +| 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 | + ## Conversion of Ingress resources to Gateway API ### Processing Order and Conflicts @@ -61,35 +73,29 @@ These rules are similar to the [Gateway API conflict resolution guidelines](http 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 Field | Gateway API configuration | -|---------------|---------------------------| -| `ingressClassName` | If configured on an Ingress resource, this value will be used as the `gatewayClassName` set on the corresponding generated Gateway. | -| `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. | +| Ingress Field | Gateway API configuration | +| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ingressClassName` | If configured on an Ingress resource, this value will be used as the `gatewayClassName` set on the corresponding generated Gateway. `kubernetes.io/ingress.class` annotation has the same behavior. | +| `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. | + +### Provider-Specific Support -### Implementation-Specific Annotations +Ingress2gateway also supports translating provider-specific resources and ingress annotations to Gateway-API resources. -Although most annotations are ignored, this project includes experimental -support for the following annotations: +#### Current supported providers: -* kubernetes.io/ingress.class: Same behavior as the `ingressClassName` field above, if specified this value will be used as the `gatewayClassName` set on the corresponding generated Gateway. +- [ingress-nginx](pkg/i2gw/providers/ingressnginx/README.md) -#### ingress-nginx: +If your provider, or a specific feature, is not currently supported, please open an issue and describe your use case. -* nginx.ingress.kubernetes.io/canary: If set to `true` will enable weighting backends. -* nginx.ingress.kubernetes.io/canary-by-header: If specified, the value of this annotation is the header name that will be added as a HTTPHeaderMatch for the routes generated from this Ingress. If not specified, no HTTPHeaderMatch will be generated. -* nginx.ingress.kubernetes.io/canary-by-header-value: If specified, the value of this annotation is the header value to perform an `HeaderMatchExact` match on in the generated HTTPHeaderMatch. -* nginx.ingress.kubernetes.io/canary-by-header-pattern: If specified, this is the pattern to match against for the HTTPHeaderMatch, which will be of type `HeaderMatchRegularExpression`. -* nginx.ingress.kubernetes.io/canary-weight: If specified and non-zero, this value will be applied as the weight of the backends for the routes generated from this Ingress resource. -* nginx.ingress.kubernetes.io/canary-weight-total +To contribute a new provider support - please read [PROVIDER.md](PROVIDER.md). -If you are reliant on any annotations not listed above, you'll need to manually -find a Gateway API equivalent. ## Get Involved diff --git a/pkg/i2gw/providers/ingressnginx/README.md b/pkg/i2gw/providers/ingressnginx/README.md new file mode 100644 index 00000000..ab8863e5 --- /dev/null +++ b/pkg/i2gw/providers/ingressnginx/README.md @@ -0,0 +1,15 @@ +# Ingress Nginx Provider + +The project supports translating ingress-nginx specific annotations. + +Current supported annotations: + +- `nginx.ingress.kubernetes.io/canary`: If set to true will enable weighting backends. +- `nginx.ingress.kubernetes.io/canary-by-header`: If specified, the value of this annotation is the header name that will be added as a HTTPHeaderMatch for the routes +- generated from this Ingress. If not specified, no HTTPHeaderMatch will be generated. +- `nginx.ingress.kubernetes.io/canary-by-header-value`: If specified, the value of this annotation is the header value to perform an HeaderMatchExact match on in the generated HTTPHeaderMatch. +- `nginx.ingress.kubernetes.io/canary-by-header-pattern`: If specified, this is the pattern to match against for the HTTPHeaderMatch, which will be of type HeaderMatchRegularExpression. +- `nginx.ingress.kubernetes.io/canary-weight`: If specified and non-zero, this value will be applied as the weight of the backends for the routes generated from this Ingress resource. +`nginx.ingress.kubernetes.io/canary-weight-total` + +If you are reliant on any annotations not listed above, please open an issue. In the meantime you'll need to manually find a Gateway API equivalent. \ No newline at end of file