Skip to content

Commit eb48f76

Browse files
committedJul 30, 2020
feat(registry): Add label dependency constraint and property
1. Introduce a new type of dependency constraint named `olm.label` which represents the constraints that are based on CSV labels. 2. The new label property is parsed from CSV labels. Signed-off-by: Vu Dinh <[email protected]>
1 parent 3da2d18 commit eb48f76

15 files changed

+498
-29
lines changed
 

‎docs/design/operator-bundle.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,24 @@ annotations:
6969

7070
The dependencies of an operator are listed as a list in `dependencies.yaml` file inside `/metadata` folder of a bundle. This file is optional and only used to specify explicit operator version dependencies at first. Eventually, operator authors can migrate the API-based dependencies into `dependencies.yaml` as well in the future. The ultimate goal is to have `dependencies.yaml` as a centralized metadata for operator dependencies and moving the dependency information away from CSV.
7171

72-
The dependency list will contain a `type` field for each item to specify what kind of dependency this is. There are two supported `type` of operator dependencies. It can be a package type (`olm.package`) meaning this is a dependency for a specific operator version. For `olm.package` type, the dependency information should include the `package` name and the `version` of the package in semver format. We use `blang/semver` library for semver parsing (https://github.com/blang/semver). For example, you can specify an exact version such as `0.5.2` or a range of version such as `>0.5.1` (https://github.com/blang/semver#ranges). In addition, the author can specify dependency that is similiar to existing CRD/API-based using `olm.gvk` type and then specify GVK information as how it is done in CSV. This is a path to enable operator authors to consolidate all dependencies (API or explicit version) to be in the same place.
72+
The dependency list will contain a `type` field for each item to specify what kind of dependency this is. There are two supported `type` of operator dependencies. It can be a package type (`olm.package`) meaning this is a dependency for a specific operator version. For `olm.package` type, the dependency information should include the `package` name and the `version` of the package in semver format. We use `blang/semver` library for semver parsing (https://github.com/blang/semver). For example, you can specify an exact version such as `0.5.2` or a range of version such as `>0.5.1` (https://github.com/blang/semver#ranges). In addition, the author can specify dependency that is similar to existing CRD/API-based using `olm.gvk` type and then specify GVK information as how it is done in CSV. The author can also specify CSV labels as dependency constraints using `olm.label` type. The value of `olm.label` type will be matched against labels in CSV with the key starting with the phrase `olm.label`. This is a path to enable operator authors to consolidate all dependencies (API or explicit version) to be in the same place.
7373

7474
An example of a `dependencies.yaml` that specifies Prometheus operator and etcd CRD dependencies:
7575

7676
```
7777
dependencies:
7878
- type: olm.package
79-
value:
79+
value:
8080
packageName: prometheus
8181
version: >0.27.0
8282
- type: olm.gvk
8383
value:
8484
group: etcd.database.coreos.com
8585
kind: EtcdCluster
8686
version: v1beta2
87+
- type: olm.label
88+
value:
89+
label: lts
8790
```
8891

8992
### Bundle Dockerfile

‎manifests/etcd/0.9.2/etcdoperator.v0.9.2.clusterserviceversion.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ kind: ClusterServiceVersion
44
metadata:
55
name: etcdoperator.v0.9.2
66
namespace: placeholder
7+
labels:
8+
olm.label: testlabel
9+
olm.label.1: testlabel1
710
annotations:
811
tectonic-visibility: ocs
912
olm.skipRange: "< 0.6.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: etcdbackups.etcd.database.coreos.com
5+
spec:
6+
group: etcd.database.coreos.com
7+
names:
8+
kind: EtcdBackup
9+
listKind: EtcdBackupList
10+
plural: etcdbackups
11+
singular: etcdbackup
12+
scope: Namespaced
13+
version: v1beta2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: etcdclusters.etcd.database.coreos.com
5+
spec:
6+
group: etcd.database.coreos.com
7+
names:
8+
kind: EtcdCluster
9+
listKind: EtcdClusterList
10+
plural: etcdclusters
11+
shortNames:
12+
- etcdclus
13+
- etcd
14+
singular: etcdcluster
15+
scope: Namespaced
16+
version: v1beta2

‎pkg/lib/bundle/testdata/validate/invalid_dependencies_bundle/invalid_label_dependency/manifests/etcdoperator.v0.9.4.clusterserviceversion.yaml

+309
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: etcdrestores.etcd.database.coreos.com
5+
spec:
6+
group: etcd.database.coreos.com
7+
names:
8+
kind: EtcdRestore
9+
listKind: EtcdRestoreList
10+
plural: etcdrestores
11+
singular: etcdrestore
12+
scope: Namespaced
13+
version: v1beta2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
annotations:
2+
operators.operatorframework.io.bundle.channel.default.v1: stable
3+
operators.operatorframework.io.bundle.channels.v1: stable,beta
4+
operators.operatorframework.io.bundle.manifests.v1: manifests/
5+
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
6+
operators.operatorframework.io.bundle.metadata.v1: metadata/
7+
operators.operatorframework.io.bundle.package.v1: etcd
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dependencies:
2+
- type: olm.label
3+
value:

‎pkg/lib/bundle/testdata/validate/valid_bundle/metadata/dependencies.yaml

-9
This file was deleted.

‎pkg/lib/bundle/validate.go

+2
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ func validateDependencies(dependenciesFile *registry.DependenciesFile) []error {
230230
errs = dp.Validate()
231231
case registry.PackageDependency:
232232
errs = dp.Validate()
233+
case registry.LabelDependency:
234+
errs = dp.Validate()
233235
default:
234236
errs = append(errs, fmt.Errorf("unsupported dependency type %s", d.GetType()))
235237
}

‎pkg/lib/bundle/validate_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ func TestValidateBundleDependencies(t *testing.T) {
6161
fmt.Errorf("couldn't parse dependency of type olm.crd"),
6262
},
6363
},
64+
{
65+
description: "registryv1 bundle/invalid label type",
66+
mediaType: RegistryV1Type,
67+
directory: "./testdata/validate/invalid_dependencies_bundle/invalid_label_dependency/",
68+
errs: []error{
69+
fmt.Errorf("Label information is missing"),
70+
},
71+
},
6472
}
6573

