Skip to content

Commit 278b38e

Browse files
ItielOlenickStarefossen
authored andcommitted
Ta https server (open-telemetry#2921)
* Added https server, tests, secret marshalling * Added changelog * Moved TLS config. Cleaned up server. * TLS config as struct method. Go Idioms * Removed default tls file paths. Minor cleanup.
1 parent 0e6d35b commit 278b38e

File tree

9 files changed

+303
-23
lines changed

9 files changed

+303
-23
lines changed

.chloggen/ta-add-https.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
5+
component: target allocator
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Added option for creating an mTLS-configured HTTPS server to fetch scrape config with real secret values.
9+
10+
# One or more tracking issues related to the change
11+
issues: [1669]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext: |
17+
The change introduces an option to create an additional HTTPS server with mTLS configuration.
18+
This server is specifically utilized for obtaining the scrape configuration with actual secret values.

cmd/otel-allocator/config/config.go

+59
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package config
1616

1717
import (
18+
"crypto/tls"
19+
"crypto/x509"
1820
"errors"
1921
"fmt"
2022
"io/fs"
@@ -53,6 +55,7 @@ type Config struct {
5355
AllocationStrategy string `yaml:"allocation_strategy,omitempty"`
5456
FilterStrategy string `yaml:"filter_strategy,omitempty"`
5557
PrometheusCR PrometheusCRConfig `yaml:"prometheus_cr,omitempty"`
58+
HTTPS HTTPSServerConfig `yaml:"https,omitempty"`
5659
}
5760

5861
type PrometheusCRConfig struct {
@@ -64,6 +67,14 @@ type PrometheusCRConfig struct {
6467
ScrapeInterval model.Duration `yaml:"scrape_interval,omitempty"`
6568
}
6669

70+
type HTTPSServerConfig struct {
71+
Enabled bool `yaml:"enabled,omitempty"`
72+
ListenAddr string `yaml:"listen_addr,omitempty"`
73+
CAFilePath string `yaml:"ca_file_path,omitempty"`
74+
TLSCertFilePath string `yaml:"tls_cert_file_path,omitempty"`
75+
TLSKeyFilePath string `yaml:"tls_key_file_path,omitempty"`
76+
}
77+
6778
func LoadFromFile(file string, target *Config) error {
6879
return unmarshal(target, file)
6980
}
@@ -103,6 +114,31 @@ func LoadFromCLI(target *Config, flagSet *pflag.FlagSet) error {
103114
return err
104115
}
105116

117+
target.HTTPS.Enabled, err = getHttpsEnabled(flagSet)
118+
if err != nil {
119+
return err
120+
}
121+
122+
target.HTTPS.ListenAddr, err = getHttpsListenAddr(flagSet)
123+
if err != nil {
124+
return err
125+
}
126+
127+
target.HTTPS.CAFilePath, err = getHttpsCAFilePath(flagSet)
128+
if err != nil {
129+
return err
130+
}
131+
132+
target.HTTPS.TLSCertFilePath, err = getHttpsTLSCertFilePath(flagSet)
133+
if err != nil {
134+
return err
135+
}
136+
137+
target.HTTPS.TLSKeyFilePath, err = getHttpsTLSKeyFilePath(flagSet)
138+
if err != nil {
139+
return err
140+
}
141+
106142
return nil
107143
}
108144

@@ -164,3 +200,26 @@ func ValidateConfig(config *Config) error {
164200
}
165201
return nil
166202
}
203+
204+
func (c HTTPSServerConfig) NewTLSConfig() (*tls.Config, error) {
205+
cert, err := tls.LoadX509KeyPair(c.TLSCertFilePath, c.TLSKeyFilePath)
206+
if err != nil {
207+
return nil, err
208+
}
209+
210+
caCert, err := os.ReadFile(c.CAFilePath)
211+
if err != nil {
212+
return nil, err
213+
}
214+
215+
caCertPool := x509.NewCertPool()
216+
caCertPool.AppendCertsFromPEM(caCert)
217+
218+
tlsConfig := &tls.Config{
219+
Certificates: []tls.Certificate{cert},
220+
ClientAuth: tls.RequireAndVerifyClientCert,
221+
ClientCAs: caCertPool,
222+
MinVersion: tls.VersionTLS12,
223+
}
224+
return tlsConfig, nil
225+
}

cmd/otel-allocator/config/config_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ func TestLoad(t *testing.T) {
6161
PrometheusCR: PrometheusCRConfig{
6262
ScrapeInterval: model.Duration(time.Second * 60),
6363
},
64+
HTTPS: HTTPSServerConfig{
65+
Enabled: true,
66+
CAFilePath: "/path/to/ca.pem",
67+
TLSCertFilePath: "/path/to/cert.pem",
68+
TLSKeyFilePath: "/path/to/key.pem",
69+
},
6470
PromConfig: &promconfig.Config{
6571
GlobalConfig: promconfig.GlobalConfig{
6672
ScrapeInterval: model.Duration(60 * time.Second),

cmd/otel-allocator/config/flags.go

+35-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,16 @@ import (
2525

2626
// Flag names.
2727
const (
28-
targetAllocatorName = "target-allocator"
29-
configFilePathFlagName = "config-file"
30-
listenAddrFlagName = "listen-addr"
31-
prometheusCREnabledFlagName = "enable-prometheus-cr-watcher"
32-
kubeConfigPathFlagName = "kubeconfig-path"
28+
targetAllocatorName = "target-allocator"
29+
configFilePathFlagName = "config-file"
30+
listenAddrFlagName = "listen-addr"
31+
prometheusCREnabledFlagName = "enable-prometheus-cr-watcher"
32+
kubeConfigPathFlagName = "kubeconfig-path"
33+
httpsEnabledFlagName = "enable-https-server"
34+
listenAddrHttpsFlagName = "listen-addr-https"
35+
httpsCAFilePathFlagName = "https-ca-file"
36+
httpsTLSCertFilePathFlagName = "https-tls-cert-file"
37+
httpsTLSKeyFilePathFlagName = "https-tls-key-file"
3338
)
3439

3540
// We can't bind this flag to our FlagSet, so we need to handle it separately.
@@ -41,6 +46,11 @@ func getFlagSet(errorHandling pflag.ErrorHandling) *pflag.FlagSet {
4146
flagSet.String(listenAddrFlagName, ":8080", "The address where this service serves.")
4247
flagSet.Bool(prometheusCREnabledFlagName, false, "Enable Prometheus CRs as target sources")
4348
flagSet.String(kubeConfigPathFlagName, filepath.Join(homedir.HomeDir(), ".kube", "config"), "absolute path to the KubeconfigPath file")
49+
flagSet.Bool(httpsEnabledFlagName, false, "Enable HTTPS additional server")
50+
flagSet.String(listenAddrHttpsFlagName, ":8443", "The address where this service serves over HTTPS.")
51+
flagSet.String(httpsCAFilePathFlagName, "", "The path to the HTTPS server TLS CA file.")
52+
flagSet.String(httpsTLSCertFilePathFlagName, "", "The path to the HTTPS server TLS certificate file.")
53+
flagSet.String(httpsTLSKeyFilePathFlagName, "", "The path to the HTTPS server TLS key file.")
4454
zapFlagSet := flag.NewFlagSet("", flag.ErrorHandling(errorHandling))
4555
zapCmdLineOpts.BindFlags(zapFlagSet)
4656
flagSet.AddGoFlagSet(zapFlagSet)
@@ -62,3 +72,23 @@ func getListenAddr(flagSet *pflag.FlagSet) (string, error) {
6272
func getPrometheusCREnabled(flagSet *pflag.FlagSet) (bool, error) {
6373
return flagSet.GetBool(prometheusCREnabledFlagName)
6474
}
75+
76+
func getHttpsListenAddr(flagSet *pflag.FlagSet) (string, error) {
77+
return flagSet.GetString(listenAddrHttpsFlagName)
78+
}
79+
80+
func getHttpsEnabled(flagSet *pflag.FlagSet) (bool, error) {
81+
return flagSet.GetBool(httpsEnabledFlagName)
82+
}
83+
84+
func getHttpsCAFilePath(flagSet *pflag.FlagSet) (string, error) {
85+
return flagSet.GetString(httpsCAFilePathFlagName)
86+
}
87+
88+
func getHttpsTLSCertFilePath(flagSet *pflag.FlagSet) (string, error) {
89+
return flagSet.GetString(httpsTLSCertFilePathFlagName)
90+
}
91+
92+
func getHttpsTLSKeyFilePath(flagSet *pflag.FlagSet) (string, error) {
93+
return flagSet.GetString(httpsTLSKeyFilePathFlagName)
94+
}

cmd/otel-allocator/config/flags_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ func TestFlagGetters(t *testing.T) {
7070
expectedErr: true,
7171
getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getConfigFilePath(fs) },
7272
},
73+
{
74+
name: "HttpsServer",
75+
flagArgs: []string{"--" + httpsEnabledFlagName, "true"},
76+
expectedValue: true,
77+
getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getHttpsEnabled(fs) },
78+
},
79+
{
80+
name: "HttpsServerKey",
81+
flagArgs: []string{"--" + httpsTLSKeyFilePathFlagName, "/path/to/tls.key"},
82+
expectedValue: "/path/to/tls.key",
83+
getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getHttpsTLSKeyFilePath(fs) },
84+
},
7385
}
7486

7587
for _, tt := range tests {

cmd/otel-allocator/config/testdata/config_test.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ collector_selector:
44
app.kubernetes.io/managed-by: opentelemetry-operator
55
prometheus_cr:
66
scrape_interval: 60s
7+
https:
8+
enabled: true
9+
ca_file_path: /path/to/ca.pem
10+
tls_cert_file_path: /path/to/cert.pem
11+
tls_key_file_path: /path/to/key.pem
712
config:
813
scrape_configs:
914
- job_name: prometheus

cmd/otel-allocator/main.go

+25-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,17 @@ func main() {
8686
setupLog.Error(err, "Unable to initialize allocation strategy")
8787
os.Exit(1)
8888
}
89-
srv := server.NewServer(log, allocator, cfg.ListenAddr)
89+
90+
httpOptions := []server.Option{}
91+
if cfg.HTTPS.Enabled {
92+
tlsConfig, confErr := cfg.HTTPS.NewTLSConfig()
93+
if confErr != nil {
94+
setupLog.Error(confErr, "Unable to initialize TLS configuration")
95+
os.Exit(1)
96+
}
97+
httpOptions = append(httpOptions, server.WithTLSConfig(tlsConfig, cfg.HTTPS.ListenAddr))
98+
}
99+
srv := server.NewServer(log, allocator, cfg.ListenAddr, httpOptions...)
90100

91101
discoveryCtx, discoveryCancel := context.WithCancel(ctx)
92102
sdMetrics, err := discovery.CreateAndRegisterSDMetrics(prometheus.DefaultRegisterer)
@@ -189,6 +199,20 @@ func main() {
189199
setupLog.Error(shutdownErr, "Error on server shutdown")
190200
}
191201
})
202+
if cfg.HTTPS.Enabled {
203+
runGroup.Add(
204+
func() error {
205+
err := srv.StartHTTPS()
206+
setupLog.Info("HTTPS Server failed to start")
207+
return err
208+
},
209+
func(_ error) {
210+
setupLog.Info("Closing HTTPS server")
211+
if shutdownErr := srv.ShutdownHTTPS(ctx); shutdownErr != nil {
212+
setupLog.Error(shutdownErr, "Error on HTTPS server shutdown")
213+
}
214+
})
215+
}
192216
runGroup.Add(
193217
func() error {
194218
for {

0 commit comments

Comments
 (0)