{
  "description": "CatalogSource is a repository of CSVs, CRDs, and operator packages.",
  "type": "object",
  "required": [
    "metadata",
    "spec"
  ],
  "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": {
      "type": "object",
      "required": [
        "sourceType"
      ],
      "properties": {
        "address": {
          "description": "Address is a host that OLM can use to connect to a pre-existing registry. Format: <registry-host or ip>:<port> Only used when SourceType = SourceTypeGrpc. Ignored when the Image field is set.",
          "type": "string"
        },
        "configMap": {
          "description": "ConfigMap is the name of the ConfigMap to be used to back a configmap-server registry. Only used when SourceType = SourceTypeConfigmap or SourceTypeInternal.",
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "displayName": {
          "description": "Metadata",
          "type": "string"
        },
        "grpcPodConfig": {
          "description": "GrpcPodConfig exposes different overrides for the pod spec of the CatalogSource Pod. Only used when SourceType = SourceTypeGrpc and Image is set.",
          "type": "object",
          "properties": {
            "nodeSelector": {
              "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node.",
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            },
            "priorityClassName": {
              "description": "If specified, indicates the pod's priority. If not specified, the pod priority will be default or zero if there is no default.",
              "type": "string"
            },
            "securityContextConfig": {
              "description": "SecurityContextConfig can be one of `legacy` or `restricted`. The CatalogSource's pod is either injected with the right pod.spec.securityContext and pod.spec.container[*].securityContext values to allow the pod to run in Pod Security Admission (PSA) `restricted` mode, or doesn't set these values at all, in which case the pod can only be run in PSA `baseline` or `privileged` namespaces. Currently if the SecurityContextConfig is unspecified, the default value of `legacy` is used. Specifying a value other than `legacy` or `restricted` result in a validation error. When using older catalog images, which could not be run in `restricted` mode, the SecurityContextConfig should be set to `legacy`. \n In a future version will the default will be set to `restricted`, catalog maintainers should rebuild their catalogs with a version of opm that supports running catalogSource pods in `restricted` mode to prepare for these changes. \n More information about PSA can be found here: https://kubernetes.io/docs/concepts/security/pod-security-admission/'",
              "type": "string",
              "default": "legacy",
              "enum": [
                "legacy",
                "restricted"
              ]
            },
            "tolerations": {
              "description": "Tolerations are the catalog source's pod's tolerations.",
              "type": "array",
              "items": {
                "description": "The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.",
                "type": "object",
                "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.",
                    "type": "integer",
                    "format": "int64"
                  },
                  "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"
                  }
                },
                "additionalProperties": false
              }
            }
          },
          "additionalProperties": false
        },
        "icon": {
          "type": "object",
          "required": [
            "base64data",
            "mediatype"
          ],
          "properties": {
            "base64data": {
              "type": "string"
            },
            "mediatype": {
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        "image": {
          "description": "Image is an operator-registry container image to instantiate a registry-server with. Only used when SourceType = SourceTypeGrpc. If present, the address field is ignored.",
          "type": "string"
        },
        "priority": {
          "description": "Priority field assigns a weight to the catalog source to prioritize them so that it can be consumed by the dependency resolver. Usage: Higher weight indicates that this catalog source is preferred over lower weighted catalog sources during dependency resolution. The range of the priority value can go from positive to negative in the range of int32. The default value to a catalog source with unassigned priority would be 0. The catalog source with the same priority values will be ranked lexicographically based on its name.",
          "type": "integer"
        },
        "publisher": {
          "type": "string"
        },
        "secrets": {
          "description": "Secrets represent set of secrets that can be used to access the contents of the catalog. It is best to keep this list small, since each will need to be tried for every catalog entry.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "sourceType": {
          "description": "SourceType is the type of source",
          "type": "string"
        },
        "updateStrategy": {
          "description": "UpdateStrategy defines how updated catalog source images can be discovered Consists of an interval that defines polling duration and an embedded strategy type",
          "type": "object",
          "properties": {
            "registryPoll": {
              "type": "object",
              "properties": {
                "interval": {
                  "description": "Interval is used to determine the time interval between checks of the latest catalog source version. The catalog operator polls to see if a new version of the catalog source is available. If available, the latest image is pulled and gRPC traffic is directed to the latest catalog source.",
                  "type": "string"
                }
              },
              "additionalProperties": false
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "status": {
      "type": "object",
      "properties": {
        "conditions": {
          "description": "Represents the state of a CatalogSource. Note that Message and Reason represent the original status information, which may be migrated to be conditions based in the future. Any new features introduced will use conditions.",
          "type": "array",
          "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 }",
            "type": "object",
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "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.",
                "type": "string",
                "format": "date-time"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition. This may be an empty string.",
                "type": "string",
                "maxLength": 32768
              },
              "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.",
                "type": "integer",
                "format": "int64",
                "minimum": 0
              },
              "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",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "type": "string",
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ]
              },
              "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",
                "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])$"
              }
            },
            "additionalProperties": false
          },
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        },
        "configMapReference": {
          "type": "object",
          "required": [
            "name",
            "namespace"
          ],
          "properties": {
            "lastUpdateTime": {
              "type": "string",
              "format": "date-time"
            },
            "name": {
              "type": "string"
            },
            "namespace": {
              "type": "string"
            },
            "resourceVersion": {
              "type": "string"
            },
            "uid": {
              "description": "UID is a type that holds unique ID values, including UUIDs.  Because we don't ONLY use UUIDs, this is an alias to string.  Being a type captures intent and helps make sure that UIDs and names do not get conflated.",
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        "connectionState": {
          "type": "object",
          "required": [
            "lastObservedState"
          ],
          "properties": {
            "address": {
              "type": "string"
            },
            "lastConnect": {
              "type": "string",
              "format": "date-time"
            },
            "lastObservedState": {
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        "latestImageRegistryPoll": {
          "description": "The last time the CatalogSource image registry has been polled to ensure the image is up-to-date",
          "type": "string",
          "format": "date-time"
        },
        "message": {
          "description": "A human readable message indicating details about why the CatalogSource is in this condition.",
          "type": "string"
        },
        "reason": {
          "description": "Reason is the reason the CatalogSource was transitioned to its current state.",
          "type": "string"
        },
        "registryService": {
          "type": "object",
          "properties": {
            "createdAt": {
              "type": "string",
              "format": "date-time"
            },
            "port": {
              "type": "string"
            },
            "protocol": {
              "type": "string"
            },
            "serviceName": {
              "type": "string"
            },
            "serviceNamespace": {
              "type": "string"
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
  }
}
