Skip to content

Commit 9921986

Browse files
authored
Merge branch 'main' into configtls-add-newdefault-funcs
2 parents 26142b0 + a327d55 commit 9921986

File tree

11 files changed

+265
-36
lines changed

11 files changed

+265
-36
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: configtls
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix issue where `IncludeSystemCACertsPool` was not consistently used between `ServerConfig` and `ClientConfig`.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [9835]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: []

.github/workflows/build-and-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ jobs:
216216
- name: Run Unit Tests With Coverage
217217
run: make gotest-with-cover
218218
- name: Upload coverage report
219-
uses: Wandalen/wretry.action@1a10d4835a1506f513ad8e7488aeb474ab20055c # v1.4.10
219+
uses: Wandalen/wretry.action@f062299947903c6e425ff67d6a93f52066e4ee1c # v2.1.0
220220
with:
221221
action: codecov/codecov-action@v3
222222
with: |

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ jobs:
3030

3131
# Initializes the CodeQL tools for scanning.
3232
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
33+
uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
3434
with:
3535
languages: go
3636

3737
- name: Autobuild
38-
uses: github/codeql-action/autobuild@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
38+
uses: github/codeql-action/autobuild@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
3939

4040
- name: Perform CodeQL Analysis
41-
uses: github/codeql-action/analyze@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
41+
uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9

.github/workflows/scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ jobs:
6464

6565
# Upload the results to GitHub's code scanning dashboard.
6666
- name: "Upload to code-scanning"
67-
uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
67+
uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9
6868
with:
6969
sarif_file: results.sarif

config/configtls/configtls.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ func (r *certReloader) GetCertificate() (*tls.Certificate, error) {
193193
}
194194

