Skip to content

Commit f6932d0

Browse files
authored
Merge pull request #924 from galletti94/master
Operator validation library project proposal
2 parents 53524d1 + f290b76 commit f6932d0

File tree

1 file changed

+298
-0
lines changed

1 file changed

+298
-0
lines changed
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
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/Documentation/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`).

0 commit comments

Comments
 (0)