# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  labels:
    events.cloud.google.com/release: devel
    events.cloud.google.com/crd-install: "true"
  name: pullsubscriptions.internal.events.cloud.google.com
spec:
  group: internal.events.cloud.google.com
  names:
    categories:
    - all
    - knative
    - pubsub
    kind: PullSubscription
    plural: pullsubscriptions
  scope: Namespaced
  preserveUnknownFields: false
  conversion:
    strategy: Webhook
    webhook:
      # conversionReviewVersions indicates what ConversionReview versions are understood/preferred by the webhook.
      # The first version in the list understood by the API server is sent to the webhook.
      # The webhook must respond with a ConversionReview object in the same version it received.
      conversionReviewVersions: ["v1", "v1beta1"]
      clientConfig:
        service:
          name: webhook
          namespace: events-system
  versions:
  - &version
    name: v1
    served: true
    storage: true
    subresources:
      status: {}
    additionalPrinterColumns:
    - name: Ready
      type: string
      jsonPath: ".status.conditions[?(@.type==\"Ready\")].status"
    - name: Reason
      type: string
      jsonPath: ".status.conditions[?(@.type==\"Ready\")].reason"
    - name: Age
      type: date
      jsonPath: .metadata.creationTimestamp
    # We remove spec.properties.mode and status.properties.serviceAccountName from v1.
    schema:
      openAPIV3Schema: &openAPIV3Schema
        type: object
        properties: &properties
          spec: &spec
            # TODO: update the OpenAPI to be much more robust.
            type: object
            required:
              - sink
              - topic
            properties: &specProperties
              serviceAccountName:
                type: string
                description: "Kubernetes service account used to bind to a google service account to poll the Cloud Pub/Sub Subscription. The value of the Kubernetes service account must be a valid DNS subdomain name. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)"
              secret:
                type: object
                description: "Credential used to poll the Cloud Pub/Sub Subscription. It is not used to create or delete the Subscription, only to poll it. The value of the secret entry must be a service account key in the JSON format (see https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Defaults to secret.name of 'google-cloud-key' and secret.key of 'key.json'."
                properties:
                  name:
                    type: string
                  key:
                    type: string
                  optional:
                    type: boolean
              project:
                type: string
                description: "ID of the Google Cloud Project that the Pub/Sub Topic exists in. E.g. 'my-project-1234' rather than its display name, 'My Project' or its number '1234567890'. If omitted uses the Project ID from the GKE cluster metadata service."
              sink:
                type: object
                description: "Reference to an object that will resolve to a domain name to use as the sink."
                properties:
                  uri:
                    type: string
                    minLength: 1
                  ref:
                    type: object
                    required:
                      - apiVersion
                      - kind
                      - name
                    properties:
                      apiVersion:
                        type: string
                        minLength: 1
                      kind:
                        type: string
                        minLength: 1
                      namespace:
                        type: string
                      name:
                        type: string
                        minLength: 1
              transformer:
                type: object
                description: "Reference to an object that will resolve to a domain name to use as the transformer."
                x-kubernetes-preserve-unknown-fields: true
              ceOverrides:
                type: object
                description: "Defines overrides to control modifications of the event sent to the sink."
                properties:
                  extensions:
                    type: object
                    description: "Extensions specify what attribute are added or overridden on the outbound event. Each `Extensions` key-value pair are set on the event as an attribute extension independently."
                    x-kubernetes-preserve-unknown-fields: true
              topic:
                type: string
                description: "ID of the Cloud Pub/Sub Topic to Subscribe to. It must be in the form of the unique identifier within the project, not the entire name. E.g. it must be 'laconia', not 'projects/my-gcp-project/topics/laconia'."
              ackDeadline:
                type: string
                description:  "The default maximum time after a subscriber receives a message before the subscriber should acknowledge the message. Defaults to `30s`. Valid time units are `s`, `m`, `h`. The minimum deadline you can specify is 0 seconds. The maximum deadline you can specify is 600 seconds (10 minutes)."
              retainAckedMessages:
                type: boolean
                description: "Whether to retain acknowledged messages. If true, acknowledged messages will not be expunged until they fall out of the RetentionDuration window."
              retentionDuration:
                type: string
                description: "How long to retain messages in backlog, from the time of publish. If retainAckedMessages is true, this duration affects the retention of acknowledged messages, otherwise only unacknowledged messages are retained. Defaults to 7 days (`168h`). Cannot be longer than 7 days or shorter than 10 minutes. Valid time units are `s`, `m`, `h`."
              adapterType:
                type: string
                description: "AdapterType determines the type of receive adapter that a PullSubscription uses."
          status: &status
            type: object
            properties: &statusProperties
              observedGeneration:
                type: integer
                format: int64
              conditions:
                items:
                  properties:
                    lastTransitionTime:
                      # we use a string in the stored object but a wrapper object
                      # at runtime.
                      type: string
                    message:
                      type: string
                    reason:
                      type: string
                    severity:
                      type: string
                    status:
                      type: string
                    type:
                      type: string
                  required:
                    - type
                    - status
                  type: object
                type: array
              sinkUri:
                type: string
              ceAttributes:
                type: array
                items:
                  type: object
                  properties:
                    type:
                      type: string
                    source:
                      type: string
              projectId:
                type: string
              topicId:
                type: string
              subscriptionId:
                type: string
              transformerUri:
                type: string
  - << : *version
    name: v1beta1
    served: true
    storage: false
    # v1beta has spec.properties.mode and status.properties.serviceAccountName in the schema
    schema:
      openAPIV3Schema:
        << : *openAPIV3Schema
        properties:
          << : *properties
          spec:
            << : *spec
            properties:
              << : *specProperties
              mode:
                type: string
                enum: [CloudEventsBinary, CloudEventsStructured, PushCompatible]
                description: "Mode defines the encoding and structure of the payload of when this PullSubscription invokes the sink. Default is CloudEventsBinary."
          status:
            << : *status
            properties:
              << : *statusProperties
              serviceAccountName:
                type: string
