@@ -39,6 +39,7 @@ type merger func(any, any, tree.Path) (any, error)
39
39
var mergeSpecials = map [tree.Path ]merger {}
40
40
41
41
func init () {
42
+ mergeSpecials ["networks.*.ipam.config" ] = mergeIPAMConfig
42
43
mergeSpecials ["services.*.annotations" ] = mergeToSequence
43
44
mergeSpecials ["services.*.build" ] = mergeBuild
44
45
mergeSpecials ["services.*.build.args" ] = mergeToSequence
@@ -197,6 +198,41 @@ func mergeUlimit(_ any, o any, p tree.Path) (any, error) {
197
198
return o , nil
198
199
}
199
200
201
+ func mergeIPAMConfig (c any , o any , path tree.Path ) (any , error ) {
202
+ var ipamConfigs []any
203
+ for _ , original := range c .([]any ) {
204
+ right := convertIntoMapping (original , nil )
205
+ for _ , override := range o .([]any ) {
206
+ left := convertIntoMapping (override , nil )
207
+ if left ["subnet" ] != right ["subnet" ] {
208
+ // check if left is already in ipamConfigs, add it if not and continue with the next config
209
+ if ! slices .ContainsFunc (ipamConfigs , func (a any ) bool {
210
+ return a .(map [string ]any )["subnet" ] == left ["subnet" ]
211
+ }) {
212
+ ipamConfigs = append (ipamConfigs , left )
213
+ continue
214
+ }
215
+ }
216
+ merged , err := mergeMappings (right , left , path )
217
+ if err != nil {
218
+ return nil , err
219
+ }
220
+ // find index of potential previous config with the same subnet in ipamConfigs
221
+ indexIfExist := slices .IndexFunc (ipamConfigs , func (a any ) bool {
222
+ return a .(map [string ]any )["subnet" ] == merged ["subnet" ]
223
+ })
224
+ // if a previous config is already in ipamConfigs, replace it
225
+ if indexIfExist >= 0 {
226
+ ipamConfigs [indexIfExist ] = merged
227
+ } else {
228
+ // or add the new config to ipamConfigs
229
+ ipamConfigs = append (ipamConfigs , merged )
230
+ }
231
+ }
232
+ }
233
+ return ipamConfigs , nil
234
+ }
235
+
200
236
func convertIntoMapping (a any , defaultValue any ) map [string ]any {
201
237
switch v := a .(type ) {
202
238
case map [string ]any :
0 commit comments