Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metadata forwarder #1485

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ import (
"github.com/go-logr/logr"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

"github.com/DataDog/datadog-operator/api/datadoghq/common"
datadoghqv1alpha1 "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
datadoghqv2alpha1 "github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
"github.com/DataDog/datadog-operator/internal/controller"
"github.com/DataDog/datadog-operator/internal/controller/metrics"

"github.com/DataDog/datadog-operator/pkg/config"
"github.com/DataDog/datadog-operator/pkg/controller/debug"
"github.com/DataDog/datadog-operator/pkg/controller/utils/metadata"
"github.com/DataDog/datadog-operator/pkg/remoteconfig"
"github.com/DataDog/datadog-operator/pkg/secrets"
"github.com/DataDog/datadog-operator/pkg/version"
Expand All @@ -52,8 +53,9 @@ const (
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
metadataLog = ctrl.Log.WithName("metadata")
)

func init() {
Expand Down Expand Up @@ -261,6 +263,7 @@ func run(opts *options) error {

// Custom setup
customSetupHealthChecks(setupLog, mgr, &opts.maximumGoroutines)
mdf := setupMetadataForwarder(metadataLog, opts)

creds, err := config.NewCredentialManager().GetCredentials()
if err != nil && opts.datadogMonitorEnabled {
Expand Down Expand Up @@ -308,17 +311,22 @@ func run(opts *options) error {
DatadogDashboardEnabled: opts.datadogDashboardEnabled,
}

if err = controller.SetupControllers(setupLog, mgr, options); err != nil {
if err = controller.SetupControllers(setupLog, mgr, options, mdf); err != nil {
return setupErrorf(setupLog, err, "Unable to start controllers")
}

// send metadata in a new goroutine
mdf.Start()

// +kubebuilder:scaffold:builder

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
return setupErrorf(setupLog, err, "Problem running manager")
}

mdf.Stop()

return nil
}

Expand Down Expand Up @@ -363,3 +371,22 @@ func setupErrorf(logger logr.Logger, err error, msg string, keysAndValues ...any
setupLog.Error(err, msg, keysAndValues...)
return fmt.Errorf("%s, err:%w", msg, err)
}

func setupMetadataForwarder(logger logr.Logger, options *options) *metadata.MetadataForwarder {
mf := metadata.NewMetadataForwarder(logger)
mf.OperatorMetadata = metadata.OperatorMetadata{
DatadogAgentEnabled: options.datadogAgentEnabled,
DatadogMonitorEnabled: options.datadogMonitorEnabled,
DatadogDashboardEnabled: options.datadogDashboardEnabled,
DatadogSLOEnabled: options.datadogSLOEnabled,
DatadogAgentProfileEnabled: options.datadogAgentProfileEnabled,
ExtendedDaemonSetEnabled: options.supportExtendedDaemonset,
RemoteConfigEnabled: options.remoteConfigEnabled,
IntrospectionEnabled: options.introspectionEnabled,
OperatorVersion: version.GetVersion(),
ConfigDDURL: os.Getenv(common.DDURL),
ConfigDDSite: os.Getenv(common.DDSite),
}

return mf
}
14 changes: 9 additions & 5 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5og
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k=
cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
Expand Down Expand Up @@ -1065,8 +1066,6 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.327 h1:ZS8oO4+7MOBLhkdwIhgtVeDzCeWOlTfKJS7EgggbIEY=
github.com/aws/aws-sdk-go v1.44.327/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.53.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aws/aws-sdk-go-v2 v1.0.0/go.mod h1:smfAbmpW+tcRVuNUjo3MOArSZmW72t62rkCzc2i0TWM=
Expand Down Expand Up @@ -1181,7 +1180,6 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
Expand Down Expand Up @@ -1422,7 +1420,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down Expand Up @@ -2150,6 +2147,7 @@ github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aW
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
Expand Down Expand Up @@ -2199,6 +2197,7 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinmbeaulieu/eq-go v1.0.0 h1:AQgYHURDOmnVJ62jnEk0W/7yFKEn+Lv8RHN6t7mB0Zo=
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
Expand Down Expand Up @@ -2310,6 +2309,7 @@ github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
Expand Down Expand Up @@ -2443,7 +2443,6 @@ github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
Expand Down Expand Up @@ -3594,6 +3593,7 @@ google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45
google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750=
google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk=
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
google.golang.org/api v0.160.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw=
Expand Down Expand Up @@ -4072,19 +4072,22 @@ k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo=
mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
modernc.org/cc/v4 v4.2.1/go.mod h1:0O8vuqhQfwBy+piyfEjzWIUGV4I3TPsXSf0W05+lgN8=
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws=
modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo=
modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI=
modernc.org/ccgo/v4 v4.0.0-20230612200659-63de3e82e68d/go.mod h1:austqj6cmEDRfewsUvmGmyIgsI/Nq87oTXlfTgY85Fc=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
Expand All @@ -4107,6 +4110,7 @@ modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=
modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
Expand Down
4 changes: 3 additions & 1 deletion internal/controller/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
componentagent "github.com/DataDog/datadog-operator/internal/controller/datadogagent/component/agent"

"github.com/DataDog/datadog-operator/pkg/config"
"github.com/DataDog/datadog-operator/pkg/controller/utils/metadata"
"github.com/DataDog/datadog-operator/pkg/datadogclient"
"github.com/DataDog/datadog-operator/pkg/kubernetes"
"github.com/DataDog/datadog-operator/pkg/utils"
Expand Down Expand Up @@ -77,7 +78,7 @@ var controllerStarters = map[string]starterFunc{
}

// SetupControllers starts all controllers (also used by e2e tests)
func SetupControllers(logger logr.Logger, mgr manager.Manager, options SetupOptions) error {
func SetupControllers(logger logr.Logger, mgr manager.Manager, options SetupOptions, mf *metadata.MetadataForwarder) error {
// Get some information about Kubernetes version
// Never use original mgr.GetConfig(), always copy as clients might modify the configuration
discoveryConfig := rest.CopyConfig(mgr.GetConfig())
Expand All @@ -92,6 +93,7 @@ func SetupControllers(logger logr.Logger, mgr manager.Manager, options SetupOpti
}

if versionInfo != nil {
mf.OperatorMetadata.KubernetesVersion = versionInfo.String()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could define discoveryClient one level up and pass it to SetupControllers, instead of passing mf? (since mf isn't related to controller setup.) then we could declare versionInfo one level up too and pass it to setupMetadataForwarder

gitVersion := versionInfo.GitVersion
if !utils.IsAboveMinVersion(gitVersion, "1.16-0") {
logger.Error(nil, "Detected Kubernetes version <1.16 which requires CRD version apiextensions.k8s.io/v1beta1. "+
Expand Down
5 changes: 4 additions & 1 deletion internal/controller/suite_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/DataDog/datadog-operator/internal/controller/testutils"

"github.com/DataDog/datadog-operator/pkg/config"
"github.com/DataDog/datadog-operator/pkg/controller/utils/metadata"
// +kubebuilder:scaffold:imports
)

Expand Down Expand Up @@ -112,7 +113,9 @@ var _ = BeforeSuite(func() {
V2APIEnabled: true,
}

err = SetupControllers(logger, mgr, options)
mdf := metadata.NewMetadataForwarder(logger)

err = SetupControllers(logger, mgr, options, mdf)
Expect(err).ToNot(HaveOccurred())

var mgrCtx context.Context
Expand Down
148 changes: 148 additions & 0 deletions pkg/controller/utils/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package metadata

import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strconv"
"time"

"github.com/go-logr/logr"
)

const (
apiHTTPHeaderKey = "Dd-Api-Key"
useragentHTTPHeaderKey = "User-Agent"
contentTypeHeaderKey = "Content-Type"
acceptHeaderKey = "Accept"

defaultURLScheme = "https"
defaultURLHost = "app.datadog.com"
defaultURLHostPrefix = "app."
defaultURLPath = "api/v1/metadata"

defaultInterval = 1 * time.Minute
)

type MetadataForwarder struct {
OperatorMetadata OperatorMetadata
logger logr.Logger
stopChan chan struct{}
}

// NewMetadataForwarder creates a new instance of the metadata forwarder
func NewMetadataForwarder(logger logr.Logger) *MetadataForwarder {
return &MetadataForwarder{
OperatorMetadata: OperatorMetadata{},
logger: logger,
stopChan: make(chan struct{}),
}
}

// Start starts the metadata forwarder
func (mdf *MetadataForwarder) Start() {
ticker := time.NewTicker(getTickerInterval(mdf.logger))
go func() {
for {
select {
case <-mdf.stopChan:
ticker.Stop()
mdf.logger.Info("Stopping ticker for metadata forwarder case")
return
case <-ticker.C:
if err := mdf.sendMetadata(); err != nil {
mdf.logger.Error(err, "Error while sending metadata")
}
}
}
}()
}

// Stop stops the metadata forwarder
func (mdf *MetadataForwarder) Stop() {
close(mdf.stopChan)
mdf.logger.Info("Stopping metadata forwarder")
}

func (mdf *MetadataForwarder) sendMetadata() error {
url := createURL(mdf.logger)
mdf.logger.V(1).Info("Sending metadata to URL", "url", url)

reader := bytes.NewReader(mdf.createPayload())
req, err := http.NewRequestWithContext(context.TODO(), "POST", url, reader)
if err != nil {
mdf.logger.Error(err, "Error creating request", "url", url, "reader", reader)
}
req.Header = getHeaders()

client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("Error sending request: %w", err)
}

defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("Failed to read response body: %w", err)
}
mdf.logger.V(1).Info("Read response", "status code", resp.StatusCode, "body", string(body))
return nil
}

func getHeaders() http.Header {
header := http.Header{}
header.Set(apiHTTPHeaderKey, os.Getenv("DD_API_KEY"))
header.Set(useragentHTTPHeaderKey, fmt.Sprintf("datadog-operator/%s", "test")) // TODO: use operator version

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Code Quality Violation

Suggested change
header.Set(useragentHTTPHeaderKey, fmt.Sprintf("datadog-operator/%s", "test")) // TODO: use operator version
header.Set(useragentHTTPHeaderKey, "datadog-operator/test") // TODO: use operator version
No need to use fmt.Sprintf("%s", var) when var is a string. (...read more)

In Go, it is recommended to avoid using fmt.Sprintf() unnecessarily when printing a string and instead use the string directly. This guideline promotes code simplicity, readability, and execution efficiency. Here are a few reasons why using the string directly is preferred over fmt.Sprintf() for simple string printing:

  1. Readability: Using the string directly is more concise and easier to read, especially when the format specifiers offered by fmt.Sprintf() are not needed. By avoiding the additional fmt.Sprintf() call, the code becomes cleaner and more straightforward, conveying its intention more effectively.
  2. Performance: Invoking fmt.Sprintf() requires additional CPU cycles and memory allocation. Although the overhead may seem insignificant in isolation, repeated usage or in performance-critical code paths can impact the overall runtime efficiency of your program. By directly printing the string, you eliminate the unnecessary overhead of formatting and allocation associated with fmt.Sprintf().
  3. Type safety: When using fmt.Sprintf(), the compiler cannot check the correctness of the format specifiers and arguments. This can potentially lead to runtime errors or incorrect output if the format specifiers or arguments do not match. By directly using the string, you avoid the risk of format string-related errors and ensure type safety.

That said, fmt.Sprintf() can still be useful in scenarios where formatting is needed, such as when building complex strings or including variable values within the output. fmt.Sprintf() offers powerful formatting options and is essential for more advanced string formatting requirements.

In summary, when it comes to simple string printing without any formatting needs or complex variable substitutions, it is best to use the string directly instead of fmt.Sprintf(). This approach promotes code simplicity, better performance, and improved code readability. However, when formatting is necessary, fmt.Sprintf() remains a powerful tool to handle more intricate string construction.

View in Datadog  Leave us feedback  Documentation

header.Set(contentTypeHeaderKey, "application/json")
header.Set(acceptHeaderKey, "application/json")
return header
}

func createURL(logger logr.Logger) string {
url := url.URL{
Scheme: defaultURLScheme,
Host: defaultURLHost,
Path: defaultURLPath,
}
// prioritize URL set in env var
if mdURLFromEnvVar := os.Getenv("METADATA_URL"); mdURLFromEnvVar != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want this to be configurable?

parsedURL, err := url.Parse(mdURLFromEnvVar)
if err != nil {
logger.Error(err, "Error parsing METADATA_URL")
}
// TODO: check for correct URL format
return parsedURL.String()
}
// check site env var
// example: datadoghq.com
if siteFromEnvVar := os.Getenv("DD_SITE"); siteFromEnvVar != "" {
url.Host = defaultURLHostPrefix + siteFromEnvVar
}
// check url env var
// example: https://app.datadoghq.com
if urlFromEnvVar := os.Getenv("DD_URL"); urlFromEnvVar != "" {
url.Host = urlFromEnvVar
}

return url.String()
}

func getTickerInterval(logger logr.Logger) time.Duration {
interval := defaultInterval
if s := os.Getenv("METADATA_INTERVAL"); s != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if we need this to be configurable as well

i, err := strconv.Atoi(s)
if err != nil {
logger.Error(err, "Error coverting METADATA_INTERVAL")
}
interval = time.Duration(i) * time.Minute
}
logger.Info("Operator metadata will be sent periodically", "frequency (seconds)", interval)
return interval
}
Loading
Loading