{
  "description": "Contour is the Schema for the contours 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": "Spec defines the desired state of Contour.",
      "properties": {
        "enableExternalNameService": {
          "description": "EnableExternalNameService enables ExternalName Services. ExternalName Services are disabled by default due to CVE-2021-XXXXX You can re-enable them by setting this setting to \"true\". This is not recommended without understanding the security implications. Please see the advisory at https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc for the details.",
          "type": "boolean"
        },
        "gatewayClassRef": {
          "description": "GatewayClassRef is a reference to a GatewayClass name used for managing a Contour. DEPRECATED: The contour operator no longer reconciles GatewayClasses.",
          "maxLength": 253,
          "type": "string"
        },
        "gatewayControllerName": {
          "description": "GatewayControllerName is used to determine which GatewayClass Contour reconciles. The string takes the form of \"projectcontour.io/<namespace>/contour\". If unset, Contour will not reconcile Gateway API resources.",
          "maxLength": 253,
          "type": "string"
        },
        "ingressClassName": {
          "description": "IngressClassName is the name of the IngressClass used by Contour. If unset, Contour will process all ingress objects without an ingress class annotation or ingress objects with an annotation matching ingress-class=contour. When specified, Contour will only process ingress objects that match the provided class. \n For additional IngressClass details, refer to:   https://projectcontour.io/docs/main/config/annotations/#ingress-class",
          "maxLength": 253,
          "minLength": 1,
          "type": "string"
        },
        "namespace": {
          "default": {
            "name": "projectcontour",
            "removeOnDeletion": false
          },
          "description": "Namespace defines the schema of a Contour namespace. See each field for additional details.",
          "properties": {
            "name": {
              "default": "projectcontour",
              "description": "Name is the name of the namespace to run Contour and dependent resources. If unset, defaults to \"projectcontour\".",
              "type": "string"
            },
            "removeOnDeletion": {
              "default": false,
              "description": "RemoveOnDeletion will remove the namespace when the Contour is deleted. If set to True, deletion will not occur if any of the following conditions exist: \n 1. The Contour namespace is \"default\", \"kube-system\" or the    contour-operator's namespace. \n 2. Another Contour exists in the namespace. \n 3. The namespace does not contain the Contour owning label.",
              "type": "boolean"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "networkPublishing": {
          "default": {
            "envoy": {
              "containerPorts": [
                {
                  "name": "http",
                  "portNumber": 8080
                },
                {
                  "name": "https",
                  "portNumber": 8443
                }
              ],
              "type": "LoadBalancerService"
            }
          },
          "description": "NetworkPublishing defines the schema for publishing Contour to a network. \n See each field for additional details.",
          "properties": {
            "envoy": {
              "default": {
                "containerPorts": [
                  {
                    "name": "http",
                    "portNumber": 8080
                  },
                  {
                    "name": "https",
                    "portNumber": 8443
                  }
                ],
                "loadBalancer": {
                  "providerParameters": {
                    "type": "AWS"
                  },
                  "scope": "External"
                },
                "type": "LoadBalancerService"
              },
              "description": "Envoy provides the schema for publishing the network endpoints of Envoy. \n If unset, defaults to:   type: LoadBalancerService   containerPorts:   - name: http     portNumber: 8080   - name: https     portNumber: 8443",
              "properties": {
                "containerPorts": {
                  "default": [
                    {
                      "name": "http",
                      "portNumber": 8080
                    },
                    {
                      "name": "https",
                      "portNumber": 8443
                    }
                  ],
                  "description": "ContainerPorts is a list of container ports to expose from the Envoy container(s). Exposing a port here gives the system additional information about the network connections the Envoy container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed by Envoy. Any port which is listening on the default \"0.0.0.0\" address inside the Envoy container will be accessible from the network. Names and port numbers must be unique in the list container ports. Two ports must be specified, one named \"http\" for Envoy's insecure service and one named \"https\" for Envoy's secure service. \n TODO [danehans]: Update minItems to 1, requiring only https when the following issue is fixed: https://github.com/projectcontour/contour/issues/2577. \n TODO [danehans]: Increase maxItems when https://github.com/projectcontour/contour/pull/3263 is implemented.",
                  "items": {
                    "description": "ContainerPort is the schema to specify a network port for a container. A container port gives the system additional information about network connections a container uses, but is primarily informational.",
                    "properties": {
                      "name": {
                        "description": "Name is an IANA_SVC_NAME within the pod.",
                        "maxLength": 253,
                        "minLength": 1,
                        "type": "string"
                      },
                      "portNumber": {
                        "description": "PortNumber is the network port number to expose on the envoy pod. The number must be greater than 0 and less than 65536.",
                        "format": "int32",
                        "maximum": 65535,
                        "minimum": 1,
                        "type": "integer"
                      }
                    },
                    "required": [
                      "name",
                      "portNumber"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "maxItems": 2,
                  "minItems": 2,
                  "type": "array"
                },
                "loadBalancer": {
                  "default": {
                    "providerParameters": {
                      "type": "AWS"
                    },
                    "scope": "External"
                  },
                  "description": "LoadBalancer holds parameters for the load balancer. Present only if type is LoadBalancerService. \n If unspecified, defaults to an external Classic AWS ELB.",
                  "properties": {
                    "providerParameters": {
                      "default": {
                        "type": "AWS"
                      },
                      "description": "ProviderParameters contains load balancer information specific to the underlying infrastructure provider.",
                      "properties": {
                        "aws": {
                          "description": "AWS provides configuration settings that are specific to AWS load balancers. \n If empty, defaults will be applied. See specific aws fields for details about their defaults.",
                          "properties": {
                            "allocationIds": {
                              "description": "AllocationIDs is a list of Allocation IDs of Elastic IP addresses that are to be assigned to the Network Load Balancer. Works only with type NLB. If you are using Amazon EKS 1.16 or later, you can assign Elastic IP addresses to Network Load Balancer with AllocationIDs. The number of Allocation IDs must match the number of subnets used for the load balancer. \n Example: \"eipalloc-<xxxxxxxxxxxxxxxxx>\" \n See: https://docs.aws.amazon.com/eks/latest/userguide/load-balancing.html",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "type": {
                              "default": "Classic",
                              "description": "Type is the type of AWS load balancer to manage. \n Valid values are: \n * \"Classic\": A Classic load balancer makes routing decisions at either the   transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See   the following for additional details: \n     https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb \n * \"NLB\": A Network load balancer makes routing decisions at the transport   layer (TCP/SSL). See the following for additional details: \n     https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb \n If unset, defaults to \"Classic\".",
                              "enum": [
                                "Classic",
                                "NLB"
                              ],
                              "type": "string"
                            }
                          },
                          "type": "object",
                          "additionalProperties": false
                        },
                        "azure": {
                          "description": "Azure provides configuration settings that are specific to Azure load balancers. \n If empty, defaults will be applied. See specific azure fields for details about their defaults.",
                          "properties": {
                            "address": {
                              "description": "Address is the desired load balancer IP address. If scope is \"Internal\", address must reside in same virtual network as AKS and must not already be assigned to a resource. If address does not reside in same subnet as AKS, the subnet parameter is also required. \n Address must already exist (e.g. `az network public-ip create`). \n See: \t https://docs.microsoft.com/en-us/azure/aks/static-ip#create-a-service-using-the-static-ip-address \t https://docs.microsoft.com/en-us/azure/aks/internal-lb#specify-an-ip-address",
                              "maxLength": 253,
                              "minLength": 1,
                              "type": "string"
                            },
                            "resourceGroup": {
                              "description": "ResourceGroup is the resource group name where the \"address\" resides. Relevant only if scope is \"External\". \n Omit if desired IP is created in same resource group as AKS cluster.",
                              "maxLength": 90,
                              "minLength": 1,
                              "type": "string"
                            },
                            "subnet": {
                              "description": "Subnet is the subnet name where the \"address\" resides. Relevant only if scope is \"Internal\" and desired IP does not reside in same subnet as AKS. \n Omit if desired IP is in same subnet as AKS cluster. \n See: https://docs.microsoft.com/en-us/azure/aks/internal-lb#specify-an-ip-address",
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "type": "object",
                          "additionalProperties": false
                        },
                        "gcp": {
                          "description": "GCP provides configuration settings that are specific to GCP load balancers. \n If empty, defaults will be applied. See specific gcp fields for details about their defaults.",
                          "properties": {
                            "address": {
                              "description": "Address is the desired load balancer IP address. If scope is \"Internal\", the address must reside in same subnet as the GKE cluster or \"subnet\" has to be provided. \n See: \t https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip#use_a_service \t https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing#lb_subnet",
                              "maxLength": 253,
                              "minLength": 1,
                              "type": "string"
                            },
                            "subnet": {
                              "description": "Subnet is the subnet name where the \"address\" resides. Relevant only if scope is \"Internal\" and desired IP does not reside in same subnet as GKE cluster. \n Omit if desired IP is in same subnet as GKE cluster. \n See: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing#lb_subnet",
                              "maxLength": 63,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "type": "object",
                          "additionalProperties": false
                        },
                        "type": {
                          "default": "AWS",
                          "description": "Type is the underlying infrastructure provider for the load balancer. Allowed values are \"AWS\", \"Azure\", and \"GCP\".",
                          "enum": [
                            "AWS",
                            "Azure",
                            "GCP"
                          ],
                          "type": "string"
                        }
                      },
                      "type": "object",
                      "additionalProperties": false
                    },
                    "scope": {
                      "default": "External",
                      "description": "Scope indicates the scope at which the load balancer is exposed. Possible values are \"External\" and \"Internal\".",
                      "enum": [
                        "Internal",
                        "External"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "nodePorts": {
                  "description": "NodePorts is a list of network ports to expose on each node's IP at a static port number using a NodePort Service. Present only if type is NodePortService. A ClusterIP Service, which the NodePort Service routes to, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>. \n If type is NodePortService and nodePorts is unspecified, two nodeports will be created, one named \"http\" and the other named \"https\", with port numbers auto assigned by Kubernetes API server. For additional information on the NodePort Service, see: \n  https://kubernetes.io/docs/concepts/services-networking/service/#nodeport \n Names and port numbers must be unique in the list. Two ports must be specified, one named \"http\" for Envoy's insecure service and one named \"https\" for Envoy's secure service.",
                  "items": {
                    "description": "NodePort is the schema to specify a network port for a NodePort Service.",
                    "properties": {
                      "name": {
                        "description": "Name is an IANA_SVC_NAME within the NodePort Service.",
                        "maxLength": 253,
                        "minLength": 1,
                        "type": "string"
                      },
                      "portNumber": {
                        "description": "PortNumber is the network port number to expose for the NodePort Service. If unspecified, a port number will be assigned from the the cluster's nodeport service range, i.e. --service-node-port-range flag (default: 30000-32767). \n If specified, the number must: \n 1. Not be used by another NodePort Service. 2. Be within the cluster's nodeport service range, i.e. --service-node-port-range    flag (default: 30000-32767). 3. Be a valid network port number, i.e. greater than 0 and less than 65536.",
                        "format": "int32",
                        "maximum": 65535,
                        "minimum": 1,
                        "type": "integer"
                      }
                    },
                    "required": [
                      "name"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "maxItems": 2,
                  "minItems": 2,
                  "type": "array"
                },
                "type": {
                  "default": "LoadBalancerService",
                  "description": "Type is the type of publishing strategy to use. Valid values are: \n * LoadBalancerService \n In this configuration, network endpoints for Envoy use container networking. A Kubernetes LoadBalancer Service is created to publish Envoy network endpoints. The Service uses port 80 to publish Envoy's HTTP network endpoint and port 443 to publish Envoy's HTTPS network endpoint. \n See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer \n * NodePortService \n Publishes Envoy network endpoints using a Kubernetes NodePort Service. \n In this configuration, Envoy network endpoints use container networking. A Kubernetes NodePort Service is created to publish the network endpoints. \n See: https://kubernetes.io/docs/concepts/services-networking/service/#nodeport \n * ClusterIPService \n Publishes Envoy network endpoints using a Kubernetes ClusterIP Service. \n In this configuration, Envoy network endpoints use container networking. A Kubernetes ClusterIP Service is created to publish the network endpoints. \n See: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types",
                  "enum": [
                    "LoadBalancerService",
                    "NodePortService",
                    "ClusterIPService"
                  ],
                  "type": "string"
                }
              },
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "nodePlacement": {
          "description": "NodePlacement enables scheduling of Contour and Envoy pods onto specific nodes. \n See each field for additional details.",
          "properties": {
            "contour": {
              "description": "Contour describes node scheduling configuration of Contour pods.",
              "properties": {
                "nodeSelector": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "NodeSelector is the simplest recommended form of node selection constraint and specifies a map of key-value pairs. For the Contour pod to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels (it can have additional labels as well). \n If unset, the Contour pod(s) will be scheduled to any available node.",
                  "type": "object"
                },
                "tolerations": {
                  "description": "Tolerations work with taints to ensure that Envoy pods are not scheduled onto inappropriate nodes. One or more taints are applied to a node; this marks that the node should not accept any pods that do not tolerate the taints. \n The default is an empty list. \n See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ for additional details.",
                  "items": {
                    "description": "The pod this Toleration is attached to tolerates any taint that matches the 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. When 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. If 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. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.",
                        "type": "string"
                      },
                      "tolerationSeconds": {
                        "description": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative 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. If the operator is Exists, the value should be empty, otherwise just a regular string.",
                        "type": "string"
                      }
                    },
                    "type": "object",
                    "additionalProperties": false
                  },
                  "type": "array"
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "envoy": {
              "description": "Envoy describes node scheduling configuration of Envoy pods.",
              "properties": {
                "nodeSelector": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "NodeSelector is the simplest recommended form of node selection constraint and specifies a map of key-value pairs. For the Envoy pod to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels (it can have additional labels as well). \n If unset, the Envoy pod(s) will be scheduled to any available node.",
                  "type": "object"
                },
                "tolerations": {
                  "description": "Tolerations work with taints to ensure that Envoy pods are not scheduled onto inappropriate nodes. One or more taints are applied to a node; this marks that the node should not accept any pods that do not tolerate the taints. \n The default is an empty list. \n See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ for additional details.",
                  "items": {
                    "description": "The pod this Toleration is attached to tolerates any taint that matches the 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. When 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. If 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. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.",
                        "type": "string"
                      },
                      "tolerationSeconds": {
                        "description": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative 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. If the operator is Exists, the value should be empty, otherwise just a regular string.",
                        "type": "string"
                      }
                    },
                    "type": "object",
                    "additionalProperties": false
                  },
                  "type": "array"
                }
              },
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "replicas": {
          "default": 2,
          "description": "Replicas is the desired number of Contour replicas. If unset, defaults to 2.",
          "format": "int32",
          "minimum": 0,
          "type": "integer"
        }
      },
      "type": "object",
      "additionalProperties": false
    },
    "status": {
      "description": "Status defines the observed state of Contour.",
      "properties": {
        "availableContours": {
          "description": "AvailableContours is the number of observed available replicas according to the Contour deployment. The deployment and its pods will reside in the namespace specified by spec.namespace.name of the contour.",
          "format": "int32",
          "type": "integer"
        },
        "availableEnvoys": {
          "description": "AvailableEnvoys is the number of observed available pods from the Envoy daemonset. The daemonset and its pods will reside in the namespace specified by spec.namespace.name of the contour.",
          "format": "int32",
          "type": "integer"
        },
        "conditions": {
          "description": "Conditions represent the observations of a contour's current state. Known condition types are \"Available\". Reference the condition type for additional details.",
          "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, 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",
            "additionalProperties": false
          },
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        }
      },
      "required": [
        "availableContours",
        "availableEnvoys"
      ],
      "type": "object",
      "additionalProperties": false
    }
  },
  "type": "object"
}