6674
for _, tt := range table {

‎pkg/registry/types.go

+27
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const (
4343
GVKType = "olm.gvk"
4444
PackageType = "olm.package"
4545
DeprecatedType = "olm.deprecated"
46+
LabelType = "olm.label"
4647
)
4748

4849
// APIKey stores GroupVersionKind for use as map keys
@@ -193,6 +194,11 @@ type PackageDependency struct {
193194
Version string `json:"version" yaml:"version"`
194195
}
195196

197+
type LabelDependency struct {
198+
// The version range of dependency in semver range format
199+
Label string `json:"label" yaml:"label"`
200+
}
201+
196202
type GVKProperty struct {
197203
// The group of GVK based property
198204
Group string `json:"group" yaml:"group"`
@@ -216,6 +222,11 @@ type DeprecatedProperty struct {
216222
// Whether the bundle is deprecated
217223
}
218224

225+
type LabelProperty struct {
226+
// The version range of dependency in semver range format
227+
Label string `json:"label" yaml:"label"`
228+
}
229+
219230
// Validate will validate GVK dependency type and return error(s)
220231
func (gd *GVKDependency) Validate() []error {
221232
errs := []error{}
@@ -231,6 +242,15 @@ func (gd *GVKDependency) Validate() []error {
231242
return errs
232243
}
233244

245+
// Validate will validate GVK dependency type and return error(s)
246+
func (ld *LabelDependency) Validate() []error {
247+
errs := []error{}
248+
if *ld == (LabelDependency{}) {
249+
errs = append(errs, fmt.Errorf("Label information is missing"))
250+
}
251+
return errs
252+
}
253+
234254
// Validate will validate package dependency type and return error(s)
235255
func (pd *PackageDependency) Validate() []error {
236256
errs := []error{}
@@ -281,6 +301,13 @@ func (e *Dependency) GetTypeValue() interface{} {
281301
return nil
282302
}
283303
return dep
304+
case LabelType:
305+
dep := LabelDependency{}
306+
err := json.Unmarshal([]byte(e.GetValue()), &dep)
307+
if err != nil {
308+
return nil
309+
}
310+
return dep
284311
}
285312
return nil
286313
}

‎pkg/server/server_test.go

+64-16
Large diffs are not rendered by default.

‎pkg/sqlite/directory_test.go

+10-2
Large diffs are not rendered by default.

‎pkg/sqlite/load.go

+18
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,24 @@ func (s *sqlLoader) addBundleProperties(tx *sql.Tx, bundle *registry.Bundle) err
803803
}
804804
}
805805

806+
// Add label properties
807+
if csv, err := bundle.ClusterServiceVersion(); err == nil {
808+
for k, v := range csv.GetLabels() {
809+
if strings.HasPrefix(k, registry.LabelType) {
810+
prop := registry.LabelProperty{
811+
Label: v,
812+
}
813+
value, err := json.Marshal(prop)
814+
if err != nil {
815+
continue
816+
}
817+
if err := s.addProperty(tx, registry.LabelType, string(value), bundle.Name, bundleVersion, bundle.BundleImage); err != nil {
818+
continue
819+
}
820+
}
821+
}
822+
}
823+
806824
return nil
807825
}
808826

0 commit comments

Comments
 (0)
Please sign in to comment.