@@ -35,13 +35,48 @@ func expandMetadata(d *schema.ResourceData) (meta meta.ObjectMeta) {
35
35
return meta
36
36
}
37
37
38
+ // expandMetadataForUpdate safely expands metadata for updates, merging user-configured
39
+ // finalizers with existing system finalizers to prevent accidental removal
40
+ func expandMetadataForUpdate (d * schema.ResourceData , existingMeta meta.ObjectMeta ) (meta meta.ObjectMeta ) {
41
+ meta = expandMetadata (d )
42
+
43
+ // Merge finalizers: keep existing system finalizers, add/update user finalizers
44
+ if len (existingMeta .Finalizers ) > 0 {
45
+ userFinalizers := make (map [string ]bool )
46
+ for _ , f := range meta .Finalizers {
47
+ userFinalizers [f ] = true
48
+ }
49
+
50
+ // Start with existing finalizers
51
+ merged := make ([]string , 0 , len (existingMeta .Finalizers )+ len (meta .Finalizers ))
52
+ for _ , existing := range existingMeta .Finalizers {
53
+ if userFinalizers [existing ] {
54
+ // User explicitly configured this finalizer, keep it
55
+ merged = append (merged , existing )
56
+ delete (userFinalizers , existing )
57
+ } else {
58
+ // System finalizer not configured by user, preserve it
59
+ merged = append (merged , existing )
60
+ }
61
+ }
62
+
63
+ // Add any new user finalizers
64
+ for finalizer := range userFinalizers {
65
+ merged = append (merged , finalizer )
66
+ }
67
+
68
+ meta .Finalizers = merged
69
+ }
70
+
71
+ return meta
72
+ }
73
+
38
74
func flattenMetadata (meta meta.ObjectMeta , d * schema.ResourceData ) []interface {} {
39
75
m := map [string ]interface {}{
40
76
"generation" : meta .Generation ,
41
77
"name" : meta .Name ,
42
78
"namespace" : meta .Namespace ,
43
79
"resource_version" : meta .ResourceVersion ,
44
- "finalizers" : meta .Finalizers ,
45
80
"uid" : fmt .Sprintf ("%v" , meta .UID ),
46
81
}
47
82
@@ -51,6 +86,9 @@ func flattenMetadata(meta meta.ObjectMeta, d *schema.ResourceData) []interface{}
51
86
labels := d .Get ("metadata.0.labels" ).(map [string ]interface {})
52
87
m ["labels" ] = metadataRemoveInternalKeys (meta .Labels , labels )
53
88
89
+ finalizers := d .Get ("metadata.0.finalizers" ).([]interface {})
90
+ m ["finalizers" ] = metadataFilterFinalizers (meta .Finalizers , finalizers )
91
+
54
92
return []interface {}{m }
55
93
}
56
94
@@ -72,3 +110,21 @@ func metadataIsInternalKey(annotationKey string) bool {
72
110
73
111
return strings .HasSuffix (u .Hostname (), "kubernetes.io" ) || annotationKey == "notified.notifications.argoproj.io"
74
112
}
113
+
114
+ func metadataFilterFinalizers (apiFinalizers []string , configuredFinalizers []interface {}) []string {
115
+ configured := make (map [string ]bool )
116
+ for _ , v := range configuredFinalizers {
117
+ if s , ok := v .(string ); ok {
118
+ configured [s ] = true
119
+ }
120
+ }
121
+
122
+ result := make ([]string , 0 )
123
+ for _ , finalizer := range apiFinalizers {
124
+ // Only include finalizers that were explicitly configured by the user
125
+ if configured [finalizer ] {
126
+ result = append (result , finalizer )
127
+ }
128
+ }
129
+ return result
130
+ }
0 commit comments