operator-framework / operator-courier

Build, verify and push operators
Apache License 2.0
41 stars 53 forks source link

operator-courier is not able to validate spec.versions, looks only for deprecated spec.version #163

Open aneeshkp opened 4 years ago

aneeshkp commented 4 years ago

Running operator-courier verify fails to validate crd with spec.versions and looks only for deprecated spec.version ERROR: crd spec.version not defined.

Expected: operator courier should be able to validate both spec.versions and deprecated spec.version with a warning message. link to show deprecated version and new versions https://github.com/kubernetes/apiextensions-apiserver/blob/9f17d72d862ef8e7e718fb15395f34e9512e2842/pkg/apis/apiextensions/types.go#L40

IBMRob commented 4 years ago

This issue prevents operator-courier from validating CRDs generated using operator-sdk v0.17.0 when the --crd-version v1 flag is used.

xiangjingli commented 4 years ago

The issue is also found when validating our new placmentrule CRDs generated by operator-sdk v 0.18.0

operator-courier is still looking for the deprecated spec.version instread of spec.versions.

Hope the issue will be fixed in operator-courier ASAP. Or all the new CRDs generated by latest operator-sdk will not pass the operator-courier validation and will not be abled to be uploaded to operator community.

% operator-courier verify --ui_validate_io multicluster-operators-subscription 
ERROR: crd spec.version not defined. [0.1.6/apps.open-cluster-management.io_placementrules_crd.yaml]

and Here is the CRD for the ref

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: placementrules.apps.open-cluster-management.io
spec:
  group: apps.open-cluster-management.io
  names:
    kind: PlacementRule
    listKind: PlacementRuleList
    plural: placementrules
    singular: placementrule
  scope: Namespaced
  versions:
  - additionalPrinterColumns:
    - jsonPath: .metadata.creationTimestamp
      name: Age
      type: date
    name: v1
    schema:
      openAPIV3Schema:
        description: PlacementRule is the Schema for the placementrules API
        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:
            description: PlacementRuleSpec defines the desired state of PlacementRule
            properties:
              clusterConditions:
                items:
                  description: ClusterConditionFilter defines filter to filter cluster
                    condition
                  properties:
                    status:
                      type: string
                    type:
                      type: string
                  type: object
                type: array
              clusterReplicas:
                description: number of replicas Application wants to
                format: int32
                type: integer
              clusterSelector:
                description: A label selector is a label query over a set of resources.
                  The result of matchLabels and matchExpressions are ANDed. An empty
                  label selector matches all objects. A null label selector matches
                  no objects.
                properties:
                  matchExpressions:
                    description: matchExpressions is a list of label selector requirements.
                      The requirements are ANDed.
                    items:
                      description: A label selector requirement is a selector that
                        contains values, a key, and an operator that relates the key
                        and values.
                      properties:
                        key:
                          description: key is the label key that the selector applies
                            to.
                          type: string
                        operator:
                          description: operator represents a key's relationship to
                            a set of values. Valid operators are In, NotIn, Exists
                            and DoesNotExist.
                          type: string
                        values:
                          description: values is an array of string values. If the
                            operator is In or NotIn, the values array must be non-empty.
                            If the operator is Exists or DoesNotExist, the values
                            array must be empty. This array is replaced during a strategic
                            merge patch.
                          items:
                            type: string
                          type: array
                      required:
                      - key
                      - operator
                      type: object
                    type: array
                  matchLabels:
                    additionalProperties:
                      type: string
                    description: matchLabels is a map of {key,value} pairs. A single
                      {key,value} in the matchLabels map is equivalent to an element
                      of matchExpressions, whose key field is "key", the operator
                      is "In", and the values array contains only "value". The requirements
                      are ANDed.
                    type: object
                type: object
              clusters:
                items:
                  description: GenericClusterReference - in alignment with kubefed
                  properties:
                    name:
                      type: string
                  required:
                  - name
                  type: object
                type: array
              policies:
                description: Set Policy Filters
                items:
                  description: 'ObjectReference contains enough information to let
                    you inspect or modify the referred object. --- New uses of this
                    type are discouraged because of difficulty describing its usage
                    when embedded in APIs.  1. Ignored fields.  It includes many fields
                    which are not generally honored.  For instance, ResourceVersion
                    and FieldPath are both very rarely valid in actual usage.  2.
                    Invalid usage help.  It is impossible to add specific help for
                    individual usage.  In most embedded usages, there are particular     restrictions
                    like, "must refer only to types A and B" or "UID not honored"
                    or "name must be restricted".     Those cannot be well described
                    when embedded.  3. Inconsistent validation.  Because the usages
                    are different, the validation rules are different by usage, which
                    makes it hard for users to predict what will happen.  4. The fields
                    are both imprecise and overly precise.  Kind is not a precise
                    mapping to a URL. This can produce ambiguity     during interpretation
                    and require a REST mapping.  In most cases, the dependency is
                    on the group,resource tuple     and the version of the actual
                    struct is irrelevant.  5. We cannot easily change it.  Because
                    this type is embedded in many locations, updates to this type     will
                    affect numerous schemas.  Don''t make new APIs embed an underspecified
                    API type they do not control. Instead of using this type, create
                    a locally provided and used type that is well-focused on your
                    reference. For example, ServiceReferences for admission registration:
                    https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
                    .'
                  properties:
                    apiVersion:
                      description: API version of the referent.
                      type: string
                    fieldPath:
                      description: 'If referring to a piece of an object instead of
                        an entire object, this string should contain a valid JSON/Go
                        field access statement, such as desiredState.manifest.containers[2].
                        For example, if the object reference is to a container within
                        a pod, this would take on a value like: "spec.containers{name}"
                        (where "name" refers to the name of the container that triggered
                        the event) or if no container name is specified "spec.containers[2]"
                        (container with index 2 in this pod). This syntax is chosen
                        only to have some well-defined way of referencing a part of
                        an object. TODO: this design is not final and this field is
                        subject to change in the future.'
                      type: string
                    kind:
                      description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
                      type: string
                    name:
                      description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
                      type: string
                    namespace:
                      description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
                      type: string
                    resourceVersion:
                      description: 'Specific resourceVersion to which this reference
                        is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
                      type: string
                    uid:
                      description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
                      type: string
                  type: object
                type: array
              resourceHint:
                description: Select Resource
                properties:
                  order:
                    description: SelectionOrder is the type for Nodes
                    type: string
                  type:
                    description: ResourceType defines types can be sorted
                    type: string
                type: object
              schedulerName:
                description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
                  Important: Run "make" to regenerate code after modifying this file
                  schedulerName, default to use mcm controller'
                type: string
            type: object
          status:
            description: PlacementRuleStatus defines the observed state of PlacementRule
            properties:
              decisions:
                description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
                  of cluster Important: Run "make" to regenerate code after modifying
                  this file'
                items:
                  description: PlacementDecision defines the decision made by controller
                  properties:
                    clusterName:
                      type: string
                    clusterNamespace:
                      type: string
                  type: object
                type: array
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}