@@ -1128,17 +1128,23 @@ func (o *Operator) ResolvePlan(plan *v1alpha1.InstallPlan) error {
1128
1128
return nil
1129
1129
}
1130
1130
1131
- // Ensure all existing served versions are present in new CRD
1132
- func ensureCRDVersions (oldCRD * v1beta1ext.CustomResourceDefinition , newCRD * v1beta1ext.CustomResourceDefinition ) error {
1133
- newCRDVersions := map [string ]struct {}{}
1131
+ func getCRDVersionsMap (crd * v1beta1ext.CustomResourceDefinition ) map [string ]struct {} {
1132
+ versionsMap := map [string ]struct {}{}
1134
1133
1135
- for _ , newVersion := range newCRD .Spec .Versions {
1136
- newCRDVersions [ newVersion .Name ] = struct {}{}
1134
+ for _ , version := range crd .Spec .Versions {
1135
+ versionsMap [ version .Name ] = struct {}{}
1137
1136
}
1138
- if newCRD .Spec .Version != "" {
1139
- newCRDVersions [ newCRD .Spec .Version ] = struct {}{}
1137
+ if crd .Spec .Version != "" {
1138
+ versionsMap [ crd .Spec .Version ] = struct {}{}
1140
1139
}
1141
1140
1141
+ return versionsMap
1142
+ }
1143
+
1144
+ // Ensure all existing served versions are present in new CRD
1145
+ func ensureCRDVersions (oldCRD * v1beta1ext.CustomResourceDefinition , newCRD * v1beta1ext.CustomResourceDefinition ) error {
1146
+ newCRDVersions := getCRDVersionsMap (newCRD )
1147
+
1142
1148
for _ , oldVersion := range oldCRD .Spec .Versions {
1143
1149
if oldVersion .Served {
1144
1150
_ , ok := newCRDVersions [oldVersion .Name ]
@@ -1203,10 +1209,39 @@ func (o *Operator) validateExistingCRs(gvr schema.GroupVersionResource, newCRD *
1203
1209
return fmt .Errorf ("error validating custom resource against new schema %#v: %s" , newCRD .Spec .Validation , err )
1204
1210
}
1205
1211
}
1206
-
1207
1212
return nil
1208
1213
}
1209
1214
1215
+ // Attempt to remove stored versions that have been deprecated before allowing
1216
+ // those versions to be removed from the new CRD.
1217
+ // The function may not always succeed as storedVersions requires at least one
1218
+ // version. If there is only stored version, it won't be removed until a new
1219
+ // stored version is added.
1220
+ func removeDeprecatedStoredVersions (oldCRD * v1beta1ext.CustomResourceDefinition , newCRD * v1beta1ext.CustomResourceDefinition ) * v1beta1ext.CustomResourceDefinition {
1221
+ // StoredVersions requires to have at least one version.
1222
+ if len (oldCRD .Status .StoredVersions ) <= 1 {
1223
+ return nil
1224
+ }
1225
+
1226
+ updatedCRD := oldCRD .DeepCopy ()
1227
+
1228
+ newCRDVersions := getCRDVersionsMap (newCRD )
1229
+ newStoredVersions := []string {}
1230
+ for _ , v := range oldCRD .Status .StoredVersions {
1231
+ _ , ok := newCRDVersions [v ]
1232
+ if ok {
1233
+ newStoredVersions = append (newStoredVersions , v )
1234
+ }
1235
+ }
1236
+
1237
+ if len (newStoredVersions ) < 1 {
1238
+ return nil
1239
+ } else {
1240
+ updatedCRD .Status .StoredVersions = newStoredVersions
1241
+ return updatedCRD
1242
+ }
1243
+ }
1244
+
1210
1245
// ExecutePlan applies a planned InstallPlan to a namespace.
1211
1246
func (o * Operator ) ExecutePlan (plan * v1alpha1.InstallPlan ) error {
1212
1247
if plan .Status .Phase != v1alpha1 .InstallPlanPhaseInstalling {
@@ -1268,6 +1303,14 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1268
1303
if len (matchedCSV ) == 1 {
1269
1304
o .logger .Debugf ("Found one owner for CRD %v" , crd )
1270
1305
1306
+ crdStatus := removeDeprecatedStoredVersions (currentCRD , & crd )
1307
+ if crdStatus != nil {
1308
+ _ , err = o .opClient .ApiextensionsV1beta1Interface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().UpdateStatus (crdStatus )
1309
+ if err != nil {
1310
+ return errorwrap .Wrapf (err , "error updating CRD's status: %s" , step .Resource .Name )
1311
+ }
1312
+ }
1313
+
1271
1314
_ , err = o .opClient .ApiextensionsV1beta1Interface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().Update (& crd )
1272
1315
if err != nil {
1273
1316
return errorwrap .Wrapf (err , "error updating CRD: %s" , step .Resource .Name )
@@ -1284,6 +1327,14 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1284
1327
return errorwrap .Wrapf (err , "error validating existing CRs agains new CRD's schema: %s" , step .Resource .Name )
1285
1328
}
1286
1329
1330
+ crdStatus := removeDeprecatedStoredVersions (currentCRD , & crd )
1331
+ if crdStatus != nil {
1332
+ _ , err = o .opClient .ApiextensionsV1beta1Interface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().UpdateStatus (crdStatus )
1333
+ if err != nil {
1334
+ return errorwrap .Wrapf (err , "error updating CRD's status: %s" , step .Resource .Name )
1335
+ }
1336
+ }
1337
+
1287
1338
_ , err = o .opClient .ApiextensionsV1beta1Interface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().Update (& crd )
1288
1339
if err != nil {
1289
1340
return errorwrap .Wrapf (err , "error update CRD: %s" , step .Resource .Name )
0 commit comments