@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/stackrox/roxie/internal/k8s"
1212 "gopkg.in/yaml.v3"
13+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1314)
1415
1516const (
@@ -107,11 +108,21 @@ func (d *Deployer) getOperatorIndexImage() string {
107108func (d * Deployer ) createCatalogSource (ctx context.Context , indexImage string ) error {
108109 d .logger .Info ("Creating CatalogSource..." )
109110
110- // Check if CatalogSource CRD supports securityContextConfig (OCP 4.14+).
111- hasSecurityContextConfig , err := d .catalogSourceSupportsSecurityContextConfig (ctx )
111+ securityContextConfigSupported , err := d .catalogSourceSupportsSecurityContextConfig (ctx )
112112 if err != nil {
113113 d .logger .Warning ("Could not check CatalogSource CRD capabilities, proceeding without securityContextConfig" )
114- hasSecurityContextConfig = false
114+ securityContextConfigSupported = false
115+ }
116+
117+ catalogSourceSpec := map [string ]interface {}{
118+ "sourceType" : "grpc" ,
119+ "image" : indexImage ,
120+ "displayName" : "StackRox Operator Index" ,
121+ }
122+ if securityContextConfigSupported {
123+ catalogSourceSpec ["grpcPodConfig" ] = map [string ]interface {}{
124+ "securityContextConfig" : "restricted" ,
125+ }
115126 }
116127
117128 catalogSource := map [string ]interface {}{
@@ -121,19 +132,7 @@ func (d *Deployer) createCatalogSource(ctx context.Context, indexImage string) e
121132 "name" : catalogSourceName ,
122133 "namespace" : operatorNamespace ,
123134 },
124- "spec" : map [string ]interface {}{
125- "sourceType" : "grpc" ,
126- "image" : indexImage ,
127- "displayName" : "StackRox Operator Index" ,
128- },
129- }
130-
131- // TODO(ROX-34499): Add security context config if supported.
132- if hasSecurityContextConfig {
133- spec := catalogSource ["spec" ].(map [string ]interface {})
134- spec ["grpcPodConfig" ] = map [string ]interface {}{
135- "securityContextConfig" : "restricted" ,
136- }
135+ "spec" : catalogSourceSpec ,
137136 }
138137
139138 yamlData , err := yaml .Marshal (catalogSource )
@@ -153,7 +152,8 @@ func (d *Deployer) createCatalogSource(ctx context.Context, indexImage string) e
153152 return nil
154153}
155154
156- // catalogSourceSupportsSecurityContextConfig checks if the CatalogSource CRD supports securityContextConfig.
155+ // catalogSourceSupportsSecurityContextConfig checks if any served CatalogSource CRD version
156+ // includes securityContextConfig in its schema.
157157func (d * Deployer ) catalogSourceSupportsSecurityContextConfig (ctx context.Context ) (bool , error ) {
158158 result , err := d .runKubectl (ctx , k8s.KubectlOptions {
159159 Args : []string {"get" , "crd" , "catalogsources.operators.coreos.com" , "-o" , "yaml" },
@@ -162,9 +162,31 @@ func (d *Deployer) catalogSourceSupportsSecurityContextConfig(ctx context.Contex
162162 return false , err
163163 }
164164
165- // TODO(ROX-34499): this is overly optimistic and would incorrectly succeed if an api version
166- // that contains this had "serving: false"
167- return strings .Contains (result .Stdout , "securityContextConfig" ), nil
165+ obj := & unstructured.Unstructured {}
166+ if err := yaml .Unmarshal ([]byte (result .Stdout ), & obj .Object ); err != nil {
167+ return false , fmt .Errorf ("failed to parse CatalogSource CRD: %w" , err )
168+ }
169+
170+ versions , _ , _ := unstructured .NestedSlice (obj .Object , "spec" , "versions" )
171+ for _ , v := range versions {
172+ version , ok := v .(map [string ]interface {})
173+ if ! ok {
174+ continue
175+ }
176+ served , _ , _ := unstructured .NestedBool (version , "served" )
177+ if ! served {
178+ continue
179+ }
180+ _ , found , _ := unstructured .NestedMap (version ,
181+ "schema" , "openAPIV3Schema" , "properties" , "spec" ,
182+ "properties" , "grpcPodConfig" , "properties" , "securityContextConfig" ,
183+ )
184+ if found {
185+ return true , nil
186+ }
187+ }
188+
189+ return false , nil
168190}
169191
170192// createOperatorGroup creates the OperatorGroup.
0 commit comments