From 2528641169f48f1726f863a74f76accd0a88820d Mon Sep 17 00:00:00 2001 From: Ignas Baranauskas Date: Wed, 11 Oct 2023 16:44:33 +0100 Subject: [PATCH] Policy attachment metrics --- config/default/custom-resource-state.yaml | 108 +++- config/examples/dashboards/policies.json | 307 +++++++++++ config/examples/dashboards/policies.yaml | 10 + config/examples/enterprise/all.yaml | 90 ++++ config/examples/kube-prometheus/bundle.yaml | 120 +++++ .../grafana_deployment_patch.yaml | 12 + .../ksm_clusterrole_patch.yaml | 11 + .../kube-state-metrics/cluster-role.yaml | 8 + ....networking.k8s.io_backendtlspolicies.yaml | 490 ++++++++++++++++++ .../kuadrant.io_ratelimitpolicies.yaml | 397 ++++++++++++++ .../crd/standard/kuadrant.io_tlspolicies.yaml | 313 +++++++++++ src/dashboards/lib/gwapi/gwapi.libsonnet | 23 + src/dashboards/policies.jsonnet | 18 + 13 files changed, 1906 insertions(+), 1 deletion(-) create mode 100644 config/examples/dashboards/policies.json create mode 100644 config/examples/dashboards/policies.yaml create mode 100644 config/gateway-api/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml create mode 100644 config/gateway-api/crd/standard/kuadrant.io_ratelimitpolicies.yaml create mode 100644 config/gateway-api/crd/standard/kuadrant.io_tlspolicies.yaml create mode 100644 src/dashboards/policies.jsonnet diff --git a/config/default/custom-resource-state.yaml b/config/default/custom-resource-state.yaml index fd8c479..382ea95 100644 --- a/config/default/custom-resource-state.yaml +++ b/config/default/custom-resource-state.yaml @@ -457,4 +457,110 @@ spec: parent_name: ["parentRef", "name"] parent_namespace: ["parentRef", "namespace"] parent_section_name: ["parentRef", "sectionName"] - parent_port: ["parentRef", "port"] \ No newline at end of file + parent_port: ["parentRef", "port"] + - groupVersionKind: + group: kuadrant.io + kind: "TLSPolicy" + version: "v1alpha1" + metricNamePrefix: gatewayapi_tlspolicy + labelsFromPath: + name: + - metadata + - name + namespace: + - metadata + - namespace + metrics: + - name: "labels" + help: "Kubernetes labels converted to Prometheus labels." + each: + type: Info + info: + path: [metadata] + labelsFromPath: + "*": [labels] + - name: "created" + help: "created timestamp" + each: + type: Gauge + gauge: + path: [metadata, creationTimestamp] + - name: "deleted" + help: "deletion timestamp" + each: + type: Gauge + gauge: + path: [metadata, deletionTimestamp] + - name: "target_info" + help: "Target references that the tlspolicy wants to be attached to" + each: + type: Info + info: + path: [spec, targetRef] + labelsFromPath: + target_group: ["group"] + target_kind: ["kind"] + target_name: ["name"] + target_namespace: ["namespace"] + - name: "status" + help: "status condition" + each: + type: Gauge + gauge: + path: [status, conditions] + labelsFromPath: + type: ["type"] + valueFrom: ["status"] + - groupVersionKind: + group: kuadrant.io + kind: "RateLimitPolicy" + version: "v1beta2" + metricNamePrefix: gatewayapi_ratelimitpolicy + labelsFromPath: + name: + - metadata + - name + namespace: + - metadata + - namespace + metrics: + - name: "labels" + help: "Kubernetes labels converted to Prometheus labels." + each: + type: Info + info: + path: [metadata] + labelsFromPath: + "*": [labels] + - name: "created" + help: "created timestamp" + each: + type: Gauge + gauge: + path: [metadata, creationTimestamp] + - name: "deleted" + help: "deletion timestamp" + each: + type: Gauge + gauge: + path: [metadata, deletionTimestamp] + - name: "target_info" + help: "Target references that the tlspolicy wants to be attached to" + each: + type: Info + info: + path: [spec, targetRef] + labelsFromPath: + target_group: ["group"] + target_kind: ["kind"] + target_name: ["name"] + target_namespace: ["namespace"] + - name: "status" + help: "status condition" + each: + type: Gauge + gauge: + path: [status, conditions] + labelsFromPath: + type: ["type"] + valueFrom: ["status"] \ No newline at end of file diff --git a/config/examples/dashboards/policies.json b/config/examples/dashboards/policies.json new file mode 100644 index 0000000..0c0d6d6 --- /dev/null +++ b/config/examples/dashboards/policies.json @@ -0,0 +1,307 @@ +{ + "editable": false, + "links": [ + { + "asDropdown": false, + "includeVars": true, + "keepTime": true, + "tags": [ + "gateway-api-state" + ], + "targetBlank": false, + "title": "Gateway Dashboards", + "type": "dashboards" + } + ], + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "title": "TLSPolicy", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "Total number of TLSPolicy across all clusters", + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 1 + }, + "id": 2, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(gatewayapi_tlspolicy_status)", + "instant": true + } + ], + "title": "Total", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "Total TLSPolicy with an Ready state", + "gridPos": { + "h": 3, + "w": 2, + "x": 0, + "y": 2 + }, + "id": 3, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(gatewayapi_tlspolicy_status{type=\"Ready\"})", + "instant": true + } + ], + "title": "Ready", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "gridPos": { + "h": 6, + "w": 10, + "x": 4, + "y": 1 + }, + "id": 4, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "gatewayapi_tlspolicy_target_info", + "format": "table", + "instant": true, + "range": false + } + ], + "title": "TLSPolicy", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": [ + "name", + "target_kind", + "target_name" + ] + } + } + }, + { + "id": "organize", + "options": { + "renameByName": { + "name": "Name", + "target_kind": "Target Kind", + "target_name": "Target Name" + } + } + } + ], + "type": "table" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 5, + "title": "RateLimitPolicy", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "Total number of RateLimitPolicy across all clusters", + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 3 + }, + "id": 6, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(gatewayapi_ratelimitpolicy_status)", + "instant": true + } + ], + "title": "Total", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "description": "Total RateLimitPolicy with an Ready state", + "gridPos": { + "h": 3, + "w": 2, + "x": 0, + "y": 4 + }, + "id": 7, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "count(gatewayapi_ratelimitpolicy_status{type=\"Ready\"})", + "instant": true + } + ], + "title": "Ready", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "gridPos": { + "h": 6, + "w": 10, + "x": 4, + "y": 7 + }, + "id": 8, + "pluginVersion": "v10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "gatewayapi_ratelimitpolicy_target_info", + "format": "table", + "instant": true, + "range": false + } + ], + "title": "RateLimitPolicy", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": [ + "name", + "target_kind", + "target_name" + ] + } + } + }, + { + "id": "organize", + "options": { + "renameByName": { + "name": "Name", + "target_kind": "Target Kind", + "target_name": "Target Name" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 36, + "style": "dark", + "tags": [ + "gateway-api", + "gateway-api-state" + ], + "templating": { + "list": [ + { + "label": "Data Source", + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "label": "TLSPolicy", + "multi": true, + "name": "tlspolicy", + "query": { + "query": "label_values(gatewayapi_tlspolicy_created, name)", + "refId": "StandardVariableQuery" + }, + "regex": "/(.*)/", + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "includeAll": true, + "label": "RateLimitPolicy", + "multi": true, + "name": "ratelimitpolicy", + "query": { + "query": "label_values(gatewayapi_ratelimitpolicy_created, name)", + "refId": "StandardVariableQuery" + }, + "regex": "/(.*)/", + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Gateway API State / Policies", + "uid": "gatewayapipolicies" +} diff --git a/config/examples/dashboards/policies.yaml b/config/examples/dashboards/policies.yaml new file mode 100644 index 0000000..fe48e12 --- /dev/null +++ b/config/examples/dashboards/policies.yaml @@ -0,0 +1,10 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: GrafanaDashboard +metadata: + name: policies +spec: + instanceSelector: + matchLabels: + dashboards: "grafana" + json: > + {"editable":false,"links":[{"asDropdown":false,"includeVars":true,"keepTime":true,"tags":["gateway-api-state"],"targetBlank":false,"title":"Gateway Dashboards","type":"dashboards"}],"panels":[{"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":1,"title":"TLSPolicy","type":"row"},{"datasource":{"type":"prometheus","uid":"$datasource"},"description":"Total number of TLSPolicy across all clusters","gridPos":{"h":3,"w":4,"x":0,"y":1},"id":2,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"count(gatewayapi_tlspolicy_status)","instant":true}],"title":"Total","type":"stat"},{"datasource":{"type":"prometheus","uid":"$datasource"},"description":"Total TLSPolicy with an Ready state","gridPos":{"h":3,"w":2,"x":0,"y":2},"id":3,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"count(gatewayapi_tlspolicy_status{type=\"Ready\"})","instant":true}],"title":"Ready","type":"stat"},{"datasource":{"type":"prometheus","uid":"$datasource"},"gridPos":{"h":6,"w":10,"x":4,"y":1},"id":4,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"gatewayapi_tlspolicy_target_info","format":"table","instant":true,"range":false}],"title":"TLSPolicy","transformations":[{"id":"filterFieldsByName","options":{"include":{"names":["name","target_kind","target_name"]}}},{"id":"organize","options":{"renameByName":{"name":"Name","target_kind":"Target Kind","target_name":"Target Name"}}}],"type":"table"},{"gridPos":{"h":1,"w":24,"x":0,"y":2},"id":5,"title":"RateLimitPolicy","type":"row"},{"datasource":{"type":"prometheus","uid":"$datasource"},"description":"Total number of RateLimitPolicy across all clusters","gridPos":{"h":3,"w":4,"x":0,"y":3},"id":6,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"count(gatewayapi_ratelimitpolicy_status)","instant":true}],"title":"Total","type":"stat"},{"datasource":{"type":"prometheus","uid":"$datasource"},"description":"Total RateLimitPolicy with an Ready state","gridPos":{"h":3,"w":2,"x":0,"y":4},"id":7,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"count(gatewayapi_ratelimitpolicy_status{type=\"Ready\"})","instant":true}],"title":"Ready","type":"stat"},{"datasource":{"type":"prometheus","uid":"$datasource"},"gridPos":{"h":6,"w":10,"x":4,"y":7},"id":8,"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"gatewayapi_ratelimitpolicy_target_info","format":"table","instant":true,"range":false}],"title":"RateLimitPolicy","transformations":[{"id":"filterFieldsByName","options":{"include":{"names":["name","target_kind","target_name"]}}},{"id":"organize","options":{"renameByName":{"name":"Name","target_kind":"Target Kind","target_name":"Target Name"}}}],"type":"table"}],"schemaVersion":36,"style":"dark","tags":["gateway-api","gateway-api-state"],"templating":{"list":[{"label":"Data Source","name":"datasource","query":"prometheus","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"includeAll":true,"label":"TLSPolicy","multi":true,"name":"tlspolicy","query":{"query":"label_values(gatewayapi_tlspolicy_created, name)","refId":"StandardVariableQuery"},"regex":"/(.*)/","type":"query"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"includeAll":true,"label":"RateLimitPolicy","multi":true,"name":"ratelimitpolicy","query":{"query":"label_values(gatewayapi_ratelimitpolicy_created, name)","refId":"StandardVariableQuery"},"regex":"/(.*)/","type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone":"utc","title":"Gateway API State / Policies","uid":"gatewayapipolicies"} diff --git a/config/examples/enterprise/all.yaml b/config/examples/enterprise/all.yaml index 040412a..845443e 100644 --- a/config/examples/enterprise/all.yaml +++ b/config/examples/enterprise/all.yaml @@ -625,6 +625,96 @@ status: - group: gateway.networking.k8s.io kind: GRPCRoute --- +apiVersion: kuadrant.io/v1alpha1 +kind: TLSPolicy +metadata: + name: external + namespace: istio-system +spec: + targetRef: + name: external + group: gateway.networking.k8s.io + kind: Gateway + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: selfsigned-cluster-issuer +status: + conditions: + - lastTransitionTime: "2023-08-21T22:53:08Z" + message: Gateway is TLS Enabled + reason: GatewayTLSEnabled + status: "True" + type: Ready +--- +apiVersion: kuadrant.io/v1alpha1 +kind: TLSPolicy +metadata: + name: internal + namespace: istio-system +spec: + targetRef: + name: internal + group: gateway.networking.k8s.io + kind: Gateway + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: selfsigned-cluster-issuer +status: + conditions: + - lastTransitionTime: "2023-08-21T22:53:08Z" + message: Gateway is TLS Enabled + reason: GatewayTLSEnabled + status: "True" + type: Ready +--- +apiVersion: kuadrant.io/v1beta2 +kind: RateLimitPolicy +metadata: + name: rlp-www +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: www + limits: + "global": + rates: + - limit: 5 + duration: 10 + unit: second +status: + conditions: + - lastTransitionTime: "2023-08-21T22:53:08Z" + message: Some message + reason: ThisEnabled + status: "True" + type: Ready +--- +apiVersion: kuadrant.io/v1beta2 +kind: RateLimitPolicy +metadata: + name: rlp-cdn +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: cdn + limits: + "global": + rates: + - limit: 5 + duration: 10 + unit: second +status: + conditions: + - lastTransitionTime: "2023-08-21T22:53:08Z" + message: Some message + reason: ThisEnabled + status: "True" + type: Ready +--- apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: diff --git a/config/examples/kube-prometheus/bundle.yaml b/config/examples/kube-prometheus/bundle.yaml index 31da0c3..beeb29f 100644 --- a/config/examples/kube-prometheus/bundle.yaml +++ b/config/examples/kube-prometheus/bundle.yaml @@ -493,6 +493,14 @@ rules: verbs: - list - watch +- apiGroups: + - kuadrant.io + resources: + - tlspolicies + - ratelimitpolicies + verbs: + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 @@ -1442,6 +1450,112 @@ data: parent_namespace: ["parentRef", "namespace"] parent_section_name: ["parentRef", "sectionName"] parent_port: ["parentRef", "port"] + - groupVersionKind: + group: kuadrant.io + kind: "TLSPolicy" + version: "v1alpha1" + metricNamePrefix: gatewayapi_tlspolicy + labelsFromPath: + name: + - metadata + - name + namespace: + - metadata + - namespace + metrics: + - name: "labels" + help: "Kubernetes labels converted to Prometheus labels." + each: + type: Info + info: + path: [metadata] + labelsFromPath: + "*": [labels] + - name: "created" + help: "created timestamp" + each: + type: Gauge + gauge: + path: [metadata, creationTimestamp] + - name: "deleted" + help: "deletion timestamp" + each: + type: Gauge + gauge: + path: [metadata, deletionTimestamp] + - name: "target_info" + help: "Target references that the tlspolicy wants to be attached to" + each: + type: Info + info: + path: [spec, targetRef] + labelsFromPath: + target_group: ["group"] + target_kind: ["kind"] + target_name: ["name"] + target_namespace: ["namespace"] + - name: "status" + help: "status condition" + each: + type: Gauge + gauge: + path: [status, conditions] + labelsFromPath: + type: ["type"] + valueFrom: ["status"] + - groupVersionKind: + group: kuadrant.io + kind: "RateLimitPolicy" + version: "v1beta2" + metricNamePrefix: gatewayapi_ratelimitpolicy + labelsFromPath: + name: + - metadata + - name + namespace: + - metadata + - namespace + metrics: + - name: "labels" + help: "Kubernetes labels converted to Prometheus labels." + each: + type: Info + info: + path: [metadata] + labelsFromPath: + "*": [labels] + - name: "created" + help: "created timestamp" + each: + type: Gauge + gauge: + path: [metadata, creationTimestamp] + - name: "deleted" + help: "deletion timestamp" + each: + type: Gauge + gauge: + path: [metadata, deletionTimestamp] + - name: "target_info" + help: "Target references that the tlspolicy wants to be attached to" + each: + type: Info + info: + path: [spec, targetRef] + labelsFromPath: + target_group: ["group"] + target_kind: ["kind"] + target_name: ["name"] + target_namespace: ["namespace"] + - name: "status" + help: "status condition" + each: + type: Gauge + gauge: + path: [status, conditions] + labelsFromPath: + type: ["type"] + valueFrom: ["status"] kind: ConfigMap metadata: name: custom-resource-state @@ -43677,6 +43791,8 @@ spec: name: grafana-tcproutes - mountPath: /grafana-dashboard-definitions/0/grafana-udproutes name: grafana-udproutes + - mountPath: /grafana-dashboard-definitions/0/grafana-tlspolicy + name: grafana-tlspolicy nodeSelector: kubernetes.io/os: linux securityContext: @@ -43791,6 +43907,10 @@ spec: defaultMode: 420 name: grafana-tlsroutes-fg5726f7k9 name: grafana-tlsroutes + - configMap: + defaultMode: 420 + name: grafana-tlspolicy + name: grafana-tlspolicy - configMap: defaultMode: 420 name: grafana-tcproutes-d7tt7t272g diff --git a/config/examples/kube-prometheus/grafana_deployment_patch.yaml b/config/examples/kube-prometheus/grafana_deployment_patch.yaml index 5d3a5ea..f773ae2 100644 --- a/config/examples/kube-prometheus/grafana_deployment_patch.yaml +++ b/config/examples/kube-prometheus/grafana_deployment_patch.yaml @@ -33,6 +33,13 @@ configMap: defaultMode: 420 name: grafana-tlsroutes +- op: add + path: /spec/template/spec/volumes/- + value: + name: grafana-tlspolicy + configMap: + defaultMode: 420 + name: grafana-tlspolicy - op: add path: /spec/template/spec/volumes/- value: @@ -82,3 +89,8 @@ value: name: grafana-udproutes mountPath: /grafana-dashboard-definitions/0/grafana-udproutes +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: + name: grafana-tlspolicy + mountPath: /grafana-dashboard-definitions/0/grafana-tlspolicy diff --git a/config/examples/kube-prometheus/ksm_clusterrole_patch.yaml b/config/examples/kube-prometheus/ksm_clusterrole_patch.yaml index 93995b8..4dded03 100644 --- a/config/examples/kube-prometheus/ksm_clusterrole_patch.yaml +++ b/config/examples/kube-prometheus/ksm_clusterrole_patch.yaml @@ -24,3 +24,14 @@ verbs: - list - watch +- op: add + path: /rules/- + value: + apiGroups: + - "kuadrant.io" + resources: + - tlspolicies + - ratelimitpolicies + verbs: + - list + - watch diff --git a/config/examples/kube-state-metrics/cluster-role.yaml b/config/examples/kube-state-metrics/cluster-role.yaml index 40f6a0f..7ac0944 100644 --- a/config/examples/kube-state-metrics/cluster-role.yaml +++ b/config/examples/kube-state-metrics/cluster-role.yaml @@ -146,3 +146,11 @@ rules: verbs: - list - watch +- apiGroups: + - "kuadrant.io" + resources: + - tlspolicies + - ratelimitpolicies + verbs: + - list + - watch diff --git a/config/gateway-api/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml b/config/gateway-api/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml new file mode 100644 index 0000000..0edb37e --- /dev/null +++ b/config/gateway-api/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml @@ -0,0 +1,490 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2245 + gateway.networking.k8s.io/bundle-version: v0.8.0 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: backendtlspolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies + shortNames: + - btlspolicy + singular: backendtlspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: BackendTLSPolicy provides a way to configure how a Gateway connects + to a Backend via TLS. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of BackendTLSPolicy. + properties: + targetRef: + description: "TargetRef identifies an API object to apply the policy + to. Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. Note that + this config applies to the entire referenced resource by default, + but this default may change in the future to provide a more granular + application of the policy. \n Support: Extended for Kubernetes Service + \n Support: Implementation-specific for any other resource" + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the referent. When + unspecified, the local namespace is inferred. Even when policy + targets a resource in a different namespace, it MUST only apply + to traffic originating from the same namespace as the policy. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. When unspecified, this targetRef targets the + entire resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name * + Service: Port Name \n If a SectionName is specified, but does + not exist on the targeted object, the Policy must fail to attach, + and the policy implementation should record a `ResolvedRefs` + or similar Condition in the Policy's status." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - group + - kind + - name + type: object + tls: + description: TLS contains backend TLS policy configuration. + properties: + certRefs: + description: "CertRefs contains one or more references to Kubernetes + objects that contain a PEM-encoded TLS CA certificate bundle, + which is used to validate a TLS handshake between the Gateway + and backend Pod. \n If CertRefs is empty or unspecified, then + StandardCerts must be specified. Only one of CertRefs or StandardCerts + may be specified, not both. \n If CertRefs is empty or unspecified, + then system trusted certificates should be used. If there are + none, or the implementation doesn't define system trusted certificates, + then a TLS connection must fail. \n References to a resource + in a different namespace are invalid for the moment, although + we will revisit this in the future. \n A single CertRef to a + Kubernetes ConfigMap kind has \"Core\" support. Implementations + MAY choose to support attaching multiple certificates to a backend, + but this behavior is implementation-specific. \n Support: Core + - An optional single reference to a Kubernetes ConfigMap, with + the CA certificate in a key named `ca.crt`. \n Support: Implementation-specific + (More than one reference, or other kinds of resources)." + items: + description: "ObjectReference identifies an API object including + its namespace, with no default kind. The Group and Kind fields + are thus required in this version. \n The API object must + be valid in the cluster; the Group and Kind must be registered + in the cluster for this reference to be valid. \n References + to objects with invalid Group and Kind are not valid, and + must be rejected by the implementation, with appropriate Conditions + set on the containing object." + properties: + group: + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When set to the empty string, + core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the referent. For example, + "ConfigMap". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the metadata.name of the referenced + config map. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referenced + object. When unspecified, the local namespace is inferred. + \n Note that when a namespace different than the local + namespace is specified, a ReferenceGrant object is required + in the referent namespace to allow that namespace's owner + to accept the reference. See the ReferenceGrant documentation + for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + maxItems: 8 + type: array + hostname: + description: "Hostname is used for two purposes in the connection + between Gateways and backends: \n 1. Hostname MUST be used as + the SNI to connect to the backend (RFC 6066). 2. Hostname MUST + be used for authentication and MUST match the certificate served + by the matching backend. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + standardCerts: + description: "StandardCerts specifies whether system CA certificates + may be used in the TLS handshake between the gateway and backend + pod. \n If StandardCerts is unspecified or set to \"\", then + CertRefs must be specified with at least one entry for a valid + configuration. Only one of CertRefs or StandardCerts may be + specified, not both. \n StandardCerts must be set to \"System\" + when CertRefs is unspecified. \n Support: Core for \"System\"" + enum: + - System + type: string + required: + - hostname + type: object + x-kubernetes-validations: + - message: must not contain both CertRefs and StandardCerts + rule: (has(self.certRefs) && size(self.certRefs) > 0 && has(self.standardCerts) + && self.standardCerts != "") + - message: must specify either CertRefs or StandardCerts + rule: '!(has(self.certRefs) && size(self.certRefs) > 0 || has(self.standardCerts) + && self.standardCerts != "")' + required: + - targetRef + - tls + type: object + status: + description: Status defines the current state of BackendTLSPolicy. + properties: + ancestors: + description: "Ancestors is a list of ancestor resources (usually Gateways) + that are associated with the policy, and the status of the policy + with respect to each ancestor. When this policy attaches to a parent, + the controller that manages the parent and the ancestors MUST add + an entry to this list when the controller first sees the policy + and SHOULD update the entry as appropriate when the relevant ancestor + is modified. \n Note that choosing the relevant ancestor is left + to the Policy designers; an important part of Policy design is designing + the right object level at which to namespace this status. \n Note + also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations + MUST use the ControllerName field to uniquely identify the entries + in this list that they are responsible for. \n Note that to achieve + this, the list of PolicyAncestorStatus structs MUST be treated as + a map with a composite key, made up of the AncestorRef and ControllerName + fields combined. \n A maximum of 8 ancestors will be represented + in this list. An empty list means the Policy is not relevant for + any ancestors." + items: + description: "PolicyAncestorStatus describes the status of a route + with respect to an associated Ancestor. \n Ancestors refer to + objects that are either the Target of a policy or above it in + terms of object hierarchy. For example, if a policy targets a + Service, the Policy's Ancestors are, in order, the Service, the + HTTPRoute, the Gateway, and the GatewayClass. Almost always, in + this hierarchy, the Gateway will be the most useful object to + place Policy status on, so we recommend that implementations SHOULD + use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. \n In the context of policy + attachment, the Ancestor is used to distinguish which resource + results in a distinct application of this policy. For example, + if a policy targets a Service, it may have a distinct result per + attached Gateway. \n Policies targeting the same resource may + have different effects depending on the ancestors of those resources. + For example, different Gateways targeting the same Service may + have different capabilities, especially if they have different + underlying implementations. \n For example, in BackendTLSPolicy, + the Policy attaches to a Service that is used as a backend in + a HTTPRoute that is itself attached to a Gateway. In this case, + the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. \n Note that a parent + is also an ancestor, so for objects where the parent is the relevant + object for status, this struct SHOULD still be used. \n This struct + is intended to be used in a slice that's effectively a map, with + a composite key made up of the AncestorRef and the ControllerName." + properties: + ancestorRef: + description: AncestorRef corresponds with a ParentRef in the + spec that this PolicyAncestorStatus struct describes the status + of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the + core API group (such as for a \"Service\" kind referent), + Group must be explicitly set to \"\" (empty string). \n + Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n There are + two kinds of parent resources with \"Core\" support: \n + * Gateway (Gateway conformance profile) * Service (Mesh + conformance profile, experimental, ClusterIP Services + only) \n Support for other resources is Implementation-Specific." + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified, this refers to the local namespace of + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n ParentRefs from a Route to a Service in + the same namespace are \"producer\" routes, which apply + default routing rules to inbound connections from any + namespace to the Service. \n ParentRefs from a Route to + a Service in a different namespace are \"consumer\" routes, + and these routing rules are only applied to outbound connections + originating from the same namespace as the Route, for + which the intended destination of the connections are + a Service targeted as a ParentRef of the Route. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n When the parent resource is + a Service, this targets a specific port in the Service + spec. When both Port (experimental) and SectionName are + specified, the name and port of the selected port must + match both specified values. \n Implementations MAY choose + to support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. * Service: Port Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match + both specified values. Note that attaching Routes to Services + as Parents is part of experimental Mesh support and is + not supported for any other purpose. \n Implementations + MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, \n type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: \"Available\", \"Progressing\", + and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields + }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 8 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null \ No newline at end of file diff --git a/config/gateway-api/crd/standard/kuadrant.io_ratelimitpolicies.yaml b/config/gateway-api/crd/standard/kuadrant.io_ratelimitpolicies.yaml new file mode 100644 index 0000000..a5c6b16 --- /dev/null +++ b/config/gateway-api/crd/standard/kuadrant.io_ratelimitpolicies.yaml @@ -0,0 +1,397 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: ratelimitpolicies.kuadrant.io +spec: + group: kuadrant.io + names: + kind: RateLimitPolicy + listKind: RateLimitPolicyList + plural: ratelimitpolicies + singular: ratelimitpolicy + scope: Namespaced + versions: + - name: v1beta2 + schema: + openAPIV3Schema: + description: RateLimitPolicy is the Schema for the ratelimitpolicies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RateLimitPolicySpec defines the desired state of RateLimitPolicy + properties: + limits: + additionalProperties: + description: Limit represents a complete rate limit configuration + properties: + counters: + description: Counters defines additional rate limit counters + based on context qualifiers and well known selectors TODO + Document properly "Well-known selector" https://github.com/Kuadrant/architecture/blob/main/rfcs/0001-rlp-v2.md#well-known-selectors + items: + description: 'ContextSelector defines one item from the well + known attributes Attributes: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes + Well-known selectors: https://github.com/Kuadrant/architecture/blob/main/rfcs/0001-rlp-v2.md#well-known-selectors + They are named by a dot-separated path (e.g. request.path) + Example: "request.path" -> The path portion of the URL' + maxLength: 253 + minLength: 1 + type: string + type: array + rates: + description: Rates holds the list of limit rates + items: + description: Rate defines the actual rate limit that will + be used when there is a match + properties: + duration: + description: Duration defines the time period for which + the Limit specified above applies. + type: integer + limit: + description: Limit defines the max value allowed for a + given period of time + type: integer + unit: + description: 'Duration defines the time uni Possible values + are: "second", "minute", "hour", "day"' + enum: + - second + - minute + - hour + - day + type: string + required: + - duration + - limit + - unit + type: object + type: array + routeSelectors: + description: RouteSelectors defines semantics for matching an + HTTP request based on conditions + items: + description: RouteSelector defines semantics for matching + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + properties: + hostnames: + description: Hostnames defines a set of hostname that + should match against the HTTP Host header to select + a HTTPRoute to process the request https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + items: + description: "Hostname is the fully qualified domain + name of a network host. This matches the RFC 1123 + definition of a hostname with 2 notable exceptions: + \n 1. IPs are not allowed. 2. A hostname may be prefixed + with a wildcard label (`*.`). The wildcard label must + appear by itself as the first label. \n Hostname can + be \"precise\" which is a domain name without the + terminating dot of a network host (e.g. \"foo.example.com\") + or \"wildcard\", which is a domain name prefixed with + a single wildcard label (e.g. `*.example.com`). \n + Note that as per RFC1035 and RFC1123, a *label* must + consist of lower case alphanumeric characters or '-', + and must start and end with an alphanumeric character. + No other punctuation is allowed." + type: string + type: array + matches: + description: Matches define conditions used for matching + the rule against incoming HTTP requests. https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + items: + description: "HTTPRouteMatch defines the predicate used + to match requests to a given action. Multiple match + types are ANDed together, i.e. the match will evaluate + to true only if all conditions are satisfied. \n For + example, the match below will match a HTTP request + only if its path starts with `/foo` AND it contains + the `version: v1` header: \n ``` match: \n path: value: + \"/foo\" headers: - name: \"version\" value \"v1\" + \n ```" + properties: + headers: + description: Headers specifies HTTP request header + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified + headers to select the route. + items: + description: HTTPHeaderMatch describes how to + select a HTTP route by matching HTTP request + headers. + properties: + name: + description: "Name is the name of the HTTP + Header to be matched. Name matching MUST + be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, only the first entry with + an equivalent name MUST be considered for + a match. Subsequent entries with an equivalent + header name MUST be ignored. Due to the + case-insensitivity of header names, \"foo\" + and \"Foo\" are considered equivalent. \n + When a header is repeated in an HTTP request, + it is implementation-specific behavior as + to how this is represented. Generally, proxies + should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, + with special handling for \"Set-Cookie\"." + type: string + type: + description: "Type specifies how to match + against the value of the header. \n Support: + Core (Exact) \n Support: Implementation-specific + (RegularExpression) \n Since RegularExpression + HeaderMatchType has implementation-specific + conformance, implementations can support + POSIX, PCRE or any other dialects of regular + expressions. Please read the implementation's + documentation to determine the supported + dialect." + type: string + value: + description: Value is the value of HTTP Header + to be matched. + type: string + required: + - name + - value + type: object + type: array + method: + description: "Method specifies HTTP method matcher. + When specified, this route will be matched only + if the request has the specified method. \n Support: + Extended" + type: string + path: + description: Path specifies a HTTP request path + matcher. If this field is not specified, a default + prefix match on the "/" path is provided. + properties: + type: + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Implementation-specific (RegularExpression)" + type: string + value: + description: Value of the HTTP path to match + against. + type: string + type: object + queryParams: + description: "QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified + query parameters to select the route. \n Support: + Extended" + items: + description: HTTPQueryParamMatch describes how + to select a HTTP route by matching HTTP query + parameters. + properties: + name: + description: "Name is the name of the HTTP + query param to be matched. This must be + an exact string match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + \n If multiple entries specify equivalent + query param names, only the first entry + with an equivalent name MUST be considered + for a match. Subsequent entries with an + equivalent query param name MUST be ignored. + \n If a query param is repeated in an HTTP + request, the behavior is purposely left + undefined, since different data planes have + different capabilities. However, it is *recommended* + that implementations should match against + the first value of the param if the data + plane supports it, as this behavior is expected + in other load balancing contexts outside + of the Gateway API. \n Users SHOULD NOT + route traffic based on repeated query params + to guard themselves against potential differences + in the implementations." + type: string + type: + description: "Type specifies how to match + against the value of the query parameter. + \n Support: Extended (Exact) \n Support: + Implementation-specific (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has Implementation-specific conformance, + implementations can support POSIX, PCRE + or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + type: string + value: + description: Value is the value of HTTP query + param to be matched. + type: string + required: + - name + - value + type: object + type: array + type: object + type: array + type: object + type: array + when: + description: When holds the list of conditions for the policy + to be enforced. Called also "soft" conditions as route selectors + must also match + items: + description: RouteSelector defines semantics for matching + an HTTP request based on conditions https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec + properties: + operator: + description: 'The binary operator to be applied to the + content fetched from the selector Possible values are: + "eq" (equal to), "neq" (not equal to)' + enum: + - eq + - neq + - startswith + - endswith + - incl + - excl + - matches + type: string + selector: + description: Selector defines one item from the well known + selectors TODO Document properly "Well-known selector" + https://github.com/Kuadrant/architecture/blob/main/rfcs/0001-rlp-v2.md#well-known-selectors + maxLength: 253 + minLength: 1 + type: string + value: + description: The value of reference for the comparison. + type: string + required: + - operator + - selector + - value + type: object + type: array + type: object + description: Limits holds the struct of limits indexed by a unique + name + type: object + targetRef: + description: TargetRef identifies an API object to apply policy to. + properties: + group: + description: Group is the group of the target resource. + type: string + kind: + description: Kind is kind of the target resource. + type: string + name: + description: Name is the name of the target resource. + type: string + namespace: + description: Namespace is the namespace of the referent. When + unspecified, the local namespace is inferred. Even when policy + targets a resource in a different namespace, it MUST only apply + to traffic originating from the same namespace as the policy. + type: string + required: + - group + - kind + - name + type: object + required: + - targetRef + type: object + status: + description: RateLimitPolicyStatus defines the observed state of RateLimitPolicy + properties: + conditions: + description: 'Represents the observations of a foo''s current state. + Known .status.conditions.type are: "Available"' + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: ObservedGeneration reflects the generation of the most + recently observed spec. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/config/gateway-api/crd/standard/kuadrant.io_tlspolicies.yaml b/config/gateway-api/crd/standard/kuadrant.io_tlspolicies.yaml new file mode 100644 index 0000000..0b55aa1 --- /dev/null +++ b/config/gateway-api/crd/standard/kuadrant.io_tlspolicies.yaml @@ -0,0 +1,313 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + gateway.networking.k8s.io/policy: direct + creationTimestamp: null + name: tlspolicies.kuadrant.io +spec: + group: kuadrant.io + names: + kind: TLSPolicy + listKind: TLSPolicyList + plural: tlspolicies + singular: tlspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: TLSPolicy ready. + jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: TLSPolicy is the Schema for the tlspolicies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TLSPolicySpec defines the desired state of TLSPolicy + properties: + commonName: + description: 'CommonName is a common name to be used on the Certificate. + The CommonName should have a length of 64 characters or fewer to + avoid generating invalid CSRs. This value is ignored by TLS clients + when any subject alt name is set. This is x509 behaviour: https://tools.ietf.org/html/rfc6125#section-6.4.4' + type: string + duration: + description: The requested 'duration' (i.e. lifetime) of the Certificate. + This option may be ignored/overridden by some issuer types. If unset + this defaults to 90 days. Certificate will be renewed either 2/3 + through its duration or `renewBefore` period before its expiry, + whichever is later. Minimum accepted duration is 1 hour. Value must + be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + issuerRef: + description: IssuerRef is a reference to the issuer for this certificate. + If the `kind` field is not set, or set to `Issuer`, an Issuer resource + with the given name in the same namespace as the Certificate will + be used. If the `kind` field is set to `ClusterIssuer`, a ClusterIssuer + with the provided name will be used. The `name` field in this stanza + is required at all times. + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + required: + - name + type: object + privateKey: + description: Options to control private keys used for the Certificate. + properties: + algorithm: + description: Algorithm is the private key algorithm of the corresponding + private key for this certificate. If provided, allowed values + are either `RSA`,`Ed25519` or `ECDSA` If `algorithm` is specified + and `size` is not provided, key size of 256 will be used for + `ECDSA` key algorithm and key size of 2048 will be used for + `RSA` key algorithm. key size is ignored when using the `Ed25519` + key algorithm. + enum: + - RSA + - ECDSA + - Ed25519 + type: string + encoding: + description: The private key cryptography standards (PKCS) encoding + for this certificate's private key to be encoded in. If provided, + allowed values are `PKCS1` and `PKCS8` standing for PKCS#1 and + PKCS#8, respectively. Defaults to `PKCS1` if not specified. + enum: + - PKCS1 + - PKCS8 + type: string + rotationPolicy: + description: RotationPolicy controls how private keys should be + regenerated when a re-issuance is being processed. If set to + Never, a private key will only be generated if one does not + already exist in the target `spec.secretName`. If one does exists + but it does not have the correct algorithm or size, a warning + will be raised to await user intervention. If set to Always, + a private key matching the specified requirements will be generated + whenever a re-issuance occurs. Default is 'Never' for backward + compatibility. + type: string + size: + description: Size is the key bit size of the corresponding private + key for this certificate. If `algorithm` is set to `RSA`, valid + values are `2048`, `4096` or `8192`, and will default to `2048` + if not specified. If `algorithm` is set to `ECDSA`, valid values + are `256`, `384` or `521`, and will default to `256` if not + specified. If `algorithm` is set to `Ed25519`, Size is ignored. + No other values are allowed. + type: integer + type: object + renewBefore: + description: How long before the currently issued certificate's expiry + cert-manager should renew the certificate. The default is 2/3 of + the issued certificate's duration. Minimum accepted value is 5 minutes. + Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit is the maximum number of CertificateRequest + revisions that are maintained in the Certificate's history. Each + revision represents a single `CertificateRequest` created by this + Certificate, either when it was created, renewed, or Spec was changed. + Revisions will be removed by oldest first if the number of revisions + exceeds this number. If set, revisionHistoryLimit must be a value + of `1` or greater. If unset (`nil`), revisions will not be garbage + collected. Default value is `nil`. + format: int32 + type: integer + targetRef: + description: PolicyTargetReference identifies an API object to apply + policy to. This should be used as part of Policy resources that + can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer + to the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the referent. When + unspecified, the local namespace is inferred. Even when policy + targets a resource in a different namespace, it MUST only apply + to traffic originating from the same namespace as the policy. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + usages: + description: Usages is the set of x509 usages that are requested for + the certificate. Defaults to `digital signature` and `key encipherment` + if not specified. + items: + description: 'KeyUsage specifies valid usage contexts for keys. + See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + Valid KeyUsage values are as follows: "signing", "digital signature", + "content commitment", "key encipherment", "key agreement", "data + encipherment", "cert sign", "crl sign", "encipher only", "decipher + only", "any", "server auth", "client auth", "code signing", "email + protection", "s/mime", "ipsec end system", "ipsec tunnel", "ipsec + user", "timestamping", "ocsp signing", "microsoft sgc", "netscape + sgc"' + enum: + - signing + - digital signature + - content commitment + - key encipherment + - key agreement + - data encipherment + - cert sign + - crl sign + - encipher only + - decipher only + - any + - server auth + - client auth + - code signing + - email protection + - s/mime + - ipsec end system + - ipsec tunnel + - ipsec user + - timestamping + - ocsp signing + - microsoft sgc + - netscape sgc + type: string + type: array + required: + - issuerRef + - targetRef + type: object + status: + description: TLSPolicyStatus defines the observed state of TLSPolicy + properties: + conditions: + description: "conditions are any conditions associated with the policy + \n If configuring the policy fails, the \"Failed\" condition will + be set with a reason and message describing the cause of the failure." + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + observedGeneration: + description: observedGeneration is the most recently observed generation + of the TLSPolicy. When the TLSPolicy is updated, the controller + updates the corresponding configuration. If an update fails, that + failure is recorded in the status condition + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/src/dashboards/lib/gwapi/gwapi.libsonnet b/src/dashboards/lib/gwapi/gwapi.libsonnet index 07c696c..3c13685 100644 --- a/src/dashboards/lib/gwapi/gwapi.libsonnet +++ b/src/dashboards/lib/gwapi/gwapi.libsonnet @@ -277,4 +277,27 @@ local var = import './variables.libsonnet'; }, }), ]), + + policyPanel(title, h, w, x, y, expr): + self.table(title, h, w, x, y, expr) + + g.panel.table.queryOptions.withTransformations([ + g.panel.table.transformation.withId('filterFieldsByName') + + g.panel.table.transformation.withOptions({ + include: { + names: [ + 'name', + 'target_kind', + 'target_name', + ], + }, + }), + g.panel.table.transformation.withId('organize') + + g.panel.table.transformation.withOptions({ + renameByName: { + name: 'Name', + target_kind: 'Target Kind', + target_name: 'Target Name', + }, + }), + ]), } \ No newline at end of file diff --git a/src/dashboards/policies.jsonnet b/src/dashboards/policies.jsonnet new file mode 100644 index 0000000..ec7aebc --- /dev/null +++ b/src/dashboards/policies.jsonnet @@ -0,0 +1,18 @@ +local g = import 'lib/g.libsonnet'; +local gwapi = import 'lib/gwapi/gwapi.libsonnet'; +local var = import 'lib/gwapi/variables.libsonnet'; + +gwapi.dashboard('Policies', 'gatewayapipolicies', [ + var.routes('tlspolicy', 'TLSPolicy'), + var.routes('ratelimitpolicy', 'RateLimitPolicy') +]) ++ g.dashboard.withPanels([ + gwapi.row('TLSPolicy', 1, 24, 0, 0), + gwapi.stat('Total', 3, 4, 0, 1, 'Total number of TLSPolicy across all clusters', 'count(gatewayapi_tlspolicy_status)'), + gwapi.stat('Ready', 3, 2, 0, 2, 'Total TLSPolicy with an Ready state', 'count(gatewayapi_tlspolicy_status{type="Ready"})'), + gwapi.policyPanel('TLSPolicy',6,10,4,1,'gatewayapi_tlspolicy_target_info'), + gwapi.row('RateLimitPolicy', 1, 24, 0, 2), + gwapi.stat('Total', 3, 4, 0, 3, 'Total number of RateLimitPolicy across all clusters', 'count(gatewayapi_ratelimitpolicy_status)'), + gwapi.stat('Ready', 3, 2, 0, 4, 'Total RateLimitPolicy with an Ready state', 'count(gatewayapi_ratelimitpolicy_status{type="Ready"})'), + gwapi.policyPanel('RateLimitPolicy',6,10,4,7,'gatewayapi_ratelimitpolicy_target_info'), +]) \ No newline at end of file