Test resources
You can use the Kubernetes dry run capability to verify your resource configuration or send requests directly to the K8sGateway validation API.
Warning
state. To enable these settings, update your K8sGateway installation and include --set gateway.validation.alwaysAcceptResources=false
, --set gateway.validation.enabled=true
, and --set gateway.validation.allowWarnings=false
. You can also edit the Settings resource directly. For more information, see Enable strict resource validation.
Use the dry run capability in Kubernetes
To test whether a YAML file is accepted by the validation webhook, you can use the kubectl apply --dry-run=server
command as shown in the following examples.
Try to create a RouteOption with an invalid fault injection configuration and verify that your resource is denied by the validation API. The following example is missing the required HTTP status code field that is returned when the request is aborted.
kubectl apply -n httpbin --dry-run=server -f- <<EOF
apiVersion: gateway.solo.io/v1
kind: RouteOption
metadata:
name: faults
namespace: httpbin
spec:
options:
faults:
abort:
percentage: 50
# httpStatus: 503
EOF
Example output:
Error from server: error when creating "STDIN": admission webhook "gloo.gloo-system.svc" denied the request: resource incompatible with current Gloo snapshot: [Validating *v1.RouteOption failed: 1 error occurred:
* Validating *v1.RouteOption failed: validating *v1.RouteOption name:"faults" namespace:"httpbin": 1 error occurred:
* Route Error: ProcessingError. Reason: *faultinjection.plugin: invalid abort status code '0', must be in range of [200,600). Route Name:
Try to create a VirtualHostOption resource with an invalid retry policy. In the following example, the baseInterval
is greater than the maxInterval
. Verify that the configuration is rejected.
kubectl apply --dry-run=server -f- <<EOF
apiVersion: gateway.solo.io/v1
kind: VirtualHostOption
metadata:
name: bad-retries
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: http
sectionName: http
options:
retries:
retryOn: "5xx"
retryBackOff:
# An error is expected when the baseInterval is greater than the maxInterval
baseInterval: "1s"
maxInterval: "1ms"
EOF
Example output:
Error from server: error when creating "STDIN": admission webhook "gloo.gloo-system.svc" denied the request: resource incompatible with current Gloo snapshot: [Validating *v1.VirtualHostOption failed: 1 error occurred:
* Validating *v1.VirtualHostOption failed: validating *v1.VirtualHostOption name:"bad-retries" namespace:"default": 1 error occurred:
* VirtualHost Error: ProcessingError. Reason: invalid virtual host [vhost] while processing plugin basic_route: base interval: 1000 is > max interval: 1
Send requests to the validation API directly
Send a curl request to the validation API to test your resource configurations. For an overview of the fields that you must include as part of your request, see Validation API reference.
{}
is returned from the validation API, you might need to add or remove a bracket from your request. This response is returned also if the wrong bracket type is used, such as when you used {}
instead of []
.
-
Port-forward the gloo service on port 8443.
kubectl -n gloo-system port-forward service/gloo 8443:443
-
Send a request with your resource configuration to the K8sGateway validation API. The following example shows successful and unsuccessful resource configuration validation for the RouteOption and VirtualHostOption resources.
The following RouteOption resource configures an invalid fault injection policy that aborts 50% of all traffic. The configuration is missing an HTTP status code.
apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: faults namespace: httpbin spec: options: faults: abort: percentage: 50 # httpStatus: 503
-
Send a request to the validation API and pass in the invalid RouteOption configuration. Verify that the configuration is rejected.
curl -k -XPOST -d '{"request":{"uid":"1234","kind":{"group":"gateway.solo.io","version":"v1","kind":"RouteOption"},"resource":{"group":"","version":"","resource":""},"name":"faults","namespace":"httpbin","operation":"CREATE","userInfo":{},"object": { "apiVersion": "gateway.solo.io/v1", "kind": "RouteOption", "metadata": { "name": "faults", "namespace": "httpbin" }, "spec": { "options": { "faults": { "abort": { "percentage": "50" } }}}}}}' \ -H 'Content-Type: application/json' https://localhost:8443/validation
Example output:
{"response":{"uid":"1234","allowed":false,"status":{"metadata":{},"message":"resource incompatible with current Gloo snapshot: [Validating *v1.RouteOption failed: 1 error occurred:\n\t* Validating *v1.RouteOption failed: validating *v1.RouteOption name:\"faults\" namespace:\"httpbin\": 1 error occurred:\n\t* Route Error: ProcessingError. Reason: *faultinjection.plugin: invalid abort status code '0', must be in range of [200,600). Route Name: \n\n\n\n]","details":{"name":"faults","group":"gateway.solo.io","kind":"RouteOption","causes":[{"message":"Error Validating *v1.RouteOption failed: 1 error occurred:\n\t* Validating *v1.RouteOption failed: validating *v1.RouteOption name:\"faults\" namespace:\"httpbin\": 1 error occurred:\n\t* Route Error: ProcessingError. Reason: *faultinjection.plugin: invalid abort status code '0', must be in range of [200,600). Route Name: \n\n\n\n"}]}}}}
-
Add the HTTP status code field to the RouteOption configuration (
"httpStatus": "503"
). Verify that the configuration is accepted.curl -k -XPOST -d '{"request":{"uid":"1234","kind":{"group":"gateway.solo.io","version":"v1","kind":"RouteOption"},"resource":{"group":"","version":"","resource":""},"name":"faults","namespace":"httpbin","operation":"CREATE","userInfo":{},"object": { "apiVersion": "gateway.solo.io/v1", "kind": "RouteOption", "metadata": { "name": "faults", "namespace": "httpbin" }, "spec": { "options": { "faults": { "abort": { "percentage": "50", "httpStatus": "503" } }}}}}}' \ -H 'Content-Type: application/json' https://localhost:8443/validation
Example output for successful validation:
{"response":{"uid":"1234","allowed":true}}
The following VirtualHostOption resource configures an invalid retry policy that sets a
maxInterval
that is smaller than thebaseInterval
.apiVersion: gateway.solo.io/v1 kind: VirtualHostOption metadata: name: bad-retries namespace: httpbin spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http sectionName: http options: retries: retryOn: "5xx" retryBackOff: # An error is expected when the maxInterval is smaller than the baseInterval baseInterval: "1s" maxInterval: "1ms"
-
Send a request to the validation API and pass in the invalid VirtualHostOption configuration. Verify that the configuration is rejected.
curl -k -XPOST -d '{"request":{"uid":"1234","kind":{"group":"gateway.solo.io","version":"v1","kind":"VirtualHostOption"},"resource":{"group":"","version":"","resource":""},"name":"bad-retries","namespace":"httpbin","operation":"CREATE","userInfo":{},"object": { "apiVersion": "gateway.solo.io/v1", "kind": "VirtualHostOption", "metadata": { "name": "bad-retries", "namespace": "httpbin" }, "spec": { "targetRefs": [{ "group": "gateway.networking.k8s.io", "kind": "Gateway", "name": "http", "sectionName": "http" }], "options": { "retries": { "retryOn": "5xx", "retryBackOff": { "baseInterval": "1s", "maxInterval":"1ms"} } }}}}}' \ -H 'Content-Type: application/json' https://localhost:8443/validation
Example output:
{"response":{"uid":"1234","allowed":false,"status":{"metadata":{},"message":"resource incompatible with current Gloo snapshot: [Validating *v1.VirtualHostOption failed: 1 error occurred:\n\t* Validating *v1.VirtualHostOption failed: validating *v1.VirtualHostOption name:\"bad-retries\" namespace:\"httpbin\": 1 error occurred:\n\t* VirtualHost Error: ProcessingError. Reason: invalid virtual host [vhost] while processing plugin basic_route: base interval: 1000 is \u003e max interval: 1\n\n\n\n]","details":{"name":"bad-retries","group":"gateway.solo.io","kind":"VirtualHostOption","causes":[{"message":"Error Validating *v1.VirtualHostOption failed: 1 error occurred:\n\t* Validating *v1.VirtualHostOption failed: validating *v1.VirtualHostOption name:\"bad-retries\" namespace:\"httpbin\": 1 error occurred:\n\t* VirtualHost Error: ProcessingError. Reason: invalid virtual host [vhost] while processing plugin basic_route: base interval: 1000 is \u003e max interval: 1\n\n\n\n"}]}}}}%
-
Change the
maxInterval
to an invalid value, such as5
("maxInterval":"5"
). This value is missing the time unit. Verify that the configuration is rejected.curl -k -XPOST -d '{"request":{"uid":"1234","kind":{"group":"gateway.solo.io","version":"v1","kind":"VirtualHostOption"},"resource":{"group":"","version":"","resource":""},"name":"bad-retries","namespace":"httpbin","operation":"CREATE","userInfo":{},"object": { "apiVersion": "gateway.solo.io/v1", "kind": "VirtualHostOption", "metadata": { "name": "bad-retries", "namespace": "httpbin" }, "spec": { "targetRefs": [{ "group": "gateway.networking.k8s.io", "kind": "Gateway", "name": "http", "sectionName": "http" }], "options": { "retries": { "retryOn": "5xx", "retryBackOff": { "baseInterval": "1s", "maxInterval":"5"} } }}}}}' \ -H 'Content-Type: application/json' https://localhost:8443/validation
Example output:
{"response":{"uid":"1234","allowed":false,"status":{"metadata":{},"message":"resource incompatible with current Gloo snapshot: [1 error occurred:\n\t* could not unmarshal raw object: parsing resource from crd spec bad-retries in namespace httpbin into *v1.VirtualHostOption: bad Duration: time: missing unit in duration \"5\"\n\n]","details":{"name":"bad-retries","group":"gateway.solo.io","kind":"VirtualHostOption","causes":[{"message":"Error 1 error occurred:\n\t* could not unmarshal raw object: parsing resource from crd spec bad-retries in namespace httpbin into *v1.VirtualHostOption: bad Duration: time: missing unit in duration \"5\"\n\n"}]}}}}%
-
Change the
maxInterval
to a value that is greater than thebaseInterval
, such as5s
("maxInterval":"5s"
). Verify that your configuration is now accepted.curl -k -XPOST -d '{"request":{"uid":"1234","kind":{"group":"gateway.solo.io","version":"v1","kind":"VirtualHostOption"},"resource":{"group":"","version":"","resource":""},"name":"bad-retries","namespace":"httpbin","operation":"CREATE","userInfo":{},"object": { "apiVersion": "gateway.solo.io/v1", "kind": "VirtualHostOption", "metadata": { "name": "bad-retries", "namespace": "httpbin" }, "spec": { "targetRefs": [{ "group": "gateway.networking.k8s.io", "kind": "Gateway", "name": "http", "sectionName": "http" }], "options": { "retries": { "retryOn": "5xx", "retryBackOff": { "baseInterval": "1s", "maxInterval":"5s"} } }}}}}' \ -H 'Content-Type: application/json' https://localhost:8443/validation
Example output:
{"response":{"uid":"1234","allowed":true}}%
-
Validation API reference
The K8sGateway validation API is implemented as a validating admission webhook in Kubernetes with the following sample JSON structure:
{
"request": {
"uid": "12345",
"kind": {
"group": "gateway.solo.io",
"version": "v1",
"kind": "RouteOption"
},
"resource": {
"group": "",
"version": "",
"resource": ""
},
"name": "vs-dry-run",
"namespace": "gloo-system",
"operation": "CREATE",
"userInfo": {
"username": "system:serviceaccount:kube-system:my-serviceaccount",
"uid": "system:serviceaccount:kube-system:my-serviceaccount"
},
"object": {
// The resource configuration that you want to validate in JSON format.
}
Parameter | Type | Required | Description |
---|---|---|---|
request.uid |
String | No | A unique identifier for the validation request. You can use this field to find the validation output for a specific resource more easily. |
request.kind |
Object | Yes | Information about the type of Kubernetes object that is involved in the validation request. The following fields can be defined:
rules section in the K8sGateway validating admission webhook configuration. |
request.resource |
Object | Yes | Information about the resource that is admitted to the webhook. In most cases, the resource defined in request.kind and request.resource is the same. They might differ only when changes in API versions or variations in resource naming were introduced, or if the resource that you admit belongs to a subresource. If this is the case, you must include the request.resource field in your request to the validation API. If request.kind and request.resource are the same, the request.resource section can be omitted. The following fields can be defined:
|
request.name |
String | No | The name of the resource that you want to validate. |
request.namespace |
String | No | The namespace where you want to create, update, or delete the resource. |
request.operation |
String | Yes | The operation in Kubernetes that you want to use for your resource. The operation that you can set depends on the resource that you want to validate. You can find supported operations in the rules section in the K8sGateway validating admission webhook configuration. |
request.userInfo |
Object | No | Information about the user that sends the validation request. The following fields can be provided:
|
request.object |
Object | Yes | The resource configuration that you want to validate, such as a RouteOption or VirtualHostOption, in JSON format. Refer to the API reference for more information about the fields that you can set for each resource. |