# 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:
    duck.knative.dev/source: "true"
    events.cloud.google.com/release: devel
    events.cloud.google.com/crd-install: "true"
  annotations:
    registry.knative.dev/eventTypes: |
      [
        { "type": "google.cloud.pubsub.topic.v1.messagePublished", "schema": "https://raw.githubusercontent.com/googleapis/google-cloudevents/master/proto/google/events/cloud/pubsub/v1/data.proto", "description": "This event is sent when a message is published to a Cloud Pub/Sub topic."}
      ]
  name: cloudpubsubsources.events.cloud.google.com
spec:
  group: events.cloud.google.com
  names:
    categories:
    - all
    - knative
    - cloudpubsubsource
    - sources
    kind: CloudPubSubSource
    plural: cloudpubsubsources
  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 status.ServiceAccountName from the schema in v1.
    schema:
      openAPIV3Schema: &openAPIV3Schema
        type: object
        properties: &properties
          spec:
            type: object
            required:
              - sink
              - topic
            properties:
              sink:
                type: object
                description: >
                  Sink which receives the notifications.
                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
              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
              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: >
                  Google Cloud Project ID of the project into which the topic should be created. If omitted uses
                  the Project ID from the GKE cluster metadata service.
              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`.
          status: &status
            type: object
            properties: &statusProperties
              observedGeneration:
                type: integer
                format: int64
              conditions:
                type: array
                items:
                  type: object
                  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
              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
  - <<: *version
    name: v1alpha1
    # TODO: Flip served bit of v1alpha1 in https://github.com/google/knative-gcp/issues/1544.
    served: true
    storage: false
    # v1alpha1 and v1beta have status.properties.serviceAccountName in the schema
    schema: &v1alpha1Schema
      openAPIV3Schema:
        <<: *openAPIV3Schema
        properties:
          <<: *properties
          status:
            <<: *status
            properties:
              <<: *statusProperties
              serviceAccountName:
                type: string
  - <<: *version
    name: v1beta1
    served: true
    storage: false
    # the schema of v1beta1 is exactly the same as v1alpha1 schema
    schema: *v1alpha1Schema
