Skip to content

Commit b460f35

Browse files
authored
add metadata forwarder (DataDog#1999)
* add metadata forwarder * refactor version and platform info, update client to reader
1 parent 047cda4 commit b460f35

9 files changed

Lines changed: 491 additions & 46 deletions

File tree

cmd/main.go

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@ import (
2020
"go.uber.org/zap/zapcore"
2121
"gopkg.in/DataDog/dd-trace-go.v1/profiler"
2222
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
23+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2324
"k8s.io/apimachinery/pkg/runtime"
2425
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
26+
apimversion "k8s.io/apimachinery/pkg/version"
27+
"k8s.io/client-go/discovery"
2528
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
29+
"k8s.io/client-go/rest"
2630
"k8s.io/client-go/tools/leaderelection/resourcelock"
2731
"k8s.io/klog/v2"
2832
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
2933
ctrl "sigs.k8s.io/controller-runtime"
34+
"sigs.k8s.io/controller-runtime/pkg/client"
3035
ctrlzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
3136
"sigs.k8s.io/controller-runtime/pkg/manager"
3237
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
@@ -37,9 +42,13 @@ import (
3742
"github.com/DataDog/datadog-operator/internal/controller"
3843
"github.com/DataDog/datadog-operator/internal/controller/metrics"
3944
"github.com/DataDog/datadog-operator/pkg/config"
45+
"github.com/DataDog/datadog-operator/pkg/constants"
4046
"github.com/DataDog/datadog-operator/pkg/controller/debug"
47+
"github.com/DataDog/datadog-operator/pkg/controller/utils/metadata"
48+
"github.com/DataDog/datadog-operator/pkg/kubernetes"
4149
"github.com/DataDog/datadog-operator/pkg/remoteconfig"
4250
"github.com/DataDog/datadog-operator/pkg/secrets"
51+
"github.com/DataDog/datadog-operator/pkg/utils"
4352
"github.com/DataDog/datadog-operator/pkg/version"
4453

4554
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
@@ -52,8 +61,9 @@ const (
5261
)
5362

5463
var (
55-
scheme = runtime.NewScheme()
56-
setupLog = ctrl.Log.WithName("setup")
64+
scheme = runtime.NewScheme()
65+
setupLog = ctrl.Log.WithName("setup")
66+
metadataLog = ctrl.Log.WithName("metadata")
5767
)
5868

5969
func init() {
@@ -344,10 +354,25 @@ func run(opts *options) error {
344354
DatadogGenericResourceEnabled: opts.datadogGenericResourceEnabled,
345355
}
346356

347-
if err = controller.SetupControllers(setupLog, mgr, options); err != nil {
357+
versionInfo, platformInfo, err := getVersionAndPlatformInfo(rest.CopyConfig(mgr.GetConfig()))
358+
if err != nil {
359+
return err
360+
}
361+
362+
if versionInfo != nil {
363+
gitVersion := versionInfo.GitVersion
364+
if !utils.IsAboveMinVersion(gitVersion, "1.16-0") {
365+
setupLog.Error(nil, "Detected Kubernetes version <1.16 which requires CRD version apiextensions.k8s.io/v1beta1. "+
366+
"CRDs of this version were removed in v1.10.0.")
367+
}
368+
}
369+
370+
if err = controller.SetupControllers(setupLog, mgr, platformInfo, options); err != nil {
348371
return setupErrorf(setupLog, err, "Unable to start controllers")
349372
}
350373

374+
setupAndStartMetadataForwarder(metadataLog, mgr.GetAPIReader(), versionInfo.String(), opts)
375+
351376
// +kubebuilder:scaffold:builder
352377

353378
setupLog.Info("starting manager")
@@ -358,6 +383,39 @@ func run(opts *options) error {
358383
return nil
359384
}
360385

386+
func getVersionAndPlatformInfo(configCopy *rest.Config) (*apimversion.Info, kubernetes.PlatformInfo, error) {
387+
// Never use original mgr.GetConfig(), always copy as clients might modify the configuration
388+
discoveryClient, err := discovery.NewDiscoveryClientForConfig(configCopy)
389+
if err != nil {
390+
return nil, kubernetes.PlatformInfo{}, fmt.Errorf("unable to get discovery client: %w", err)
391+
}
392+
393+
versionInfo, err := discoveryClient.ServerVersion()
394+
if err != nil {
395+
return nil, kubernetes.PlatformInfo{}, fmt.Errorf("unable to get APIServer version: %w", err)
396+
}
397+
398+
groups, resources, err := getServerGroupsAndResources(setupLog, discoveryClient)
399+
if err != nil {
400+
return nil, kubernetes.PlatformInfo{}, fmt.Errorf("unable to get API resource versions: %w", err)
401+
}
402+
platformInfo := kubernetes.NewPlatformInfo(versionInfo, groups, resources)
403+
404+
return versionInfo, platformInfo, nil
405+
406+
}
407+
408+
func getServerGroupsAndResources(log logr.Logger, discoveryClient *discovery.DiscoveryClient) ([]*v1.APIGroup, []*v1.APIResourceList, error) {
409+
groups, resources, err := discoveryClient.ServerGroupsAndResources()
410+
if err != nil {
411+
if !discovery.IsGroupDiscoveryFailedError(err) {
412+
log.Info("GetServerGroupsAndResources ERROR", "err", err)
413+
return nil, nil, err
414+
}
415+
}
416+
return groups, resources, nil
417+
}
418+
361419
func customSetupLogging(logLevel zapcore.Level, logEncoder string) error {
362420
encoderConfig := zap.NewProductionEncoderConfig()
363421
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
@@ -419,3 +477,28 @@ func setupErrorf(logger logr.Logger, err error, msg string, keysAndValues ...any
419477
setupLog.Error(err, msg, keysAndValues...)
420478
return fmt.Errorf("%s, err:%w", msg, err)
421479
}
480+
481+
func setupAndStartMetadataForwarder(logger logr.Logger, client client.Reader, kubernetesVersion string, options *options) {
482+
mdf := metadata.NewMetadataForwarder(logger, client)
483+
mdf.OperatorMetadata = metadata.OperatorMetadata{
484+
OperatorVersion: version.GetVersion(),
485+
KubernetesVersion: kubernetesVersion,
486+
InstallMethodTool: "datadog-operator",
487+
InstallMethodToolVersion: version.GetVersion(),
488+
IsLeader: true,
489+
DatadogAgentEnabled: options.datadogAgentEnabled,
490+
DatadogMonitorEnabled: options.datadogMonitorEnabled,
491+
DatadogDashboardEnabled: options.datadogDashboardEnabled,
492+
DatadogSLOEnabled: options.datadogSLOEnabled,
493+
DatadogGenericResourceEnabled: options.datadogGenericResourceEnabled,
494+
DatadogAgentProfileEnabled: options.datadogAgentProfileEnabled,
495+
LeaderElectionEnabled: options.enableLeaderElection,
496+
ExtendedDaemonSetEnabled: options.supportExtendedDaemonset,
497+
RemoteConfigEnabled: options.remoteConfigEnabled,
498+
IntrospectionEnabled: options.introspectionEnabled,
499+
ConfigDDURL: os.Getenv(constants.DDURL),
500+
ConfigDDSite: os.Getenv(constants.DDSite),
501+
}
502+
503+
mdf.Start()
504+
}

config/manager/manager.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ spec:
4343
imagePullPolicy: IfNotPresent
4444
name: manager
4545
env:
46+
- name: DD_HOSTNAME
47+
valueFrom:
48+
fieldRef:
49+
fieldPath: spec.nodeName
4650
- name: POD_NAME
4751
valueFrom:
4852
fieldRef:

internal/controller/datadogagent/component/clusterchecksrunner/default.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func defaultEnvVars(dda metav1.Object) []corev1.EnvVar {
259259
Value: "false",
260260
},
261261
{
262-
Name: DDHostname,
262+
Name: constants.DDHostName,
263263
ValueFrom: &corev1.EnvVarSource{
264264
FieldRef: &corev1.ObjectFieldSelector{
265265
FieldPath: common.FieldPathSpecNodeName,

internal/controller/datadogagent/component/clusterchecksrunner/envvar.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ const (
1010
DDClcRunnerHost = "DD_CLC_RUNNER_HOST"
1111
DDClcRunnerID = "DD_CLC_RUNNER_ID"
1212
DDEnableMetadataCollection = "DD_ENABLE_METADATA_COLLECTION"
13-
DDHostname = "DD_HOSTNAME"
1413
)

internal/controller/setup.go

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1616
"k8s.io/apimachinery/pkg/runtime/schema"
1717
"k8s.io/apimachinery/pkg/types"
18-
"k8s.io/client-go/discovery"
1918
"k8s.io/client-go/dynamic"
2019
"k8s.io/client-go/rest"
2120
ctrl "sigs.k8s.io/controller-runtime"
@@ -29,7 +28,6 @@ import (
2928
"github.com/DataDog/datadog-operator/pkg/datadogclient"
3029
"github.com/DataDog/datadog-operator/pkg/kubernetes"
3130
"github.com/DataDog/datadog-operator/pkg/kubernetes/rbac"
32-
"github.com/DataDog/datadog-operator/pkg/utils"
3331
)
3432

3533
const (
@@ -89,33 +87,7 @@ var controllerStarters = map[string]starterFunc{
8987
}
9088

9189
// SetupControllers starts all controllers (also used by e2e tests)
92-
func SetupControllers(logger logr.Logger, mgr manager.Manager, options SetupOptions) error {
93-
// Get some information about Kubernetes version
94-
// Never use original mgr.GetConfig(), always copy as clients might modify the configuration
95-
discoveryConfig := rest.CopyConfig(mgr.GetConfig())
96-
discoveryClient, err := discovery.NewDiscoveryClientForConfig(discoveryConfig)
97-
if err != nil {
98-
return fmt.Errorf("unable to get discovery client: %w", err)
99-
}
100-
101-
versionInfo, err := discoveryClient.ServerVersion()
102-
if err != nil {
103-
return fmt.Errorf("unable to get APIServer version: %w", err)
104-
}
105-
106-
if versionInfo != nil {
107-
gitVersion := versionInfo.GitVersion
108-
if !utils.IsAboveMinVersion(gitVersion, "1.16-0") {
109-
logger.Error(nil, "Detected Kubernetes version <1.16 which requires CRD version apiextensions.k8s.io/v1beta1. "+
110-
"CRDs of this version will be deprecated and will not be updated starting with Operator v1.8.0 and will be removed in v1.10.0.")
111-
}
112-
}
113-
114-
groups, resources, err := getServerGroupsAndResources(logger, discoveryClient)
115-
if err != nil {
116-
return fmt.Errorf("unable to get API resource versions: %w", err)
117-
}
118-
platformInfo := kubernetes.NewPlatformInfo(versionInfo, groups, resources)
90+
func SetupControllers(logger logr.Logger, mgr manager.Manager, platformInfo kubernetes.PlatformInfo, options SetupOptions) error {
11991

12092
var metricForwardersMgr datadog.MetricsForwardersManager
12193
if options.OperatorMetricsEnabled {
@@ -131,17 +103,6 @@ func SetupControllers(logger logr.Logger, mgr manager.Manager, options SetupOpti
131103
return nil
132104
}
133105

134-
func getServerGroupsAndResources(log logr.Logger, discoveryClient *discovery.DiscoveryClient) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
135-
groups, resources, err := discoveryClient.ServerGroupsAndResources()
136-
if err != nil {
137-
if !discovery.IsGroupDiscoveryFailedError(err) {
138-
log.Info("GetServerGroupsAndResources ERROR", "err", err)
139-
return nil, nil, err
140-
}
141-
}
142-
return groups, resources, nil
143-
}
144-
145106
func startDatadogAgent(logger logr.Logger, mgr manager.Manager, pInfo kubernetes.PlatformInfo, options SetupOptions, metricForwardersMgr datadog.MetricsForwardersManager) error {
146107
if !options.DatadogAgentEnabled {
147108
logger.Info("Feature disabled, not starting the controller", "controller", agentControllerName)

internal/controller/suite_v2_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636

3737
datadoghqv1alpha1 "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
3838
"github.com/DataDog/datadog-operator/internal/controller/testutils"
39+
"github.com/DataDog/datadog-operator/pkg/kubernetes"
3940

4041
"github.com/DataDog/datadog-operator/pkg/config"
4142
// +kubebuilder:scaffold:imports
@@ -112,7 +113,9 @@ var _ = BeforeSuite(func() {
112113
V2APIEnabled: true,
113114
}
114115

115-
err = SetupControllers(logger, mgr, options)
116+
dummyPlatformInfo := kubernetes.PlatformInfo{}
117+
118+
err = SetupControllers(logger, mgr, dummyPlatformInfo, options)
116119
Expect(err).ToNot(HaveOccurred())
117120

118121
var mgrCtx context.Context

pkg/constants/envvar.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ const (
1313
DDSite = "DD_SITE"
1414
DDClusterName = "DD_CLUSTER_NAME"
1515
DDLogLevel = "DD_LOG_LEVEL"
16+
DDHostName = "DD_HOSTNAME"
1617
)

0 commit comments

Comments
 (0)