Skip to content

Discussion: How to add CLI meta data to Source CRDs ? #1940

@rhuss

Description

@rhuss

Problem

For helping kn (or any other CLI) it would be very helpful when a Source CRD would carry some extra meta information for mapping cli-options (like --access-token or --event-types for a GitHubSource) to the property within the CR (e.g. .spec.accessToken.secreteKeyRef for --access-token and .spect.eventTypes for --event-types).

Fortunately, OpenAPI schema supports so-called Specification Extensions in a Schema Object. These are fields starting with a x-

So ideally a GitHubSource CRD could look like in the example below (where I picked up the existing GitHub source, and added the required meta information to the properties which are supposed to be mapped. I also moved the registry types away from the schema to annotations, but that's not important here)

GitHub Source with `x-cli-` annotations
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: githubsources.sources.eventing.knative.dev
  labels:
    contrib.eventing.knative.dev/release: devel
    eventing.knative.dev/source: "true"
    knative.dev/crd-install: "true"
  annotations:
    registry.knative.dev/check_suite.type: dev.knative.source.github.check_suite
    registry.knative.dev/commit_comment.type: dev.knative.source.github.commit_comment
    registry.knative.dev/create.type: dev.knative.source.github.create
    registry.knative.dev/delete.type: dev.knative.source.github.delete
    registry.knative.dev/deployment.type: dev.knative.source.github.deployment
    registry.knative.dev/deployment_status.type: dev.knative.source.github.deployment_status
    registry.knative.dev/fork.type: dev.knative.source.github.fork
    registry.knative.dev/gollum.type: dev.knative.source.github.gollum
    registry.knative.dev/installation.type: dev.knative.source.github.installation
    registry.knative.dev/integration_installation.type: dev.knative.source.github.integration_installation
    registry.knative.dev/issue_comment.type: dev.knative.source.github.issue_comment
    registry.knative.dev/issues.type: dev.knative.source.github.issues
    registry.knative.dev/member.type: dev.knative.source.github.member
    registry.knative.dev/milestone.type: dev.knative.source.github.milestone
    registry.knative.dev/org_block.type: dev.knative.source.github.org_block
    registry.knative.dev/ping.type: dev.knative.source.github.ping
    registry.knative.dev/project_column.type: dev.knative.source.github.project_column
    registry.knative.dev/public.type: dev.knative.source.github.public
    registry.knative.dev/pull_request_review.type: dev.knative.source.github.pull_request_review
    registry.knative.dev/push.type: dev.knative.source.github.push
    registry.knative.dev/repository.type: dev.knative.source.github.repository
    registry.knative.dev/team.type: dev.knative.source.github.team
    registry.knative.dev/watch.type: dev.knative.source.github.watch
spec:
  group: sources.eventing.knative.dev
  names:
    categories:
    - all
    - knative
    - eventing
    - sources
    kind: GitHubSource
    plural: githubsources
  scope: Namespaced
  subresources:
    status: {}
  validation:
    openAPIV3Schema:
      properties:
        spec:
          properties:
            accessToken:
              properties:
                secretKeyRef:
                  # Name of a cli option mapping to this field
                  x-cli-option: "access-token"
                  # Type which triggers a special treatment of the option to
                  # create the embedded opject with a `key:` and `name:` field
                  x-cli-type: "map-selector"
                  # Help message which can be used by a CLI on the help page
                  x-cli-help: "GitHub access token. The value of this option is the name of a secret and key within secret to GitHub access, dot separated (e.g. --secret-token=mygithubsecret.mykey) "
                  type: object
              type: object
            eventTypes:
              items:
                enum:
                - check_suite
                - commit_comment
                - create
                - delete
                - deployment
                - deployment_status
                - fork
                - gollum
                - installation
                - integration_installation
                - issue_comment
                - issues
                - label
                - member
                - membership
                - milestone
                - organization
                - org_block
                - page_build
                - ping
                - project_card
                - project_column
                - project
                - public
                - pull_request
                - pull_request_review
                - pull_request_review_comment
                - push
                - release
                - repository
                - status
                - team
                - team_add
                - watch
                type: string
              minItems: 1
              x-cli-option: "event-type"
              x-cli-help: "GitHub events to watch for. This is a comma separated list of options. Alternatively this option can be provided multiple times."
              type: array
            ownerAndRepository:
              x-cli-option: "owner"
              minLength: 1
              type: string
            secretToken:
              properties:
                secretKeyRef:
                  x-cli-option: "secret-token"
                  x-cli-type: "map-selector"
                  x-cli-help: "GitHub secret token. The value of this option is the name of a secret and key within secret to GitHub access, dot separated (e.g. --secret-token=mygithubsecret.mykey) "
                  type: object
              type: object
            serviceAccountName:
              x-cli-option: "service-account"
              x-cli-help: "Service account"
              type: string
            sink:
              type: object
          required:
          - ownerAndRepository
          - eventTypes
          - accessToken
          - secretToken
          type: object
        status:
          properties:
            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
            webhookIDKey:
              type: string
          type: object
  version: v1alpha1

Unfortunately, Kubernetes does not support this (see kubernetes/kubernetes#82942 and also the API docs for CRDs where it seems only a fixed set of x-kubernetes- fields are supported

😞

The question is how to proceed:

  • Wait if Kubernetes fix this ? (if even the issue is not rejected with wontfix)
  • Creatively "reuse" one of the existing fields of the OpenAPI Schema Object Spec, like
  • example: "A free-form property to include an example of an instance for this schema. To represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary."
  • externalDocs : An object with description and url field

An solution would be also to put the mapping into CRD annotations with the cli-option as key and the JSON path expression as value (or having a single annotation which has a JSON mapping as value), e.g

annotations:
  client.knative.dev/access-token.option=.spec.accessToken.secretRef
  client.knative.dev/access-token.help="GitHub access token. The value of this option is the name of a secret and key within secret to GitHub access, dot separated (e.g. --secret-token=mygithubsecret.mykey)"
  client.knative.dev/access-token.type="map-selector"

Tbh, I would prefer a hook into the schema as it feels that it belongs to the schema as an 'annotation' kind.

What do you think about the proposal or is there any other way to help the client to create CRs from flat command line options ?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions