@@ -26,6 +26,8 @@ import (
26
26
"github.com/operator-framework/operator-registry/pkg/registry"
27
27
log "github.com/sirupsen/logrus"
28
28
admissionregv1 "k8s.io/api/admissionregistration/v1"
29
+ appsv1 "k8s.io/api/apps/v1"
30
+ corev1 "k8s.io/api/core/v1"
29
31
"k8s.io/apimachinery/pkg/version"
30
32
31
33
"github.com/operator-framework/operator-sdk/internal/generate/collector"
@@ -39,6 +41,10 @@ func ApplyTo(c *collector.Manifests, csv *operatorsv1alpha1.ClusterServiceVersio
39
41
return fmt .Errorf ("error updating ClusterServiceVersion: %v" , err )
40
42
}
41
43
44
+ // Set fields required by namespaced operators. This is a no-op for cluster-
45
+ // scoped operators.
46
+ setNamespacedFields (csv )
47
+
42
48
// Sort all updated fields.
43
49
sortUpdates (csv )
44
50
@@ -111,6 +117,47 @@ func applyDeployments(c *collector.Manifests, strategy *operatorsv1alpha1.Strate
111
117
strategy .DeploymentSpecs = depSpecs
112
118
}
113
119
120
+ const (
121
+ // WatchNamespaceEnv is a constant for internal use.
122
+ WatchNamespaceEnv = "WATCH_NAMESPACE"
123
+ // TargetNamespacesRef references the target namespaces a CSV is installed in.
124
+ // This is required by legacy project Deployments.
125
+ TargetNamespacesRef = "metadata.annotations['olm.targetNamespaces']"
126
+ )
127
+
128
+ // setNamespacedFields sets static fields in a CSV required by namespaced
129
+ // operators.
130
+ func setNamespacedFields (csv * operatorsv1alpha1.ClusterServiceVersion ) {
131
+ for _ , dep := range csv .Spec .InstallStrategy .StrategySpec .DeploymentSpecs {
132
+ // Set WATCH_NAMESPACE if it exists in a deployment spec..
133
+ envVar := newFieldRefEnvVar (WatchNamespaceEnv , TargetNamespacesRef )
134
+ setContainerEnvVarIfExists (& dep .Spec , envVar )
135
+ }
136
+ }
137
+
138
+ // setContainerEnvVarIfExists overwrites all references to ev.Name with ev.
139
+ func setContainerEnvVarIfExists (spec * appsv1.DeploymentSpec , ev corev1.EnvVar ) {
140
+ for _ , c := range spec .Template .Spec .Containers {
141
+ for i := 0 ; i < len (c .Env ); i ++ {
142
+ if c .Env [i ].Name == ev .Name {
143
+ c .Env [i ] = ev
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ // newFieldRefEnvVar creates a new environment variable referencing fieldPath.
150
+ func newFieldRefEnvVar (name , fieldPath string ) corev1.EnvVar {
151
+ return corev1.EnvVar {
152
+ Name : name ,
153
+ ValueFrom : & corev1.EnvVarSource {
154
+ FieldRef : & corev1.ObjectFieldSelector {
155
+ FieldPath : fieldPath ,
156
+ },
157
+ },
158
+ }
159
+ }
160
+
114
161
// applyCustomResourceDefinitions updates csv's customresourcedefinitions.owned
115
162
// with CustomResourceDefinitions in the collector.
116
163
// customresourcedefinitions.required are left as-is, since they are
0 commit comments