-
Notifications
You must be signed in to change notification settings - Fork 99
/
controller_reconcile_dca.go
133 lines (114 loc) · 6.19 KB
/
controller_reconcile_dca.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.
package datadogagent
import (
"context"
"time"
datadoghqv2alpha1 "github.com/DataDog/datadog-operator/apis/datadoghq/v2alpha1"
apiutils "github.com/DataDog/datadog-operator/apis/utils"
componentdca "github.com/DataDog/datadog-operator/controllers/datadogagent/component/clusteragent"
"github.com/DataDog/datadog-operator/controllers/datadogagent/feature"
"github.com/DataDog/datadog-operator/controllers/datadogagent/override"
"github.com/DataDog/datadog-operator/pkg/controller/utils/datadog"
"github.com/go-logr/logr"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
func (r *Reconciler) reconcileV2ClusterAgent(logger logr.Logger, requiredComponents feature.RequiredComponents, features []feature.Feature, dda *datadoghqv2alpha1.DatadogAgent, resourcesManager feature.ResourceManagers, newStatus *datadoghqv2alpha1.DatadogAgentStatus) (reconcile.Result, error) {
var result reconcile.Result
now := metav1.NewTime(time.Now())
// Start by creating the Default Cluster-Agent deployment
deployment := componentdca.NewDefaultClusterAgentDeployment(dda)
podManagers := feature.NewPodTemplateManagers(&deployment.Spec.Template)
// Set Global setting on the default deployment
deployment.Spec.Template = *override.ApplyGlobalSettingsClusterAgent(logger, podManagers, dda, resourcesManager)
// Apply features changes on the Deployment.Spec.Template
var featErrors []error
for _, feat := range features {
if errFeat := feat.ManageClusterAgent(podManagers); errFeat != nil {
featErrors = append(featErrors, errFeat)
}
}
if len(featErrors) > 0 {
err := utilerrors.NewAggregate(featErrors)
updateStatusV2WithClusterAgent(deployment, newStatus, now, metav1.ConditionFalse, "ClusterAgent feature error", err.Error())
return result, err
}
deploymentLogger := logger.WithValues("component", datadoghqv2alpha1.ClusterAgentComponentName)
// The requiredComponents can change depending on if updates to features result in disabled components
dcaEnabled := requiredComponents.ClusterAgent.IsEnabled()
// If Override is defined for the clusterAgent component, apply the override on the PodTemplateSpec, it will cascade to container.
if componentOverride, ok := dda.Spec.Override[datadoghqv2alpha1.ClusterAgentComponentName]; ok {
if apiutils.BoolValue(componentOverride.Disabled) {
if dcaEnabled {
// The override supersedes what's set in requiredComponents; update status to reflect the conflict
datadoghqv2alpha1.UpdateDatadogAgentStatusConditions(
newStatus,
metav1.NewTime(time.Now()),
datadoghqv2alpha1.OverrideReconcileConflictConditionType,
metav1.ConditionTrue,
"OverrideConflict",
"ClusterAgent component is set to disabled",
true,
)
}
deleteStatusV2WithClusterAgent(newStatus)
return r.cleanupV2ClusterAgent(deploymentLogger, dda, deployment, resourcesManager, newStatus)
}
override.PodTemplateSpec(logger, podManagers, componentOverride, datadoghqv2alpha1.ClusterAgentComponentName, dda.Name)
override.Deployment(deployment, componentOverride)
} else if !dcaEnabled {
// If the override is not defined, then disable based on dcaEnabled value
deleteStatusV2WithClusterAgent(newStatus)
return r.cleanupV2ClusterAgent(deploymentLogger, dda, deployment, resourcesManager, newStatus)
}
return r.createOrUpdateDeployment(deploymentLogger, dda, deployment, newStatus, updateStatusV2WithClusterAgent)
}
func updateStatusV2WithClusterAgent(dca *appsv1.Deployment, newStatus *datadoghqv2alpha1.DatadogAgentStatus, updateTime metav1.Time, status metav1.ConditionStatus, reason, message string) {
newStatus.ClusterAgent = datadoghqv2alpha1.UpdateDeploymentStatus(dca, newStatus.ClusterAgent, &updateTime)
datadoghqv2alpha1.UpdateDatadogAgentStatusConditions(newStatus, updateTime, datadoghqv2alpha1.ClusterAgentReconcileConditionType, status, reason, message, true)
}
func deleteStatusV2WithClusterAgent(newStatus *datadoghqv2alpha1.DatadogAgentStatus) {
newStatus.ClusterAgent = nil
datadoghqv2alpha1.DeleteDatadogAgentStatusCondition(newStatus, datadoghqv2alpha1.ClusterAgentReconcileConditionType)
}
func (r *Reconciler) cleanupV2ClusterAgent(logger logr.Logger, dda *datadoghqv2alpha1.DatadogAgent, deployment *appsv1.Deployment, resourcesManager feature.ResourceManagers, newStatus *datadoghqv2alpha1.DatadogAgentStatus) (reconcile.Result, error) {
nsName := types.NamespacedName{
Name: deployment.GetName(),
Namespace: deployment.GetNamespace(),
}
// ClusterAgentDeployment attached to this instance
clusterAgentDeployment := &appsv1.Deployment{}
if err := r.client.Get(context.TODO(), nsName, clusterAgentDeployment); err != nil {
if errors.IsNotFound(err) {
return reconcile.Result{}, nil
}
return reconcile.Result{}, err
}
logger.Info("Deleting Cluster Agent Deployment", "deployment.Namespace", clusterAgentDeployment.Namespace, "deployment.Name", clusterAgentDeployment.Name)
event := buildEventInfo(clusterAgentDeployment.Name, clusterAgentDeployment.Namespace, clusterRoleBindingKind, datadog.DeletionEvent)
r.recordEvent(dda, event)
if err := r.client.Delete(context.TODO(), clusterAgentDeployment); err != nil {
return reconcile.Result{}, err
}
// Delete associated RBACs as well
rbacManager := resourcesManager.RBACManager()
logger.Info("Deleting Cluster Agent RBACs")
if err := rbacManager.DeleteServiceAccountByComponent(string(datadoghqv2alpha1.ClusterAgentComponentName), dda.Namespace); err != nil {
return reconcile.Result{}, err
}
if err := rbacManager.DeleteRoleByComponent(string(datadoghqv2alpha1.ClusterAgentComponentName), dda.Namespace); err != nil {
return reconcile.Result{}, err
}
if err := rbacManager.DeleteClusterRoleByComponent(string(datadoghqv2alpha1.ClusterAgentComponentName)); err != nil {
return reconcile.Result{}, err
}
newStatus.ClusterAgent = nil
return reconcile.Result{}, nil
}