Compare commits
5 Commits
c40f03449e
...
d51d9f8f60
| Author | SHA1 | Date |
|---|---|---|
|
|
d51d9f8f60 | |
|
|
d3908e6a3c | |
|
|
daebbfb0ad | |
|
|
8034acff6e | |
|
|
c617d4f5d6 |
28
go.mod
28
go.mod
|
|
@ -6,8 +6,8 @@ require (
|
|||
dario.cat/mergo v1.0.2
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.13
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.6
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.15
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.7
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/go-test/deep v1.1.1
|
||||
github.com/golang/mock v1.6.0
|
||||
|
|
@ -143,25 +143,25 @@ require (
|
|||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 // indirect
|
||||
github.com/aws/smithy-go v1.23.1 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
|
|
|
|||
56
go.sum
56
go.sum
|
|
@ -140,48 +140,48 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
|
|||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ=
|
||||
github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.3 h1:h7xSsanJ4EQJXG5iuW4UqgP7qBopLpj84mpkNx3wPjM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.3/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.4 h1:qTsQKcdQPHnfGYBBs+Btl8QwxJeoWcOcPcixK90mRhg=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.4/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2 h1:t9yYsydLYNBk9cJ73rgPhPWqOh/52fcWDQB5b1JsKSY=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2/go.mod h1:IusfVNTmiSN3t4rhxWFaBAqn+mcNdwKtPcV16eYdgko=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.13 h1:wcqQB3B0PgRPUF5ZE/QL1JVOyB0mbPevHFoAMpemR9k=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.13/go.mod h1:ySB5D5ybwqGbT6c3GszZ+u+3KvrlYCUQNo62+hkKOFk=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.17 h1:skpEwzN/+H8cdrrtT8y+rvWJGiWWv0DeNAe+4VTf+Vs=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.17/go.mod h1:Ed+nXsaYa5uBINovJhcAWkALvXw2ZLk36opcuiSZfJM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 h1:UuGVOX48oP4vgQ36oiKmW9RuSeT8jlgQgBFQD+HUiHY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10/go.mod h1:vM/Ini41PzvudT4YkQyE/+WiQJiQ6jzeDyU8pQKwCac=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.15 h1:gE3M4xuNXfC/9bG4hyowGm/35uQTi7bUKeYs5e/6uvU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.15/go.mod h1:HvnvGJoE2I95KAIW8kkWVPJ4XhdrlvwJpV6pEzFQa8o=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.19 h1:Jc1zzwkSY1QbkEcLujwqRTXOdvW8ppND3jRBb/VhBQc=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.19/go.mod h1:DIfQ9fAk5H0pGtnqfqkbSIzky82qYnGvh06ASQXXg6A=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 h1:X7X4YKb+c0rkI6d4uJ5tEMxXgCZ+jZ/D6mvkno8c8Uw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11/go.mod h1:EqM6vPZQsZHYvC4Cai35UDg/f5NCEU+vp0WfbVqVcZc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 h1:Z1897HnnfLLgbs3pcUv8xLvtbai9TEfPUZfA0BFw968=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9/go.mod h1:8oVESJIPBYGWdZhaHcIvTm7BnI6hbsR3ggKn0uyRMhk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 h1:mj/bdWleWEh81DtpdHKkw41IrS+r3uw1J/VQtbwYYp8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10/go.mod h1:7+oEMxAZWP8gZCyjcm9VicI0M61Sx4DJtcGfKYv2yKQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 h1:wh+/mn57yhUrFtLIxyFPh2RgxgQz/u+Yrf7hiHGHqKY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10/go.mod h1:7zirD+ryp5gitJJ2m1BBux56ai8RIRDykXZrJSp540w=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 h1:7AANQZkF3ihM8fbdftpjhken0TP9sBzFbV/Ze/Y4HXA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11/go.mod h1:NTF4QCGkm6fzVwncpkFQqoquQyOolcyXfbpC98urj+c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11 h1:ShdtWUZT37LCAA4Mw2kJAJtzaszfSHFb5n25sdcv4YE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11/go.mod h1:7bUb2sSr2MZ3M/N+VyETLTQtInemHXb/Fl3s8CLzm0Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.10 h1:FHw90xCTsofzk6vjU808TSuDtDfOOKPNdz5Weyc3tUI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.10/go.mod h1:n8jdIE/8F3UYkg8O4IGkQpn2qUmapg/1K1yl29/uf/c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.11 h1:bKgSxk1TW//00PGQqYmrq83c+2myGidEclp+t9pPqVI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.11/go.mod h1:vrPYCQ6rFHL8jzQA8ppu3gWX18zxjLIDGTeqDxkBmSI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.1 h1:ne+eepnDB2Wh5lHKzELgEncIqeVlQ1rSF9fEa4r5I+A=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.1/go.mod h1:u0Jkg0L+dcG1ozUq21uFElmpbmjBnhHR5DELHIme4wg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 h1:DRND0dkCKtJzCj4Xl4OpVbXZgfttY5q712H9Zj7qc/0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10/go.mod h1:tGGNmJKOTernmR2+VJ0fCzQRurcPZj9ut60Zu5Fi6us=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.10 h1:DA+Hl5adieRyFvE7pCvBWm3VOZTRexGVkXw33SUqNoY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.10/go.mod h1:L+A89dH3/gr8L4ecrdzuXUYd1znoko6myzndVGZx/DA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.2 h1:DGFpGybmutVsCuF6vSuLZ25Vh55E3VmsnJmFfjeBx4M=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.2/go.mod h1:hm/wU1HDvXCFEDzOLorQnZZ/CVvPXvWEmHMSmqgQRuA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11 h1:GpMf3z2KJa4RnJ0ew3Hac+hRFYLZ9DDjfgXjuW+pB54=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11/go.mod h1:6MZP3ZI4QQsgUCFTwMZA2V0sEriNQ8k2hmoHF3qjimQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.11 h1:weapBOuuFIBEQ9OX/NVW3tFQCvSutyjZYk/ga5jDLPo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.11/go.mod h1:3C1gN4FmIVLwYSh8etngUS+f1viY6nLCDVtZmrFbDy0=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 h1:Br3kil4j7RPW+7LoLVkYt8SuhIWlg6ylmbmzXJ7PgXY=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.45.6/go.mod h1:FKXkHzw1fJZtg1P1qoAIiwen5thz/cDRTTDCIu8ljxc=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.6 h1:Hcb4yllr4GTOHC/BKjEklxWhciWMHIqzeCI9oYf1OIk=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.6/go.mod h1:N/iojY+8bW3MYol9NUMuKimpSbPEur75cuI1SmtonFM=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.7 h1:Wer3W0GuaedWT7dv/PiWNZGSQFSTcBY2rZpbiUp5xcA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.88.7/go.mod h1:UHKgcRSx8PVtvsc1Poxb/Co3PD3wL7P+f49P0+cWtuY=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6 h1:9PWl450XOG+m5lKv+qg5BXso1eLxpsZLqq7VPug5km0=
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6/go.mod h1:hwt7auGsDcaNQ8pzLgE2kCNyIWouYlAKSjuUu5Dqr7I=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 h1:TFg6XiS7EsHN0/jpV3eVNczZi/sPIVP5jxIs+euIESQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1/go.mod h1:OIezd9K0sM/64DDP4kXx/i0NdgXu6R5KE6SCsIPJsjc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 h1:fspVFg6qMx0svs40YgRmE7LZXh9VRZvTT35PfdQR6FM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.7/go.mod h1:BQTKL3uMECaLaUV3Zc2L4Qybv8C6BIXjuu1dOPyxTQs=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 h1:scVnW+NLXasGOhy7HhkdT9AGb6kjgW7fJ5xYkUaqHs0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2/go.mod h1:FRNCY3zTEWZXBKm2h5UBUPvCVDOecTad9KhynDyGBc0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 h1:VEO5dqFkMsl8QZ2yHsFDJAIZLAkEbaYDB+xdKi0Feic=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.7/go.mod h1:L1xxV3zAdB+qVrVW/pBIrIAnHFWHo6FBbFe4xOGsG/o=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 h1:M5nimZmugcZUO9wG7iVtROxPhiqyZX6ejS1lxlDPbTU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8/go.mod h1:mbef/pgKhtKRwrigPPs7SSSKZgytzP8PQ6P6JAAdqyM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 h1:S5GuJZpYxE0lKeMHKn+BRTz6PTFpgThyJ+5mYfux7BM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3/go.mod h1:X4OF+BTd7HIb3L+tc4UlWHVrpgwZZIVENU15pRDVTI0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 h1:Ekml5vGg6sHSZLZJQJagefnVe6PmqC2oiRkBq4F7fU0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9/go.mod h1:/e15V+o1zFHWdH3u7lpI3rVBcxszktIKuHKCY2/py+k=
|
||||
github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M=
|
||||
github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e
|
|||
storage := state.NewStorage(opts.CalleePath, ld.logger, ld.fs)
|
||||
envld := state.NewEnvironmentValuesLoader(storage, ld.fs, ld.logger, ld.remote)
|
||||
handler := state.MissingFileHandlerError
|
||||
vals, err := envld.LoadEnvironmentValues(&handler, args, environment.New(ld.env), ld.env)
|
||||
vals, err := envld.LoadEnvironmentValues(&handler, args, environment.New(ld.env), ld.env, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,11 +116,19 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState,
|
|||
return nil, &StateLoadError{fmt.Sprintf("failed to read %s: reading document at index %d", file, i), err}
|
||||
}
|
||||
|
||||
if err := mergo.Merge(&state, &intermediate, mergo.WithAppendSlice); err != nil {
|
||||
if err := mergo.Merge(&state, &intermediate, mergo.WithAppendSlice, mergo.WithOverride); err != nil {
|
||||
return nil, &StateLoadError{fmt.Sprintf("failed to read %s: merging document at index %d", file, i), err}
|
||||
}
|
||||
}
|
||||
|
||||
state.logger = c.logger
|
||||
state.valsRuntime = c.valsRuntime
|
||||
|
||||
return &state, nil
|
||||
}
|
||||
|
||||
// applyDefaultsAndOverrides applies default binary paths and command-line overrides
|
||||
func (c *StateCreator) applyDefaultsAndOverrides(state *HelmState) {
|
||||
if c.overrideHelmBinary != "" && c.overrideHelmBinary != DefaultHelmBinary {
|
||||
state.DefaultHelmBinary = c.overrideHelmBinary
|
||||
} else if state.DefaultHelmBinary == "" {
|
||||
|
|
@ -134,11 +142,6 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState,
|
|||
// Let `helmfile --kustomize-binary ""` not break this helmfile run
|
||||
state.DefaultKustomizeBinary = DefaultKustomizeBinary
|
||||
}
|
||||
|
||||
state.logger = c.logger
|
||||
state.valsRuntime = c.valsRuntime
|
||||
|
||||
return &state, nil
|
||||
}
|
||||
|
||||
// LoadEnvValues loads environment values files relative to the `baseDir`
|
||||
|
|
@ -181,6 +184,11 @@ func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envNam
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Apply default binaries and command-line overrides only for the main helmfile
|
||||
// after loading and merging all bases. This ensures that values from bases are
|
||||
// properly respected and that later bases/documents can override earlier ones.
|
||||
c.applyDefaultsAndOverrides(state)
|
||||
}
|
||||
|
||||
state, err = c.LoadEnvValues(state, envName, failOnMissingEnv, envValues, overrode)
|
||||
|
|
@ -216,7 +224,7 @@ func (c *StateCreator) loadBases(envValues, overrodeEnv *environment.Environment
|
|||
layers = append(layers, st)
|
||||
|
||||
for i := 1; i < len(layers); i++ {
|
||||
if err := mergo.Merge(layers[0], layers[i], mergo.WithAppendSlice); err != nil {
|
||||
if err := mergo.Merge(layers[0], layers[i], mergo.WithAppendSlice, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -452,7 +460,7 @@ func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []any
|
|||
valuesEntries := append([]any{}, entries...)
|
||||
ld := NewEnvironmentValuesLoader(st.storage(), st.fs, st.logger, remote)
|
||||
var err error
|
||||
envVals, err = ld.LoadEnvironmentValues(missingFileHandler, valuesEntries, ctxEnv, envName)
|
||||
envVals, err = ld.LoadEnvironmentValues(missingFileHandler, valuesEntries, ctxEnv, envName, st.Features)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
@ -525,3 +526,205 @@ releaseContext:
|
|||
t.Errorf("unexpected values: expected=%v, actual=%v", expectedValues, actualValues)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHelmBinaryInBases tests that helmBinary and kustomizeBinary settings
|
||||
// from bases are properly merged with later values overriding earlier ones
|
||||
func TestHelmBinaryInBases(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
files map[string]string
|
||||
mainFile string
|
||||
expectedHelmBinary string
|
||||
expectedKustomizeBinary string
|
||||
}{
|
||||
{
|
||||
name: "helmBinary in second base should be used",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/env.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/repos.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/releases.yaml
|
||||
`,
|
||||
"/path/to/bases/env.yaml": `environments:
|
||||
default:
|
||||
values:
|
||||
- key: value1
|
||||
`,
|
||||
"/path/to/bases/repos.yaml": `repositories:
|
||||
- name: stable
|
||||
url: https://charts.helm.sh/stable
|
||||
helmBinary: /path/to/custom/helm
|
||||
`,
|
||||
"/path/to/bases/releases.yaml": `releases:
|
||||
- name: myapp
|
||||
chart: stable/nginx
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: "/path/to/custom/helm",
|
||||
expectedKustomizeBinary: DefaultKustomizeBinary,
|
||||
},
|
||||
{
|
||||
name: "helmBinary in main file after bases should override",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/env.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/repos.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/releases.yaml
|
||||
helmBinary: /path/to/main/helm
|
||||
`,
|
||||
"/path/to/bases/env.yaml": `environments:
|
||||
default:
|
||||
values:
|
||||
- key: value1
|
||||
`,
|
||||
"/path/to/bases/repos.yaml": `repositories:
|
||||
- name: stable
|
||||
url: https://charts.helm.sh/stable
|
||||
helmBinary: /path/to/base/helm
|
||||
`,
|
||||
"/path/to/bases/releases.yaml": `releases:
|
||||
- name: myapp
|
||||
chart: stable/nginx
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: "/path/to/main/helm",
|
||||
expectedKustomizeBinary: DefaultKustomizeBinary,
|
||||
},
|
||||
{
|
||||
name: "helmBinary in main file between bases should override earlier bases",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/env.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/repos.yaml
|
||||
helmBinary: /path/to/middle/helm
|
||||
---
|
||||
bases:
|
||||
- ./bases/releases.yaml
|
||||
`,
|
||||
"/path/to/bases/env.yaml": `environments:
|
||||
default:
|
||||
values:
|
||||
- key: value1
|
||||
`,
|
||||
"/path/to/bases/repos.yaml": `repositories:
|
||||
- name: stable
|
||||
url: https://charts.helm.sh/stable
|
||||
helmBinary: /path/to/base/helm
|
||||
`,
|
||||
"/path/to/bases/releases.yaml": `releases:
|
||||
- name: myapp
|
||||
chart: stable/nginx
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: "/path/to/middle/helm",
|
||||
expectedKustomizeBinary: DefaultKustomizeBinary,
|
||||
},
|
||||
{
|
||||
name: "kustomizeBinary in base should be used",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/base.yaml
|
||||
`,
|
||||
"/path/to/bases/base.yaml": `kustomizeBinary: /path/to/custom/kustomize
|
||||
releases:
|
||||
- name: myapp
|
||||
chart: mychart
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: DefaultHelmBinary,
|
||||
expectedKustomizeBinary: "/path/to/custom/kustomize",
|
||||
},
|
||||
{
|
||||
name: "both helmBinary and kustomizeBinary in different bases",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/helm.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/kustomize.yaml
|
||||
`,
|
||||
"/path/to/bases/helm.yaml": `helmBinary: /path/to/custom/helm
|
||||
`,
|
||||
"/path/to/bases/kustomize.yaml": `kustomizeBinary: /path/to/custom/kustomize
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: "/path/to/custom/helm",
|
||||
expectedKustomizeBinary: "/path/to/custom/kustomize",
|
||||
},
|
||||
{
|
||||
name: "later base overrides earlier base for helmBinary",
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `bases:
|
||||
- ./bases/first.yaml
|
||||
---
|
||||
bases:
|
||||
- ./bases/second.yaml
|
||||
`,
|
||||
"/path/to/bases/first.yaml": `helmBinary: /path/to/first/helm
|
||||
`,
|
||||
"/path/to/bases/second.yaml": `helmBinary: /path/to/second/helm
|
||||
`,
|
||||
},
|
||||
mainFile: "/path/to/helmfile.yaml",
|
||||
expectedHelmBinary: "/path/to/second/helm",
|
||||
expectedKustomizeBinary: DefaultKustomizeBinary,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testFs := testhelper.NewTestFs(tt.files)
|
||||
if testFs.Cwd == "" {
|
||||
testFs.Cwd = "/"
|
||||
}
|
||||
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem())
|
||||
creator := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", "", r, false, "")
|
||||
|
||||
// Set up LoadFile for recursive base loading
|
||||
creator.LoadFile = func(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*HelmState, error) {
|
||||
path := filepath.Join(baseDir, file)
|
||||
content, ok := tt.files[path]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("file not found: %s", path)
|
||||
}
|
||||
return creator.ParseAndLoad([]byte(content), filepath.Dir(path), path, DefaultEnv, true, evaluateBases, inheritedEnv, overrodeEnv)
|
||||
}
|
||||
|
||||
yamlContent, ok := tt.files[tt.mainFile]
|
||||
if !ok {
|
||||
t.Fatalf("no file named %q registered", tt.mainFile)
|
||||
}
|
||||
|
||||
state, err := creator.ParseAndLoad([]byte(yamlContent), filepath.Dir(tt.mainFile), tt.mainFile, DefaultEnv, true, true, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if state.DefaultHelmBinary != tt.expectedHelmBinary {
|
||||
t.Errorf("helmBinary mismatch: expected=%s, actual=%s",
|
||||
tt.expectedHelmBinary, state.DefaultHelmBinary)
|
||||
}
|
||||
|
||||
if state.DefaultKustomizeBinary != tt.expectedKustomizeBinary {
|
||||
t.Errorf("kustomizeBinary mismatch: expected=%s, actual=%s",
|
||||
tt.expectedKustomizeBinary, state.DefaultKustomizeBinary)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package state
|
|||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"dario.cat/mergo"
|
||||
|
|
@ -36,13 +37,15 @@ func NewEnvironmentValuesLoader(storage *Storage, fs *filesystem.FileSystem, log
|
|||
}
|
||||
}
|
||||
|
||||
func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *string, valuesEntries []any, ctxEnv *environment.Environment, envName string) (map[string]any, error) {
|
||||
func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *string, valuesEntries []any, ctxEnv *environment.Environment, envName string, features []string) (map[string]any, error) {
|
||||
var (
|
||||
result = map[string]any{}
|
||||
hclLoader = hcllang.NewHCLLoader(ld.fs, ld.logger)
|
||||
err error
|
||||
)
|
||||
|
||||
layeredValues := slices.Contains(features, FeatureLayeredEnvironmentValues)
|
||||
|
||||
for _, entry := range valuesEntries {
|
||||
maps := []any{}
|
||||
|
||||
|
|
@ -65,7 +68,14 @@ func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *str
|
|||
if strings.HasSuffix(f, ".hcl") {
|
||||
hclLoader.AddFile(f)
|
||||
} else {
|
||||
tmplData := NewEnvironmentTemplateData(env, "", env.Values)
|
||||
values := env.Values
|
||||
if layeredValues {
|
||||
values, err = mapMerge(values, []any{result})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
tmplData := NewEnvironmentTemplateData(env, "", values)
|
||||
r := tmpl.NewFileRenderer(ld.fs, filepath.Dir(f), tmplData)
|
||||
bytes, err := r.RenderToBytes(f)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func newLoader() *EnvironmentValuesLoader {
|
|||
func TestEnvValsLoad_SingleValuesFile(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.5.yaml"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.5.yaml"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ func TestEnvValsLoad_EnvironmentNameFile(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.6.yaml.gotmpl"}, tt.env, tt.envName)
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.6.yaml.gotmpl"}, tt.env, tt.envName, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ func TestEnvValsLoad_EnvironmentNameFile(t *testing.T) {
|
|||
func TestEnvValsLoad_SingleValuesFileRemote(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"git::https://github.com/helm/helm.git@cmd/helm/testdata/output/values.yaml?ref=v3.8.1"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"git::https://github.com/helm/helm.git@cmd/helm/testdata/output/values.yaml?ref=v3.8.1"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ func TestEnvValsLoad_SingleValuesFileRemote(t *testing.T) {
|
|||
func TestEnvValsLoad_OverwriteNilValue_Issue1150(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.1.yaml", "testdata/values.2.yaml"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.1.yaml", "testdata/values.2.yaml"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ func TestEnvValsLoad_OverwriteNilValue_Issue1150(t *testing.T) {
|
|||
func TestEnvValsLoad_OverwriteWithNilValue_Issue1154(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.3.yaml", "testdata/values.4.yaml"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.3.yaml", "testdata/values.4.yaml"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ func TestEnvValsLoad_OverwriteWithNilValue_Issue1154(t *testing.T) {
|
|||
func TestEnvValsLoad_OverwriteEmptyValue_Issue1168(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/issues/1168/addons.yaml", "testdata/issues/1168/addons2.yaml"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/issues/1168/addons.yaml", "testdata/issues/1168/addons2.yaml"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ func TestEnvValsLoad_OverwriteEmptyValue_Issue1168(t *testing.T) {
|
|||
func TestEnvValsLoad_MultiHCL(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.7.hcl", "testdata/values.8.hcl"}, nil, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.7.hcl", "testdata/values.8.hcl"}, nil, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -234,7 +234,7 @@ func TestEnvValsLoad_EnvironmentValues(t *testing.T) {
|
|||
env := environment.New("test")
|
||||
env.Values["foo"] = "bar"
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.9.yaml.gotmpl"}, env, "")
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/values.9.yaml.gotmpl"}, env, "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -247,3 +247,22 @@ func TestEnvValsLoad_EnvironmentValues(t *testing.T) {
|
|||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvValsLoad_LayeredValues(t *testing.T) {
|
||||
l := newLoader()
|
||||
|
||||
actual, err := l.LoadEnvironmentValues(nil, []any{"testdata/layered.1.yaml", "testdata/layered.2.yaml.gotmpl", "testdata/layered.3.yaml.gotmpl"}, nil, "", []string{FeatureLayeredEnvironmentValues})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := map[string]any{
|
||||
"somevalue": string("foo"),
|
||||
"someothervalue": string("new foo"),
|
||||
"greeting": string("hello new foo"),
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package state
|
||||
|
||||
const (
|
||||
// FeatureLayeredEnvironmentValues is the feature flag for layered environment values
|
||||
FeatureLayeredEnvironmentValues = "layeredEnvironmentValues"
|
||||
)
|
||||
|
|
@ -89,6 +89,8 @@ type ReleaseSetSpec struct {
|
|||
MissingFileHandlerConfig *MissingFileHandlerConfig `yaml:"missingFileHandlerConfig,omitempty"`
|
||||
|
||||
LockFile string `yaml:"lockFilePath,omitempty"`
|
||||
|
||||
Features []string `yaml:"features,omitempty"`
|
||||
}
|
||||
|
||||
type MissingFileHandlerConfig struct {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
somevalue: foo
|
||||
greeting: hello
|
||||
|
|
@ -0,0 +1 @@
|
|||
someothervalue: "new {{ .Values.somevalue }}"
|
||||
|
|
@ -0,0 +1 @@
|
|||
greeting: "{{ .Values.greeting }} {{ .Values.someothervalue }}"
|
||||
Loading…
Reference in New Issue