195195
func (c TLSSetting) Validate() error {
196+
if c.hasCAFile() && c.hasCAPem() {
197+
return fmt.Errorf("provide either a CA file or the PEM-encoded string, but not both")
198+
}
199+
196200
minTLS, err := convertVersion(c.MinVersion, defaultMinTLSVersion)
197201
if err != nil {
198202
return fmt.Errorf("invalid TLS min_version: %w", err)
@@ -309,6 +313,15 @@ func (c Config) loadCertFile(certPath string) (*x509.CertPool, error) {
309313

310314
func (c Config) loadCertPem(certPem []byte) (*x509.CertPool, error) {
311315
certPool := x509.NewCertPool()
316+
if c.IncludeSystemCACertsPool {
317+
scp, err := systemCertPool()
318+
if err != nil {
319+
return nil, err
320+
}
321+
if scp != nil {
322+
certPool = scp
323+
}
324+
}
312325
if !certPool.AppendCertsFromPEM(certPem) {
313326
return nil, fmt.Errorf("failed to parse cert")
314327
}

config/configtls/configtls_test.go

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -657,30 +657,25 @@ func TestMinMaxTLSVersions(t *testing.T) {
657657

658658
func TestTLSSettingValidate(t *testing.T) {
659659
tests := []struct {
660-
name string
661-
minVersion string
662-
maxVersion string
663-
errorTxt string
660+
name string
661+
tlsConfig TLSSetting
662+
errorTxt string
664663
}{
665-
{name: `TLS Config ["", ""] to be valid`, minVersion: "", maxVersion: ""},
666-
{name: `TLS Config ["", "1.3"] to be valid`, minVersion: "", maxVersion: "1.3"},
667-
{name: `TLS Config ["1.2", ""] to be valid`, minVersion: "1.2", maxVersion: ""},
668-
{name: `TLS Config ["1.3", "1.3"] to be valid`, minVersion: "1.3", maxVersion: "1.3"},
669-
{name: `TLS Config ["1.0", "1.1"] to be valid`, minVersion: "1.0", maxVersion: "1.1"},
670-
{name: `TLS Config ["asd", ""] to give [Error]`, minVersion: "asd", maxVersion: "", errorTxt: `invalid TLS min_version: unsupported TLS version: "asd"`},
671-
{name: `TLS Config ["", "asd"] to give [Error]`, minVersion: "", maxVersion: "asd", errorTxt: `invalid TLS max_version: unsupported TLS version: "asd"`},
672-
{name: `TLS Config ["0.4", ""] to give [Error]`, minVersion: "0.4", maxVersion: "", errorTxt: `invalid TLS min_version: unsupported TLS version: "0.4"`},
673-
{name: `TLS Config ["1.2", "1.1"] to give [Error]`, minVersion: "1.2", maxVersion: "1.1", errorTxt: `invalid TLS configuration: min_version cannot be greater than max_version`},
664+
{name: `TLS Config ["", ""] to be valid`, tlsConfig: Config{MinVersion: "", MaxVersion: ""}},
665+
{name: `TLS Config ["", "1.3"] to be valid`, tlsConfig: Config{MinVersion: "", MaxVersion: "1.3"}},
666+
{name: `TLS Config ["1.2", ""] to be valid`, tlsConfig: Config{MinVersion: "1.2", MaxVersion: ""}},
667+
{name: `TLS Config ["1.3", "1.3"] to be valid`, tlsConfig: Config{MinVersion: "1.3", MaxVersion: "1.3"}},
668+
{name: `TLS Config ["1.0", "1.1"] to be valid`, tlsConfig: Config{MinVersion: "1.0", MaxVersion: "1.1"}},
669+
{name: `TLS Config ["asd", ""] to give [Error]`, tlsConfig: Config{MinVersion: "asd", MaxVersion: ""}, errorTxt: `invalid TLS min_version: unsupported TLS version: "asd"`},
670+
{name: `TLS Config ["", "asd"] to give [Error]`, tlsConfig: Config{MinVersion: "", MaxVersion: "asd"}, errorTxt: `invalid TLS max_version: unsupported TLS version: "asd"`},
671+
{name: `TLS Config ["0.4", ""] to give [Error]`, tlsConfig: Config{MinVersion: "0.4", MaxVersion: ""}, errorTxt: `invalid TLS min_version: unsupported TLS version: "0.4"`},
672+
{name: `TLS Config ["1.2", "1.1"] to give [Error]`, tlsConfig: Config{MinVersion: "1.2", MaxVersion: "1.1"}, errorTxt: `invalid TLS configuration: min_version cannot be greater than max_version`},
673+
{name: `TLS Config with both CA File and PEM`, tlsConfig: Config{CAFile: "test", CAPem: "test"}, errorTxt: `provide either a CA file or the PEM-encoded string, but not both`},
674674
}
675675

676676
for _, test := range tests {
677677
t.Run(test.name, func(t *testing.T) {
678-
setting := TLSSetting{
679-
MinVersion: test.minVersion,
680-
MaxVersion: test.maxVersion,
681-
}
682-
683-
err := setting.Validate()
678+
err := test.tlsConfig.Validate()
684679

685680
if test.errorTxt == "" {
686681
assert.Nil(t, err)
@@ -741,6 +736,86 @@ invalid TLS cipher suite: "BAR"`,
741736
}
742737

743738
func TestSystemCertPool(t *testing.T) {
739+
anError := errors.New("my error")
740+
tests := []struct {
741+
name string
742+
tlsSetting TLSSetting
743+
wantErr error
744+
systemCertFn func() (*x509.CertPool, error)
745+
}{
746+
{
747+
name: "not using system cert pool",
748+
tlsSetting: TLSSetting{
749+
IncludeSystemCACertsPool: false,
750+
CAFile: filepath.Join("testdata", "ca-1.crt"),
751+
},
752+
wantErr: nil,
753+
systemCertFn: x509.SystemCertPool,
754+
},
755+
{
756+
name: "using system cert pool",
757+
tlsSetting: TLSSetting{
758+
IncludeSystemCACertsPool: true,
759+
CAFile: filepath.Join("testdata", "ca-1.crt"),
760+
},
761+
wantErr: nil,
762+
systemCertFn: x509.SystemCertPool,
763+
},
764+
{
765+
name: "error loading system cert pool",
766+
tlsSetting: TLSSetting{
767+
IncludeSystemCACertsPool: true,
768+
CAFile: filepath.Join("testdata", "ca-1.crt"),
769+
},
770+
wantErr: anError,
771+
systemCertFn: func() (*x509.CertPool, error) {
772+
return nil, anError
773+
},
774+
},
775+
{
776+
name: "nil system cert pool",
777+
tlsSetting: TLSSetting{
778+
IncludeSystemCACertsPool: true,
779+
CAFile: filepath.Join("testdata", "ca-1.crt"),
780+
},
781+
wantErr: nil,
782+
systemCertFn: func() (*x509.CertPool, error) {
783+
return nil, nil
784+
},
785+
},
786+
}
787+
for _, test := range tests {
788+
t.Run(test.name, func(t *testing.T) {
789+
oldSystemCertPool := systemCertPool
790+
systemCertPool = test.systemCertFn
791+
defer func() {
792+
systemCertPool = oldSystemCertPool
793+
}()
794+
795+
serverConfig := ServerConfig{
796+
TLSSetting: test.tlsSetting,
797+
}
798+
c, err := serverConfig.LoadTLSConfig()
799+
if test.wantErr != nil {
800+
assert.ErrorContains(t, err, test.wantErr.Error())
801+
} else {
802+
assert.NotNil(t, c.RootCAs)
803+
}
804+
805+
clientConfig := ClientConfig{
806+
TLSSetting: test.tlsSetting,
807+
}
808+
c, err = clientConfig.LoadTLSConfig()
809+
if test.wantErr != nil {
810+
assert.ErrorContains(t, err, test.wantErr.Error())
811+
} else {
812+
assert.NotNil(t, c.RootCAs)
813+
}
814+
})
815+
}
816+
}
817+
818+
func TestSystemCertPool_loadCert(t *testing.T) {
744819
anError := errors.New("my error")
745820
tests := []struct {
746821
name string

confmap/converter/expandconverter/expand.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,71 @@ package expandconverter // import "go.opentelemetry.io/collector/confmap/convert
55

66
import (
77
"context"
8+
"fmt"
89
"os"
10+
"regexp"
11+
12+
"go.uber.org/zap"
913

1014
"go.opentelemetry.io/collector/confmap"
1115
)
1216

13-
type converter struct{}
17+
type converter struct {
18+
logger *zap.Logger
19+
20+
// Record of which env vars we have logged a warning for
21+
loggedDeprecations map[string]struct{}
22+
}
1423

1524
// New returns a confmap.Converter, that expands all environment variables for a given confmap.Conf.
1625
//
1726
// Notice: This API is experimental.
18-
func New(confmap.ConverterSettings) confmap.Converter {
19-
return converter{}
27+
func New(_ confmap.ConverterSettings) confmap.Converter {
28+
return converter{
29+
loggedDeprecations: make(map[string]struct{}),
30+
logger: zap.NewNop(), // TODO: pass logger in ConverterSettings
31+
}
2032
}
2133

22-
func (converter) Convert(_ context.Context, conf *confmap.Conf) error {
34+
func (c converter) Convert(_ context.Context, conf *confmap.Conf) error {
2335
out := make(map[string]any)
2436
for _, k := range conf.AllKeys() {
25-
out[k] = expandStringValues(conf.Get(k))
37+
out[k] = c.expandStringValues(conf.Get(k))
2638
}
2739
return conf.Merge(confmap.NewFromStringMap(out))
2840
}
2941

30-
func expandStringValues(value any) any {
42+
func (c converter) expandStringValues(value any) any {
3143
switch v := value.(type) {
3244
case string:
33-
return expandEnv(v)
45+
return c.expandEnv(v)
3446
case []any:
3547
nslice := make([]any, 0, len(v))
3648
for _, vint := range v {
37-
nslice = append(nslice, expandStringValues(vint))
49+
nslice = append(nslice, c.expandStringValues(vint))
3850
}
3951
return nslice
4052
case map[string]any:
4153
nmap := map[string]any{}
4254
for mk, mv := range v {
43-
nmap[mk] = expandStringValues(mv)
55+
nmap[mk] = c.expandStringValues(mv)
4456
}
4557
return nmap
4658
default:
4759
return v
4860
}
4961
}
5062

51-
func expandEnv(s string) string {
63+
func (c converter) expandEnv(s string) string {
5264
return os.Expand(s, func(str string) string {
65+
// Matches on $VAR style environment variables
66+
// in order to make sure we don't log a warning for ${VAR}
67+
var regex = regexp.MustCompile(fmt.Sprintf(`\$%s`, regexp.QuoteMeta(str)))
68+
if _, exists := c.loggedDeprecations[str]; !exists && regex.MatchString(s) {
69+
msg := fmt.Sprintf("Variable substitution using $VAR will be deprecated in favor of ${VAR} and ${env:VAR}, please update $%s", str)
70+
c.logger.Warn(msg, zap.String("variable", str))
71+
c.loggedDeprecations[str] = struct{}{}
72+
}
5373
// This allows escaping environment variable substitution via $$, e.g.
5474
// - $FOO will be substituted with env var FOO
5575
// - $$FOO will be replaced with $FOO

0 commit comments

Comments
 (0)