Skip to content

Commit 0798cc0

Browse files
committed
review updates
Signed-off-by: grokspawn <jordan@nimblewidget.com>
1 parent a313edb commit 0798cc0

17 files changed

Lines changed: 196 additions & 336 deletions

File tree

api/v1/clusterextension_types.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,19 @@ const (
130130
//
131131
// +union
132132
// +kubebuilder:validation:XValidation:rule="has(self.sourceType) && self.sourceType == 'Catalog' ? has(self.catalog) : !has(self.catalog)",message="catalog is required when sourceType is Catalog, and forbidden otherwise"
133-
// +kubebuilder:validation:XValidation:rule="has(self.sourceType) && self.sourceType == 'OCIImage' ? has(self.ociImage) : !has(self.ociImage)",message="ociImage is required when sourceType is OCIImage, and forbidden otherwise"
133+
// <opcon:experimental:validation:XValidation:rule="has(self.sourceType) && self.sourceType == 'OCIImage' ? self.ociImage.ref.size() != 0 : self.ociImage.ref.size() == 0",message="ociImage is required when sourceType is OCIImage, and forbidden otherwise">
134134
type SourceConfig struct {
135135
// sourceType is required and specifies the type of install source.
136136
//
137+
// <opcon:standard:description>
138+
// The allowed value is "Catalog".
139+
//
140+
// When set to "Catalog", information for determining the appropriate bundle of content to install
141+
// is fetched from ClusterCatalog resources on the cluster.
142+
// When using the Catalog sourceType, the catalog field must also be set.
143+
// </opcon:standard:description>
144+
//
145+
// <opcon:experimental:description>
137146
// The allowed values are "Catalog" and "OCIImage".
138147
//
139148
// When set to "OCIImage", the bundle image is used directly. Direct sources do not perform
@@ -142,9 +151,11 @@ type SourceConfig struct {
142151
// When set to "Catalog", information for determining the appropriate bundle of content to install
143152
// is fetched from ClusterCatalog resources on the cluster.
144153
// When using the Catalog sourceType, the catalog field must also be set.
154+
// </opcon:experimental:description>
145155
//
146156
// +unionDiscriminator
147-
// +kubebuilder:validation:Enum:="Catalog";"OCIImage"
157+
// +kubebuilder:validation:Enum:="Catalog"
158+
// <opcon:experimental:validation:Enum=Catalog;OCIImage>
148159
// +required
149160
SourceType string `json:"sourceType"`
150161

@@ -155,27 +166,24 @@ type SourceConfig struct {
155166
Catalog *CatalogFilter `json:"catalog,omitempty"`
156167

157168
// ociImage configures a bundle image to install directly.
169+
// <opcon:experimental:description>
158170
// They do not provide catalog dependency resolution or upgrade safety.
159-
//
171+
// </opcon:experimental:description>
172+
// <opcon:experimental>
160173
// +optional
161-
OCIImage *OCIImageSource `json:"ociImage,omitempty"`
174+
OCIImage OCIImageSource `json:"ociImage,omitzero"`
162175
}
163176

164177
// OCIImageSource identifies a bundle image to install directly from an OCI registry.
178+
// +kubebuilder:validation:MinProperties:=1
165179
type OCIImageSource struct {
166180
// ref is a Docker-style image reference with a tag or digest.
167181
//
168182
// +required
169183
// +kubebuilder:validation:MaxLength:=1000
170-
// +kubebuilder:validation:XValidation:rule="self.matches(\"^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\\\b\")",message="must start with a valid domain"
171-
// +kubebuilder:validation:XValidation:rule="self.find(\"(\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)\") != \"\"",message="a valid image name is required"
172-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") != \"\" || self.find(\":.*$\") != \"\"",message="must end with a digest or a tag"
173-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") == \"\" ? (self.find(\":.*$\") != \"\" ? self.find(\":.*$\").substring(1).size() <= 127 : true) : true",message="tag is invalid"
174-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") == \"\" ? (self.find(\":.*$\") != \"\" ? self.find(\":.*$\").matches(\":[\\\\w][\\\\w.-]*$\") : true) : true",message="tag is invalid"
175-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") != \"\" ? self.find(\"(@.*:)\").matches(\"(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])\") : true",message="digest algorithm is not valid"
176-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") != \"\" ? self.find(\":.*$\").substring(1).size() >= 32 : true",message="digest is not valid"
177-
// +kubebuilder:validation:XValidation:rule="self.find(\"(@.*:)\") != \"\" ? self.find(\":.*$\").matches(\":[0-9A-Fa-f]*$\") : true",message="digest is not valid"
178-
Ref string `json:"ref"`
184+
// +kubebuilder:validation:MinLength:=1
185+
// +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?(:[0-9]+)?/[a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*(:[A-Za-z0-9_][A-Za-z0-9_.-]{0,126}|@[A-Za-z][A-Za-z0-9+._-]*:[0-9A-Fa-f]{32,})$\")",message="must be a complete image reference with a valid repository and tag or digest"
186+
Ref string `json:"ref,omitempty"`
179187
}
180188

181189
// ClusterExtensionInstallConfig is a union which selects the clusterExtension installation config.

api/v1/zz_generated.deepcopy.go

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

applyconfigurations/api/v1/sourceconfig.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/operator-controller/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
664664
controllers.ValidateClusterExtension(
665665
controllers.ServiceAccountDeprecationWarning(),
666666
controllers.DirectBundleRequiresBoxcutter(),
667+
controllers.ValidateDirectBundleSource(),
667668
),
668669
controllers.MigrateStorage(storageMigrator),
669670
controllers.RetrieveRevisionStates(revisionStatesGetter),
@@ -753,6 +754,7 @@ func (c *helmReconcilerConfigurator) Configure(ceReconciler *controllers.Cluster
753754
controllers.ValidateClusterExtension(
754755
controllers.ServiceAccountDeprecationWarning(),
755756
controllers.DirectBundleRequiresBoxcutter(),
757+
controllers.ValidateDirectBundleSource(),
756758
),
757759
controllers.RetrieveRevisionStates(revisionStatesGetter),
758760
controllers.ResolveBundle(c.resolver, c.mgr.GetClient()),

docs/api-reference/olmv1-api-reference.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -463,14 +463,15 @@ _Appears in:_
463463

464464
OCIImageSource identifies a bundle image to install directly from an OCI registry.
465465

466-
466+
_Validation:_
467+
- MinProperties: 1
467468

468469
_Appears in:_
469470
- [SourceConfig](#sourceconfig)
470471

471472
| Field | Description | Default | Validation |
472473
| --- | --- | --- | --- |
473-
| `ref` _string_ | ref is a Docker-style image reference with a tag or digest. | | MaxLength: 1000 <br />Required: \{\} <br /> |
474+
| `ref` _string_ | ref is a Docker-style image reference with a tag or digest. | | MaxLength: 1000 <br />MinLength: 1 <br />Required: \{\} <br /> |
474475

475476

476477
#### ObjectSelector
@@ -622,16 +623,18 @@ _Appears in:_
622623

623624
SourceConfig is a discriminated union which selects the installation source.
624625

626+
<opcon:experimental:validation:XValidation:rule="has(self.sourceType) && self.sourceType == 'OCIImage' ? self.ociImage.ref.size() != 0 : self.ociImage.ref.size() == 0",message="ociImage is required when sourceType is OCIImage, and forbidden otherwise">
627+
625628

626629

627630
_Appears in:_
628631
- [ClusterExtensionSpec](#clusterextensionspec)
629632

630633
| Field | Description | Default | Validation |
631634
| --- | --- | --- | --- |
632-
| `sourceType` _string_ | sourceType is required and specifies the type of install source.<br />The allowed values are "Catalog" and "OCIImage".<br />When set to "OCIImage", the bundle image is used directly. Direct sources do not perform<br />dependency resolution and are only supported by the Boxcutter runtime.<br />When set to "Catalog", information for determining the appropriate bundle of content to install<br />is fetched from ClusterCatalog resources on the cluster.<br />When using the Catalog sourceType, the catalog field must also be set. | | Enum: [Catalog OCIImage] <br />Required: \{\} <br /> |
635+
| `sourceType` _string_ | sourceType is required and specifies the type of install source.<br /><opcon:standard:description><br />The allowed value is "Catalog".<br />When set to "Catalog", information for determining the appropriate bundle of content to install<br />is fetched from ClusterCatalog resources on the cluster.<br />When using the Catalog sourceType, the catalog field must also be set.<br /></opcon:standard:description><br /><opcon:experimental:description><br />The allowed values are "Catalog" and "OCIImage".<br />When set to "OCIImage", the bundle image is used directly. Direct sources do not perform<br />dependency resolution and are only supported by the Boxcutter runtime.<br />When set to "Catalog", information for determining the appropriate bundle of content to install<br />is fetched from ClusterCatalog resources on the cluster.<br />When using the Catalog sourceType, the catalog field must also be set.<br /></opcon:experimental:description><br /><opcon:experimental:validation:Enum=Catalog;OCIImage> | | Enum: [Catalog] <br />Required: \{\} <br /> |
633636
| `catalog` _[CatalogFilter](#catalogfilter)_ | catalog configures how information is sourced from a catalog.<br />It is required when sourceType is "Catalog", and forbidden otherwise. | | Optional: \{\} <br /> |
634-
| `ociImage` _[OCIImageSource](#ociimagesource)_ | ociImage configures a bundle image to install directly.<br />They do not provide catalog dependency resolution or upgrade safety. | | Optional: \{\} <br /> |
637+
| `ociImage` _[OCIImageSource](#ociimagesource)_ | ociImage configures a bundle image to install directly.<br /><opcon:experimental:description><br />They do not provide catalog dependency resolution or upgrade safety.<br /></opcon:experimental:description><br /><opcon:experimental> | | MinProperties: 1 <br />Optional: \{\} <br /> |
635638

636639

637640
#### SourceType

helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensions.yaml

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -474,39 +474,20 @@ spec:
474474
ociImage:
475475
description: |-
476476
ociImage configures a bundle image to install directly.
477+
477478
They do not provide catalog dependency resolution or upgrade safety.
479+
minProperties: 1
478480
properties:
479481
ref:
480482
description: ref is a Docker-style image reference with a
481483
tag or digest.
482484
maxLength: 1000
485+
minLength: 1
483486
type: string
484487
x-kubernetes-validations:
485-
- message: must start with a valid domain
486-
rule: self.matches("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b")
487-
- message: a valid image name is required
488-
rule: self.find("(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)")
489-
!= ""
490-
- message: must end with a digest or a tag
491-
rule: self.find("(@.*:)") != "" || self.find(":.*$") !=
492-
""
493-
- message: tag is invalid
494-
rule: 'self.find("(@.*:)") == "" ? (self.find(":.*$") !=
495-
"" ? self.find(":.*$").substring(1).size() <= 127 : true)
496-
: true'
497-
- message: tag is invalid
498-
rule: 'self.find("(@.*:)") == "" ? (self.find(":.*$") !=
499-
"" ? self.find(":.*$").matches(":[\\w][\\w.-]*$") : true)
500-
: true'
501-
- message: digest algorithm is not valid
502-
rule: 'self.find("(@.*:)") != "" ? self.find("(@.*:)").matches("(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])")
503-
: true'
504-
- message: digest is not valid
505-
rule: 'self.find("(@.*:)") != "" ? self.find(":.*$").substring(1).size()
506-
>= 32 : true'
507-
- message: digest is not valid
508-
rule: 'self.find("(@.*:)") != "" ? self.find(":.*$").matches(":[0-9A-Fa-f]*$")
509-
: true'
488+
- message: must be a complete image reference with a valid
489+
repository and tag or digest
490+
rule: self.matches("^[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?(:[0-9]+)?/[a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*(:[A-Za-z0-9_][A-Za-z0-9_.-]{0,126}|@[A-Za-z][A-Za-z0-9+._-]*:[0-9A-Fa-f]{32,})$")
510491
required:
511492
- ref
512493
type: object
@@ -534,10 +515,6 @@ spec:
534515
otherwise
535516
rule: 'has(self.sourceType) && self.sourceType == ''Catalog'' ?
536517
has(self.catalog) : !has(self.catalog)'
537-
- message: ociImage is required when sourceType is OCIImage, and forbidden
538-
otherwise
539-
rule: 'has(self.sourceType) && self.sourceType == ''OCIImage'' ?
540-
has(self.ociImage) : !has(self.ociImage)'
541518
required:
542519
- namespace
543520
- source

helm/olmv1/base/operator-controller/crd/standard/olm.operatorframework.io_clusterextensions.yaml

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -423,60 +423,17 @@ spec:
423423
required:
424424
- packageName
425425
type: object
426-
ociImage:
427-
description: |-
428-
ociImage configures a bundle image to install directly.
429-
They do not provide catalog dependency resolution or upgrade safety.
430-
properties:
431-
ref:
432-
description: ref is a Docker-style image reference with a
433-
tag or digest.
434-
maxLength: 1000
435-
type: string
436-
x-kubernetes-validations:
437-
- message: must start with a valid domain
438-
rule: self.matches("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b")
439-
- message: a valid image name is required
440-
rule: self.find("(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)")
441-
!= ""
442-
- message: must end with a digest or a tag
443-
rule: self.find("(@.*:)") != "" || self.find(":.*$") !=
444-
""
445-
- message: tag is invalid
446-
rule: 'self.find("(@.*:)") == "" ? (self.find(":.*$") !=
447-
"" ? self.find(":.*$").substring(1).size() <= 127 : true)
448-
: true'
449-
- message: tag is invalid
450-
rule: 'self.find("(@.*:)") == "" ? (self.find(":.*$") !=
451-
"" ? self.find(":.*$").matches(":[\\w][\\w.-]*$") : true)
452-
: true'
453-
- message: digest algorithm is not valid
454-
rule: 'self.find("(@.*:)") != "" ? self.find("(@.*:)").matches("(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])")
455-
: true'
456-
- message: digest is not valid
457-
rule: 'self.find("(@.*:)") != "" ? self.find(":.*$").substring(1).size()
458-
>= 32 : true'
459-
- message: digest is not valid
460-
rule: 'self.find("(@.*:)") != "" ? self.find(":.*$").matches(":[0-9A-Fa-f]*$")
461-
: true'
462-
required:
463-
- ref
464-
type: object
465426
sourceType:
466427
description: |-
467428
sourceType is required and specifies the type of install source.
468429
469-
The allowed values are "Catalog" and "OCIImage".
470-
471-
When set to "OCIImage", the bundle image is used directly. Direct sources do not perform
472-
dependency resolution and are only supported by the Boxcutter runtime.
430+
The allowed value is "Catalog".
473431
474432
When set to "Catalog", information for determining the appropriate bundle of content to install
475433
is fetched from ClusterCatalog resources on the cluster.
476434
When using the Catalog sourceType, the catalog field must also be set.
477435
enum:
478436
- Catalog
479-
- OCIImage
480437
type: string
481438
required:
482439
- sourceType
@@ -486,10 +443,6 @@ spec:
486443
otherwise
487444
rule: 'has(self.sourceType) && self.sourceType == ''Catalog'' ?
488445
has(self.catalog) : !has(self.catalog)'
489-
- message: ociImage is required when sourceType is OCIImage, and forbidden
490-
otherwise
491-
rule: 'has(self.sourceType) && self.sourceType == ''OCIImage'' ?
492-
has(self.ociImage) : !has(self.ociImage)'
493446
required:
494447
- namespace
495448
- source

0 commit comments

Comments
 (0)