{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "apiVersion": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "spec": {
      "properties": {
        "listeners": {
          "items": {
            "properties": {
              "allowedRoutes": {
                "default": {
                  "namespaces": {
                    "from": "Same"
                  }
                },
                "properties": {
                  "kinds": {
                    "items": {
                      "properties": {
                        "group": {
                          "default": "gateway.networking.k8s.io",
                          "maxLength": 253,
                          "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                          "type": "string"
                        },
                        "kind": {
                          "maxLength": 63,
                          "minLength": 1,
                          "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind"
                      ],
                      "type": "object"
                    },
                    "maxItems": 8,
                    "type": "array",
                    "x-kubernetes-list-type": "atomic"
                  },
                  "namespaces": {
                    "default": {
                      "from": "Same"
                    },
                    "properties": {
                      "from": {
                        "default": "Same",
                        "enum": [
                          "All",
                          "Selector",
                          "Same"
                        ],
                        "type": "string"
                      },
                      "selector": {
                        "properties": {
                          "matchExpressions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "operator": {
                                  "type": "string"
                                },
                                "values": {
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array",
                                  "x-kubernetes-list-type": "atomic"
                                }
                              },
                              "required": [
                                "key",
                                "operator"
                              ],
                              "type": "object"
                            },
                            "type": "array",
                            "x-kubernetes-list-type": "atomic"
                          },
                          "matchLabels": {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "type": "object"
                          }
                        },
                        "type": "object",
                        "x-kubernetes-map-type": "atomic"
                      }
                    },
                    "type": "object"
                  }
                },
                "type": "object"
              },
              "hostname": {
                "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"
              },
              "name": {
                "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"
              },
              "port": {
                "format": "int32",
                "maximum": 65535,
                "minimum": 1,
                "type": "integer"
              },
              "protocol": {
                "maxLength": 255,
                "minLength": 1,
                "pattern": "^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$",
                "type": "string"
              },
              "tls": {
                "properties": {
                  "certificateRefs": {
                    "items": {
                      "properties": {
                        "group": {
                          "default": "",
                          "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": "Secret",
                          "maxLength": 63,
                          "minLength": 1,
                          "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                          "type": "string"
                        },
                        "name": {
                          "maxLength": 253,
                          "minLength": 1,
                          "type": "string"
                        },
                        "namespace": {
                          "maxLength": 63,
                          "minLength": 1,
                          "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "name"
                      ],
                      "type": "object"
                    },
                    "maxItems": 64,
                    "type": "array",
                    "x-kubernetes-list-type": "atomic"
                  },
                  "mode": {
                    "default": "Terminate",
                    "enum": [
                      "Terminate",
                      "Passthrough"
                    ],
                    "type": "string"
                  },
                  "options": {
                    "additionalProperties": {
                      "maxLength": 4096,
                      "minLength": 0,
                      "type": "string"
                    },
                    "maxProperties": 16,
                    "type": "object"
                  }
                },
                "type": "object",
                "x-kubernetes-validations": [
                  {
                    "message": "certificateRefs or options must be specified when mode is Terminate",
                    "rule": "self.mode == 'Terminate' ? size(self.certificateRefs) > 0 || size(self.options) > 0 : true"
                  }
                ]
              }
            },
            "required": [
              "name",
              "port",
              "protocol"
            ],
            "type": "object"
          },
          "maxItems": 64,
          "minItems": 1,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "name"
          ],
          "x-kubernetes-list-type": "map",
          "x-kubernetes-validations": [
            {
              "message": "tls must not be specified for protocols ['HTTP', 'TCP', 'UDP']",
              "rule": "self.all(l, l.protocol in ['HTTP', 'TCP', 'UDP'] ? !has(l.tls) : true)"
            },
            {
              "message": "tls mode must be Terminate for protocol HTTPS",
              "rule": "self.all(l, (l.protocol == 'HTTPS' && has(l.tls)) ? (l.tls.mode == '' || l.tls.mode == 'Terminate') : true)"
            },
            {
              "message": "tls mode must be set for protocol TLS",
              "rule": "self.all(l, (l.protocol == 'TLS' ? has(l.tls) && has(l.tls.mode) && l.tls.mode != '' : true))"
            },
            {
              "message": "hostname must not be specified for protocols ['TCP', 'UDP']",
              "rule": "self.all(l, l.protocol in ['TCP', 'UDP']  ? (!has(l.hostname) || l.hostname == '') : true)"
            },
            {
              "message": "Listener name must be unique within the Gateway",
              "rule": "self.all(l1, self.exists_one(l2, l1.name == l2.name))"
            },
            {
              "message": "Combination of port, protocol and hostname must be unique for each listener",
              "rule": "self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port) && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
            }
          ]
        },
        "parentRef": {
          "properties": {
            "group": {
              "default": "gateway.networking.k8s.io",
              "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",
              "maxLength": 63,
              "minLength": 1,
              "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
              "type": "string"
            },
            "name": {
              "maxLength": 253,
              "minLength": 1,
              "type": "string"
            },
            "namespace": {
              "maxLength": 63,
              "minLength": 1,
              "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
              "type": "string"
            }
          },
          "required": [
            "name"
          ],
          "type": "object"
        }
      },
      "required": [
        "listeners",
        "parentRef"
      ],
      "type": "object"
    },
    "status": {
      "default": {
        "conditions": [
          {
            "lastTransitionTime": "1970-01-01T00:00:00Z",
            "message": "Waiting for controller",
            "reason": "Pending",
            "status": "Unknown",
            "type": "Accepted"
          },
          {
            "lastTransitionTime": "1970-01-01T00:00:00Z",
            "message": "Waiting for controller",
            "reason": "Pending",
            "status": "Unknown",
            "type": "Programmed"
          }
        ]
      },
      "properties": {
        "conditions": {
          "default": [
            {
              "lastTransitionTime": "1970-01-01T00:00:00Z",
              "message": "Waiting for controller",
              "reason": "Pending",
              "status": "Unknown",
              "type": "Accepted"
            },
            {
              "lastTransitionTime": "1970-01-01T00:00:00Z",
              "message": "Waiting for controller",
              "reason": "Pending",
              "status": "Unknown",
              "type": "Programmed"
            }
          ],
          "items": {
            "properties": {
              "lastTransitionTime": {
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "maxLength": 32768,
                "type": "string"
              },
              "observedGeneration": {
                "format": "int64",
                "minimum": 0,
                "type": "integer"
              },
              "reason": {
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                "type": "string"
              },
              "status": {
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ],
                "type": "string"
              },
              "type": {
                "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,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        },
        "listeners": {
          "items": {
            "properties": {
              "attachedRoutes": {
                "format": "int32",
                "type": "integer"
              },
              "conditions": {
                "items": {
                  "properties": {
                    "lastTransitionTime": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "message": {
                      "maxLength": 32768,
                      "type": "string"
                    },
                    "observedGeneration": {
                      "format": "int64",
                      "minimum": 0,
                      "type": "integer"
                    },
                    "reason": {
                      "maxLength": 1024,
                      "minLength": 1,
                      "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "True",
                        "False",
                        "Unknown"
                      ],
                      "type": "string"
                    },
                    "type": {
                      "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,
                "type": "array",
                "x-kubernetes-list-map-keys": [
                  "type"
                ],
                "x-kubernetes-list-type": "map"
              },
              "name": {
                "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"
              },
              "supportedKinds": {
                "items": {
                  "properties": {
                    "group": {
                      "default": "gateway.networking.k8s.io",
                      "maxLength": 253,
                      "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                      "type": "string"
                    },
                    "kind": {
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "kind"
                  ],
                  "type": "object"
                },
                "maxItems": 8,
                "type": "array",
                "x-kubernetes-list-type": "atomic"
              }
            },
            "required": [
              "attachedRoutes",
              "conditions",
              "name"
            ],
            "type": "object"
          },
          "maxItems": 64,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "name"
          ],
          "x-kubernetes-list-type": "map"
        }
      },
      "type": "object"
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}
