Skip to content

Commit 0e9f52b

Browse files
iamnitingrohan47
authored andcommitted
controllers: ensure CSV inherits hostNetwork from previous deployment
The webhook now mutates the ClusterServiceVersion (CSV) to set `hostNetwork` on deployments if the replaced CSV had it enabled. This ensures continuity of networking configuration across operator upgrades and avoids potential deployment issues caused by missing `hostNetwork` in the new CSV. Signed-off-by: Nitin Goyal <[email protected]> Signed-off-by: Rohan Gupta <[email protected]>
1 parent f0955eb commit 0e9f52b

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

webhook/csv.go

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525

2626
"github.com/go-logr/logr"
2727
opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
28-
"k8s.io/apimachinery/pkg/api/errors"
2928
"k8s.io/utils/ptr"
3029
ctrl "sigs.k8s.io/controller-runtime"
3130
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -71,19 +70,25 @@ func (r *ClusterServiceVersionDeploymentScaler) Handle(ctx context.Context, req
7170
return admission.Allowed("csv is not managed by ODF")
7271
}
7372

74-
running, err := r.isPreviousCsvHasRunningDeployments(ctx, logger, csv)
75-
if err != nil {
76-
logger.Error(err, "failed getting replicas from csv")
77-
return admission.Errored(http.StatusInternalServerError, fmt.Errorf("failed getting replicas from csv: %v", err))
73+
prevCsv := &opv1a1.ClusterServiceVersion{}
74+
if csv.Spec.Replaces != "" {
75+
key := client.ObjectKey{Name: csv.Spec.Replaces, Namespace: csv.Namespace}
76+
if err := r.Client.Get(ctx, key, prevCsv); client.IgnoreNotFound(err) != nil {
77+
logger.Error(err, "failed to get previous CSV", "csv", csv.Spec.Replaces)
78+
return admission.Errored(http.StatusInternalServerError, fmt.Errorf("failed getting previous csv %q: %w", csv.Spec.Replaces, err))
79+
} else if prevCsv.UID != "" {
80+
logger.Info("previous CSV found", "csv", prevCsv.Name)
81+
r.syncNewCsvWithPrevCsv(prevCsv, csv)
82+
} else {
83+
logger.Info("previous CSV not found", "csv", csv.Spec.Replaces)
84+
}
7885
}
7986

80-
if running {
81-
logger.Info("ignoring csv as the previous csv deployments are running")
82-
return admission.Allowed("previous csv deployments are running")
87+
if prevCsv.UID != "" && !r.isCsvHasRunningDeployments(prevCsv) {
88+
logger.Info("scaling down deployments")
89+
r.scaleDownCsvDeployments(logger, csv)
8390
}
8491

85-
r.scaleDownCsvDeployments(logger, csv)
86-
8792
marshaledCsv, err := json.Marshal(csv)
8893
if err != nil {
8994
logger.Error(err, "failed marshaling csv")
@@ -123,35 +128,36 @@ func (r *ClusterServiceVersionDeploymentScaler) loadOdfConfigMapData(ctx context
123128
return nil
124129
}
125130

126-
func (r *ClusterServiceVersionDeploymentScaler) isPreviousCsvHasRunningDeployments(ctx context.Context, logger logr.Logger, csv *opv1a1.ClusterServiceVersion) (bool, error) {
131+
func (r *ClusterServiceVersionDeploymentScaler) syncNewCsvWithPrevCsv(prevCsv *opv1a1.ClusterServiceVersion, newCsv *opv1a1.ClusterServiceVersion) {
127132

128-
if csv.Spec.Replaces == "" {
129-
logger.Info("csv.Spec.Replaces is not populated")
130-
return false, nil
131-
}
133+
prevDeployments := prevCsv.Spec.InstallStrategy.StrategySpec.DeploymentSpecs
134+
newDeployments := newCsv.Spec.InstallStrategy.StrategySpec.DeploymentSpecs
132135

133-
prevCsv := &opv1a1.ClusterServiceVersion{}
134-
key := client.ObjectKey{Name: csv.Spec.Replaces, Namespace: csv.Namespace}
135-
136-
if err := r.Client.Get(ctx, key, prevCsv); errors.IsNotFound(err) {
137-
// new install where an previous csv does not exists
138-
return false, nil
139-
} else if err != nil {
140-
logger.Error(err, "failed getting previous csv")
141-
return false, err
136+
for i := range prevDeployments {
137+
prevDeployment := &prevDeployments[i]
138+
139+
for j := range newDeployments {
140+
newDeployment := &newDeployments[j]
141+
142+
if prevDeployment.Name == newDeployment.Name {
143+
newDeployment.Spec.Template.Spec.HostNetwork = prevDeployment.Spec.Template.Spec.HostNetwork
144+
newDeployment.Spec.Replicas = prevDeployment.Spec.Replicas
145+
}
146+
}
142147
}
148+
}
149+
150+
func (r *ClusterServiceVersionDeploymentScaler) isCsvHasRunningDeployments(csv *opv1a1.ClusterServiceVersion) bool {
143151

144-
deployments := prevCsv.Spec.InstallStrategy.StrategySpec.DeploymentSpecs
152+
deployments := csv.Spec.InstallStrategy.StrategySpec.DeploymentSpecs
145153
for i := range deployments {
146154
deployment := &deployments[i]
147155
if deployment.Spec.Replicas == nil || *deployment.Spec.Replicas > 0 {
148-
// upgrade case where an older csv is found with replica 1
149-
return true, nil
156+
return true
150157
}
151158
}
152159

153-
// upgrade case where an older csv is found with replica 0
154-
return false, nil
160+
return false
155161
}
156162

157163
func (r *ClusterServiceVersionDeploymentScaler) scaleDownCsvDeployments(logger logr.Logger, csv *opv1a1.ClusterServiceVersion) {

0 commit comments

Comments
 (0)