Files
kubeconform/crdSchemas/cfgate.io/cloudflaretunnel_v1alpha1.json
2026-08-18 19:18:31 +01:00

484 lines
22 KiB
JSON

{
"description": "CloudflareTunnel is the Schema for the cloudflaretunnels API.\n\nCloudflareTunnel manages the lifecycle of a Cloudflare Tunnel and its cloudflared daemon\ndeployment. It handles tunnel creation or adoption, credential management, and deploys\ncloudflared pods that establish secure connections to Cloudflare's edge network.\n\nCloudflareTunnel follows a composable architecture where tunnel lifecycle is separate from\nDNS management. Use CloudflareDNS with a tunnelRef to create DNS records pointing to this\ntunnel's domain.\n\nStatus conditions:\n - Ready: tunnel is fully operational\n - CredentialsValid: API credentials have been validated\n - TunnelReady: tunnel exists in Cloudflare\n - ConfigurationSynced: ingress configuration is synced\n - CloudflaredDeployed: cloudflared pods are running",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore 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.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "CloudflareTunnelSpec defines the desired state of a CloudflareTunnel resource.\n\nCloudflareTunnelSpec configures the tunnel identity, Cloudflare credentials, cloudflared\ndeployment settings, and origin connection defaults. The tunnel manages lifecycle only;\nDNS records are managed separately via CloudflareDNS resources.",
"properties": {
"cloudflare": {
"description": "Cloudflare defines the Cloudflare API credentials.",
"properties": {
"accountId": {
"description": "AccountID is the Cloudflare Account ID.",
"maxLength": 32,
"type": "string"
},
"accountName": {
"description": "AccountName is the Cloudflare Account name. Will be looked up via API.",
"maxLength": 255,
"type": "string"
},
"secretKeys": {
"description": "SecretKeys defines the key mappings within the secret.",
"properties": {
"apiToken": {
"default": "CLOUDFLARE_API_TOKEN",
"description": "APIToken is the key name for the Cloudflare API token.",
"maxLength": 253,
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"secretRef": {
"description": "SecretRef references the Secret containing Cloudflare API credentials.\nThe secret must contain an API token (not tunnel token).",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the tunnel's namespace.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"secretRef"
],
"type": "object",
"x-kubernetes-validations": [
{
"message": "either accountId or accountName must be specified",
"rule": "has(self.accountId) || has(self.accountName)"
},
{
"message": "accountId must be a 32-character hex string",
"rule": "!has(self.accountId) || self.accountId.matches('^[a-f0-9]{32}$')"
}
],
"additionalProperties": false
},
"cloudflared": {
"description": "Cloudflared defines the cloudflared deployment configuration.",
"properties": {
"extraArgs": {
"description": "ExtraArgs are additional arguments to pass to cloudflared.",
"items": {
"type": "string"
},
"maxItems": 20,
"type": "array"
},
"image": {
"default": "ghcr.io/inherent-design/cloudflared:2026.5.0-h2c.1",
"description": "Image is the cloudflared container image.",
"maxLength": 255,
"type": "string"
},
"imagePullPolicy": {
"default": "IfNotPresent",
"description": "ImagePullPolicy is the pull policy for the cloudflared image.",
"enum": [
"Always",
"Never",
"IfNotPresent"
],
"type": "string"
},
"metrics": {
"description": "Metrics configures the cloudflared metrics endpoint.",
"properties": {
"enabled": {
"default": true,
"description": "Enabled enables the metrics endpoint.",
"type": "boolean"
},
"port": {
"default": 44483,
"description": "Port is the port for the metrics endpoint.",
"format": "int32",
"maximum": 65535,
"minimum": 1,
"type": "integer"
}
},
"type": "object",
"additionalProperties": false
},
"nodeSelector": {
"additionalProperties": {
"type": "string"
},
"description": "NodeSelector is a selector for nodes to run cloudflared on.",
"maxProperties": 50,
"type": "object"
},
"podAnnotations": {
"additionalProperties": {
"type": "string"
},
"description": "PodAnnotations are annotations to add to cloudflared pods.",
"maxProperties": 50,
"type": "object"
},
"protocol": {
"default": "auto",
"description": "Protocol is the tunnel transport protocol: auto, quic, http2.",
"enum": [
"auto",
"quic",
"http2"
],
"type": "string"
},
"replicas": {
"default": 2,
"description": "Replicas is the number of cloudflared replicas.",
"format": "int32",
"maximum": 10,
"minimum": 1,
"type": "integer"
},
"resources": {
"description": "Resources are the resource requirements for cloudflared containers.",
"properties": {
"claims": {
"description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\nThis field depends on the\nDynamicResourceAllocation feature gate.\n\nThis field is immutable. It can only be set for containers.",
"items": {
"description": "ResourceClaim references one entry in PodSpec.ResourceClaims.",
"properties": {
"name": {
"description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.",
"type": "string"
},
"request": {
"description": "Request is the name chosen for a request in the referenced claim.\nIf empty, everything from the claim is made available, otherwise\nonly the result of this request.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
"limits": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/",
"type": "object"
},
"requests": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/",
"type": "object"
}
},
"type": "object",
"additionalProperties": false
},
"tolerations": {
"description": "Tolerations are tolerations for the cloudflared pods.",
"items": {
"description": "The pod this Toleration is attached to tolerates any taint that matches\nthe triple <key,value,effect> using the matching operator <operator>.",
"properties": {
"effect": {
"description": "Effect indicates the taint effect to match. Empty means match all taint effects.\nWhen specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.",
"type": "string"
},
"key": {
"description": "Key is the taint key that the toleration applies to. Empty means match all taint keys.\nIf the key is empty, operator must be Exists; this combination means to match all values and all keys.",
"type": "string"
},
"operator": {
"description": "Operator represents a key's relationship to the value.\nValid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.\nExists is equivalent to wildcard for value, so that a pod can\ntolerate all taints of a particular category.\nLt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).",
"type": "string"
},
"tolerationSeconds": {
"description": "TolerationSeconds represents the period of time the toleration (which must be\nof effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\nit is not set, which means tolerate the taint forever (do not evict). Zero and\nnegative values will be treated as 0 (evict immediately) by the system.",
"format": "int64",
"type": "integer"
},
"value": {
"description": "Value is the taint value the toleration matches to.\nIf the operator is Exists, the value should be empty, otherwise just a regular string.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"maxItems": 20,
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"fallbackCredentialsRef": {
"description": "FallbackCredentialsRef references a secret containing fallback Cloudflare API credentials.\nUsed during deletion when primary credentials (in Cloudflare.SecretRef) are unavailable.\nThis enables cleanup of Cloudflare resources even if the per-tunnel secret is deleted.\nThe secret must contain the same keys as the primary credentials secret.",
"properties": {
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
},
"namespace": {
"description": "Namespace of the secret. Defaults to the resource's namespace if empty.",
"maxLength": 63,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"fallbackTarget": {
"default": "http_status:404",
"description": "FallbackTarget is the service for unmatched requests.",
"maxLength": 255,
"type": "string"
},
"originDefaults": {
"description": "OriginDefaults defines default settings for origin connections.",
"properties": {
"caPoolSecretRef": {
"description": "CAPoolSecretRef references a Secret containing CA certificates for origin verification.",
"properties": {
"key": {
"default": "ca.crt",
"description": "Key is the key within the secret data.",
"maxLength": 253,
"type": "string"
},
"name": {
"description": "Name of the secret.",
"maxLength": 253,
"minLength": 1,
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
},
"connectTimeout": {
"default": "30s",
"description": "ConnectTimeout is the timeout for connecting to the origin.",
"pattern": "^[0-9]+(s|m|h)$",
"type": "string"
},
"h2cOrigin": {
"default": false,
"description": "H2cOrigin enables HTTP/2 cleartext (h2c) for origin connections.\nUse this for origins that speak HTTP/2 without TLS (e.g., gRPC services).\nMutually exclusive with http2Origin (TLS-based HTTP/2).",
"type": "boolean"
},
"http2Origin": {
"default": false,
"description": "HTTP2Origin enables HTTP/2 for origin connections.",
"type": "boolean"
},
"noTLSVerify": {
"default": false,
"description": "NoTLSVerify disables TLS verification for origin connections.",
"type": "boolean"
}
},
"type": "object",
"x-kubernetes-validations": [
{
"message": "http2Origin and h2cOrigin are mutually exclusive",
"rule": "!(self.http2Origin && self.h2cOrigin)"
}
],
"additionalProperties": false
},
"tunnel": {
"description": "Tunnel defines the tunnel identity configuration.",
"properties": {
"name": {
"description": "Name is the tunnel name in Cloudflare. If tunnel with this name exists, adopt it.\nIf not, create it. Tunnel ID is stored in status after resolution/creation.",
"maxLength": 63,
"minLength": 1,
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"cloudflare",
"tunnel"
],
"type": "object",
"additionalProperties": false
},
"status": {
"description": "CloudflareTunnelStatus defines the observed state of a CloudflareTunnel resource.\n\nCloudflareTunnelStatus captures the tunnel's Cloudflare-assigned identifiers, deployment\nstatus, and reconciliation state. The TunnelDomain field provides the CNAME target\n({tunnelId}.cfargotunnel.com) that CloudflareDNS uses for DNS record creation.",
"properties": {
"accountId": {
"description": "AccountID is the resolved Cloudflare account ID.",
"type": "string"
},
"conditions": {
"description": "Conditions represent the latest available observations of the tunnel's state.",
"items": {
"description": "Condition contains details for one aspect of the current state of this API Resource.",
"properties": {
"lastTransitionTime": {
"description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis 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.\nThis may be an empty string.",
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith 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.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis 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.",
"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",
"additionalProperties": false
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"connectedRouteCount": {
"description": "ConnectedRouteCount is the number of routes connected to this tunnel.",
"format": "int32",
"type": "integer"
},
"lastSyncTime": {
"description": "LastSyncTime is the last time the configuration was synced to Cloudflare.",
"format": "date-time",
"type": "string"
},
"observedGeneration": {
"description": "ObservedGeneration is the generation observed by the controller.",
"format": "int64",
"type": "integer"
},
"readyReplicas": {
"description": "ReadyReplicas is the number of ready cloudflared replicas.",
"format": "int32",
"type": "integer"
},
"replicas": {
"description": "Replicas is the total number of cloudflared replicas.",
"format": "int32",
"type": "integer"
},
"tunnelDomain": {
"description": "TunnelDomain is the tunnel's CNAME target domain (e.g., {tunnelId}.cfargotunnel.com).",
"type": "string"
},
"tunnelId": {
"description": "TunnelID is the Cloudflare tunnel ID.",
"type": "string"
},
"tunnelName": {
"description": "TunnelName is the Cloudflare tunnel name.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}