github.com/operator-framework/operator-lifecycle-manager@v0.30.0/doc/contributors/design-proposals/operator-validation-library.md (about)

     1  # Operator Validation Library
     2  
     3  ### Problem Statement
     4  
     5  This project aims to create a validation library within OLM for operators managed by OLM. Such operators are manageable by creating a manifest bundle composed of [ClusterServiceVersions](https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md), [CustomResourceDefinitions](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/), and [Package Manifest](https://github.com/operator-framework/operator-lifecycle-manager#discovery-catalogs-and-automated-upgrades) yamls. The steps to creating these files are error-prone and validation of this bundle happens in scattered places that are not always up to date with the latest changes to the manifest's definition.
     6  
     7  For example, operator-sdk's [csv-gen](https://github.com/operator-framework/operator-sdk/blob/master/doc/user/olm-catalog/generating-a-csv.md) tool uses static verification logic based on OLM's CSV type to validate the generated file. There is also [scorecard](https://github.com/operator-framework/operator-sdk/blob/master/doc/test-framework/scorecard.md) that uses runtime checks to validate the bundle. [operator-courier](https://github.com/operator-framework/operator-courier) uses static verification logic before pushing the bundles to an app-registry. Finally, the [operator-registry](https://github.com/operator-framework/operator-registry) and [olm-operator](https://github.com/operator-framework/operator-lifecycle-manager/tree/master/pkg/controller/operators/olm) both contain logic for static and runtime validation of CSVs.
     8  
     9  Each of these validates only a piece of the bundle and most are not in sync with changes to the CSV type. This means operator owners use different tools to validate their bundle - each providing partial or inconsistent validation - which dampens the user experience. The operator framework needs to agree on a single source of truth for a valid OLM-managed operator.
    10  
    11  Our plan is to bring the already defined validators scattered across various code bases (along with potentially new validators) into a single location/package with validation logic that adapts to changes made to OLM.
    12  
    13  ### Stakeholders
    14  
    15  Our main stakeholders of this library are:
    16  
    17  - OLM/operator-registry: refactoring some code to call a single validation library may help with improving user experience.
    18  - Operator-sdk: calling this library for the csv-gen tool instead of creating custom functions.
    19  - Operator-courier (or similar tool): community-operators or upstream operator owners who are not using the sdk to build their operator need a validation tool.
    20  - OSD SRE: validating bundles before pushing them down their deployment pipeline to minimize resource expenditure.
    21  
    22  ### Development Strategy
    23  
    24  As a preliminary step, this library is interested in static verification of operator bundles. Static verification is crucial to help improve the development process of operators. It is time efficient and can be used in a variety of contexts: from IDE linter extensions to CI pipelines with limited resources to command line utilities. All consistent by calling the same APIs from this library.
    25  
    26  In the future, we aim to extend this library to contain runtime tests and apis to be called by runtime tools on cluster.
    27  
    28  ### Requirements
    29  
    30  - Methods of this library should adapt to any changes in OLM's type. There should be minimal to no changes required when there is a change in OLM's type and/or version. Or if this is not possible, methods of the library need to be part of the build/test pipeline of OLM.
    31  - Better error reporting by informing the user of all errors found instead of exiting after the first occurrence. We should define custom error types easily digestible by users of these APIs.
    32  - APIs should expose verification methods for individual yaml files as well as for the bundle as a whole.
    33  - This library should expose a validator interface for users to define their own custom validators (ex: operatorhub.io specific validators) while obeying the same overarching structure.
    34  
    35  ### Progress so far
    36  
    37  [https://github.com/dweepgogia/new-manifest-verification](https://github.com/dweepgogia/new-manifest-verification)
    38  
    39  We have started with the validation of Cluster Service Version yaml files. Currently, this library checks for the following against OLM's CSV type:
    40  
    41  - Data type mismatch.
    42  - Mandatory/optional field/struct/value missing (reports errors and warnings for mandatory and optional fields, respectively). Currently, this uses the json annotation `omitempty` to determine whether the field is optional.
    43  
    44  There is also a Command Line Tool that serves as an example of how a user can interact with the library. Details on using the CLI tool can be found in the `README` of the repo above.
    45  
    46  ### Outcomes
    47  
    48  - A universally accepted definition of operator validation tests.
    49  - Improved developer experience brought about through the reduction of the number of tools required to build, test, and distribute an operator.
    50  - Stronger alignment across operator-framework teams.
    51  
    52  ### Open Questions
    53  
    54  - How do we deal with different versions of the CSV type?
    55      
    56    Ideas: 
    57    - Include a version of the library alongside the CSV type definition so that it is versioned in the same way the CSV is versioned.
    58    - To be compatible across different versions of OLM's types and changing requirements/fields within the same version, this library can use the version defined in csv yaml and enforces the field requirements accordingly for validating the manifest.
    59  
    60  # Fake README
    61  
    62  ## Installing
    63  
    64  ### Command Line Tool
    65  
    66  You can interact with this library with a command line tool. 
    67  
    68  You can install the `operator-verify` tool from source using:
    69  
    70  ```
    71  $ go install
    72  ```
    73  
    74  ```bash
    75  $ echo $PATH
    76  ```
    77  
    78  If you do not have your workspace's `bin` subdirectory in your `$PATH`, 
    79  
    80  ```bash
    81  $ export PATH=$PATH:$(go env GOPATH)/bin
    82  ```
    83  
    84  This adds your workspace's bin subdirectory to your PATH. As a result, you can use the `operator-verify` tool anywhere on your system. Otherwise, you would have to `cd` to your workspace's `bin` directory to run the executable. Verify that we can find `operator-verify` in our new `PATH`:
    85  
    86  ```bash
    87  $ which operator-verify
    88  ```
    89  
    90  This should return something like:
    91  
    92  ```
    93  ~/go/bin/operator-verify
    94  ```
    95  
    96  To verify that the library installed correctly, use it to validate the ClusterServiceVersion yaml,
    97  
    98  ```
    99  $ operator-verify csv /path/to/filename.yaml
   100  ```
   101  
   102  ## Usage
   103  
   104  The command line tool's `help` flag gives the following output:
   105  
   106  ```text
   107  operator-verify is a command line tool for the Operator Manifest Verification Library. This library provides functions to validate the operator manifest bundles against Operator-Lifecycle-Manager's clusterServiceVersion type, customResourceDefinitions, and package yamls. Currently, this application supports static validation of both individual operator files and the manifest bundle. 
   108  
   109  Usage:
   110    operator-verify [flags]
   111    operator-verify [command]
   112  
   113  Available Commands:
   114    help        Help about any command
   115    csv         Validate CSV against OLM's type
   116    crd         Validate manifest CRDs
   117    package     Validate package yaml
   118    manifest    Validate operator manifest bundle  
   119  
   120  Flags:
   121    -h, --help    help for operator-verify
   122    -i, --ignore  ignore warnings in log
   123  
   124  Use "operator-verify [command] --help" for more information about a command.
   125  ```
   126  
   127  
   128  ### Commands 
   129  **For individual files**: 
   130  
   131  ```
   132  $ operator-verify csv /path/to/csv.yaml
   133  ```
   134  
   135  Validates the given CSV yaml file against OLM type and reports errors and warnings as described in the `List of Errors` section below.
   136  
   137  Similarly, 
   138  
   139  ```
   140  $ operator-verify crd /path/to/crd.yaml
   141  ```
   142  
   143  and 
   144  
   145  ```
   146  $ operator-verify package /path/to/package.yaml
   147  ```
   148  
   149  validates CRD and package yaml, respectively. The `crd` command can accept and validate both a single yaml file and a bunch of CRDs at once and report a separate log for each.
   150  
   151  **For manifest bundle**:
   152  
   153  ```
   154  $ operator-verify manifest /path/to/bundle
   155  ```
   156  
   157  Here `path/to/bundle` is a directory structure as per the [operator manifest format](https://github.com/operator-framework/operator-registry#manifest-format). This command reports errors and/or warnings for each file in the bundle.
   158  
   159  Using the `help` flag with `manifest` command we get,
   160  
   161  ```text
   162  Validates the manifest bundle as a whole, in addition to validating individual operator files. `manifest` reports errors/warnings for each file in the bundle. It works both with a directory structure (as per operator manifest format) and an operator image. `manifest` can also validate only the CSVs or CRDs present in a bundle. See flags for more information. 
   163  
   164  Usage:
   165    operator-verify verify [flags]
   166  
   167  Flags:
   168    -h, --help    help for verify
   169    -r, --remote  remote manifest (requires operator image)
   170    --csv-only    validate only bundle CSVs
   171    --crd-only    validate only bundle CRDs  
   172  ```
   173  
   174  ### Flags
   175  
   176  To ignore warnings in the log, we have `-i` flag available, 
   177  
   178  ```
   179  $ operator-verify -i csv /path/to/csv.yaml
   180  ```
   181  
   182  This flag works similarly for other commands available in `operator-verify` tool. To validate a remote manifest, we an use the operator image with `-r` flag,
   183  
   184  ```
   185  $ operator-verify manifest -r <link to operator image>
   186  ```
   187  
   188  For validating only the CSVs or CRDs in the manifest, we have `--csv-only` and `--crd-only` flags under the `manifest` command.
   189  
   190  ```
   191  $ operator-verify manifest --csv-only or --crd-only /path/to/bundle
   192  ```
   193  
   194  We can also use these flags on remote manifest by combining the respective flags.
   195  
   196  ## Examples
   197  
   198  ```
   199  $ operator-verify csv csv.yaml
   200  ```
   201  
   202  Output of the `csv` command against a valid sample csv yaml with some missing optional fields/struct:
   203  
   204  ```
   205  Warning: Optional Field Missing (ObjectMeta.GenerateName)
   206  Warning: Optional Field Missing (ObjectMeta.SelfLink)
   207  Warning: Optional Field Missing (ObjectMeta.UID)
   208  Warning: Optional Field Missing (ObjectMeta.ResourceVersion)
   209  Warning: Optional Field Missing (ObjectMeta.Generation)
   210  Warning: Optional Struct Missing (ObjectMeta.CreationTimestamp)
   211  Warning: Optional Field Missing (ObjectMeta.DeletionTimestamp)
   212  Warning: Optional Field Missing (ObjectMeta.DeletionGracePeriodSeconds)
   213  Warning: Optional Field Missing (ObjectMeta.Labels)
   214  Warning: Optional Field Missing (ObjectMeta.OwnerReferences)
   215  Warning: Optional Field Missing (ObjectMeta.Initializers)
   216  Warning: Optional Field Missing (ObjectMeta.Finalizers)
   217  Warning: Optional Field Missing (ObjectMeta.ClusterName)
   218  Warning: Optional Field Missing (Spec.CustomResourceDefinitions.Required)
   219  Warning: Optional Struct Missing (Spec.APIServiceDefinitions)
   220  Warning: Optional Field Missing (Spec.NativeAPIs)
   221  Warning: Optional Field Missing (Spec.MinKubeVersion)
   222  Warning: Optional Field Missing (Spec.Provider.URL)
   223  Warning: Optional Field Missing (Spec.Replaces)
   224  Warning: Optional Field Missing (Spec.Annotations)
   225  csv.yaml is verified.
   226  ```
   227  
   228  Omitting `Spec.InstallStrategy.StrategyName`, one of the mandatory fields, yields
   229  
   230  ```
   231  Error: Mandatory Field Missing (Spec.InstallStrategy.StrategyName)
   232  Populate all the mandatory fields missing from csv.yaml file.
   233  ```
   234  
   235  in addition to the warnings shown above.
   236  
   237  To ignore the warnings, we have `-i` flag available.
   238  
   239  ```
   240  $ operator-verify -i csv csv.yaml
   241  ```
   242  
   243  `crd` and `package` commands work in a similar way as the `csv`. The `manifest` command returns a log similar to the one shown above for `csv` for each file in the manifest bundle. For validating just the CSVs or CRDs in the manifest, we can use the flags mentioned above.
   244  
   245  ```text
   246  Note: We can have various other APIs for validating only the CSVs or CRDs. For instance,
   247  
   248  - `csv`/`crd` command accepts both an individual file or a directory containing a group of respective files. 
   249  
   250     Usage: $operator-verify crd /path/to/directory
   251  
   252  - Using a flag for indicating a directory structure. 
   253  
   254     Usage: $operator-verify crd -d /path/to/directory
   255  ```
   256  
   257  # Library
   258  
   259  ## Getting Started
   260  
   261  The Operator Manifest Verfication library provides APIs for validating both individual yaml files and the manifest bundle as a whole. For **individual yaml files**, it checks for: 
   262  
   263  * Data type mismatch
   264  * Missing mandatory and optional fields
   265  * Incompatible configurations
   266  * Logical errors (e.g. business logic)
   267    
   268  against OLM's type.
   269  
   270  For **manifest bundle**, in addition to verifying the individual operator files, this library checks for:
   271  
   272  * CRDs mentioned in the CSV
   273  * Incompatible CSV configurations when upgrading to a newer version of CSV
   274  
   275  It accepts both nested and flattened directory structures containing manifest yamls. The  directory structure is expected to adhere to [manifest format](https://github.com/operator-framework/operator-registry#manifest-format). See `usage` for more information. 
   276  
   277  ### List of Errors
   278  
   279  * Unmarshalling errors like
   280    * Data type mismatch 
   281    * Incorrect indentation
   282    * Inconsistent yaml file structure that can't be converted to JSON for unmarshalling
   283  * Warning for any missing optional field
   284  * Error for any missing mandatory field
   285  * Error for missing CRDs which are mentioned in the CSV
   286  
   287  Errors and warnings returned by the API are of type `missingTypeError` and can be used to extract more information. `missingTypeError` is struct type and its implementation in the library is as follows,
   288  
   289  ```go
   290  type missingTypeError struct {
   291  	err         string
   292  	typeName    string
   293  	path        string
   294  	isMandatory bool
   295  }
   296  ```
   297  
   298  For each error/warning, we can check if it's a field or a struct (`typeName`), path of that field in the nested yaml file (`path`), and if the field is mandatory or not (`isMandatory`).