Skip to content

Commit

Permalink
feat: DatadogAgent reconcileV2 skeleton (#491)
Browse files Browse the repository at this point in the history
* feat(controller): reconcileV2 function skeleton

* new iteration

* Update code after first local run

* update after @celene review

* fix ci error

Co-authored-by: Celene Chang <celene@datadoghq.com>
  • Loading branch information
clamoriniere and celenechang committed May 18, 2022
1 parent c32af59 commit cda69ab
Show file tree
Hide file tree
Showing 41 changed files with 1,328 additions and 5,056 deletions.
21 changes: 21 additions & 0 deletions apis/datadoghq/common/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

package common

import (
"time"

appsv1 "k8s.io/api/apps/v1"
)

// Datadog const value
const (
// AgentDeploymentNameLabelKey label key use to link a Resource to a DatadogAgent
Expand All @@ -28,6 +34,8 @@ const (
DefaultAPIKeyKey = "api_key"
// DefaultTokenKey default token key (use in secret for instance).
DefaultTokenKey = "token"
// DefaultClusterAgentReplicas default cluster-agent deployment replicas
DefaultClusterAgentReplicas = 1
// DefaultClusterAgentServicePort default cluster-agent service port
DefaultClusterAgentServicePort = 5005
// DefaultMetricsServerServicePort default metrics-server port
Expand Down Expand Up @@ -67,6 +75,19 @@ const (
DefaultReadinessProbeSuccessThreshold int32 = 1
DefaultReadinessProbeFailureThreshold int32 = 6
DefaultReadinessProbeHTTPPath = "/ready"

// Default Image name
DefaultAgentImageName string = "agent"
DefaultClusterAgentImageName string = "cluster-agent"

// ExtendedDaemonset defaulting
DefaultRollingUpdateMaxUnavailable = "10%"
DefaultUpdateStrategy = appsv1.RollingUpdateDaemonSetStrategyType
DefaultRollingUpdateMaxPodSchedulerFailure = "10%"
DefaultRollingUpdateMaxParallelPodCreation int32 = 250
DefaultRollingUpdateSlowStartIntervalDuration = 1 * time.Minute
DefaultRollingUpdateSlowStartAdditiveIncrease = "5"
DefaultReconcileFrequency = 10 * time.Second
)

// Annotations
Expand Down
5 changes: 3 additions & 2 deletions apis/datadoghq/v1alpha1/datadogagent_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
func (src *DatadogAgent) ConvertTo(dst conversion.Hub) error {
ddaV2 := dst.(*v2alpha1.DatadogAgent)

if err := convertTo(src, ddaV2); err != nil {
if err := ConvertTo(src, ddaV2); err != nil {
return fmt.Errorf("unable to convert DatadogAgent %s/%s to version: %v, err: %w", src.Namespace, src.Name, dst.GetObjectKind().GroupVersionKind().Version, err)
}

Expand All @@ -33,7 +33,8 @@ func (dst *DatadogAgent) ConvertFrom(src conversion.Hub) error { //nolint
return fmt.Errorf("convert from v2alpha1 to %s is not implemented", src.GetObjectKind().GroupVersionKind().Version)
}

func convertTo(src *DatadogAgent, dst *v2alpha1.DatadogAgent) error {
// ConvertTo use to convert v1alpha1.DatadogAgent to v2alpha1.DatadogAgent
func ConvertTo(src *DatadogAgent, dst *v2alpha1.DatadogAgent) error {
// Copying ObjectMeta as a whole
dst.ObjectMeta = src.ObjectMeta

Expand Down
2 changes: 1 addition & 1 deletion apis/datadoghq/v1alpha1/datadogagent_conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestDatadogAgentConversion(t *testing.T) {
assert.NoError(t, err)

agentV2 := &v2alpha1.DatadogAgent{}
assert.NoError(t, convertTo(agentV1, agentV2))
assert.NoError(t, ConvertTo(agentV1, agentV2))

if tc.expectedFilename != "" {
expectedV2 := &v2alpha1.DatadogAgent{}
Expand Down
23 changes: 7 additions & 16 deletions apis/datadoghq/v1alpha1/datadogagent_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package v1alpha1
import (
"path"
"strings"
"time"

apicommon "github.com/DataDog/datadog-operator/apis/datadoghq/common"
commonv1 "github.com/DataDog/datadog-operator/apis/datadoghq/common/v1"
Expand All @@ -18,7 +17,6 @@ import (

edsdatadoghqv1alpha1 "github.com/DataDog/extendeddaemonset/api/v1alpha1"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -74,13 +72,6 @@ const (
defaultKubeStateMetricsCoreEnabled bool = false
defaultPrometheusScrapeEnabled bool = false
defaultPrometheusScrapeServiceEndpoints bool = false
defaultRollingUpdateMaxUnavailable = "10%"
defaultUpdateStrategy = appsv1.RollingUpdateDaemonSetStrategyType
defaultRollingUpdateMaxPodSchedulerFailure = "10%"
defaultRollingUpdateMaxParallelPodCreation int32 = 250
defaultRollingUpdateSlowStartIntervalDuration = 1 * time.Minute
defaultRollingUpdateSlowStartAdditiveIncrease = "5"
defaultReconcileFrequency = 10 * time.Second
defaultRbacCreate = true
defaultMutateUnlabelled = false
DefaultAdmissionServiceName = "datadog-admission-controller"
Expand Down Expand Up @@ -505,43 +496,43 @@ func DefaultDatadogAgentSpecDatadogAgentStrategy(agent *DatadogAgentSpecAgentSpe
}

if agent.DeploymentStrategy.UpdateStrategyType == nil {
updateStrategy := defaultUpdateStrategy
updateStrategy := apicommon.DefaultUpdateStrategy
agent.DeploymentStrategy.UpdateStrategyType = &updateStrategy
strategyOverride.UpdateStrategyType = agent.DeploymentStrategy.UpdateStrategyType
}

if agent.DeploymentStrategy.RollingUpdate.MaxUnavailable == nil {
agent.DeploymentStrategy.RollingUpdate.MaxUnavailable = &intstr.IntOrString{
Type: intstr.String,
StrVal: defaultRollingUpdateMaxUnavailable,
StrVal: apicommon.DefaultRollingUpdateMaxUnavailable,
}
strategyOverride.RollingUpdate.MaxUnavailable = agent.DeploymentStrategy.RollingUpdate.MaxUnavailable
}

if agent.DeploymentStrategy.RollingUpdate.MaxPodSchedulerFailure == nil {
agent.DeploymentStrategy.RollingUpdate.MaxPodSchedulerFailure = &intstr.IntOrString{
Type: intstr.String,
StrVal: defaultRollingUpdateMaxPodSchedulerFailure,
StrVal: apicommon.DefaultRollingUpdateMaxPodSchedulerFailure,
}
strategyOverride.RollingUpdate.MaxPodSchedulerFailure = agent.DeploymentStrategy.RollingUpdate.MaxPodSchedulerFailure
}

if agent.DeploymentStrategy.RollingUpdate.MaxParallelPodCreation == nil {
agent.DeploymentStrategy.RollingUpdate.MaxParallelPodCreation = apiutils.NewInt32Pointer(defaultRollingUpdateMaxParallelPodCreation)
agent.DeploymentStrategy.RollingUpdate.MaxParallelPodCreation = apiutils.NewInt32Pointer(apicommon.DefaultRollingUpdateMaxParallelPodCreation)
strategyOverride.RollingUpdate.MaxParallelPodCreation = agent.DeploymentStrategy.RollingUpdate.MaxParallelPodCreation
}

if agent.DeploymentStrategy.RollingUpdate.SlowStartIntervalDuration == nil {
agent.DeploymentStrategy.RollingUpdate.SlowStartIntervalDuration = &metav1.Duration{
Duration: defaultRollingUpdateSlowStartIntervalDuration,
Duration: apicommon.DefaultRollingUpdateSlowStartIntervalDuration,
}
strategyOverride.RollingUpdate.SlowStartIntervalDuration = agent.DeploymentStrategy.RollingUpdate.SlowStartIntervalDuration
}

if agent.DeploymentStrategy.RollingUpdate.SlowStartAdditiveIncrease == nil {
agent.DeploymentStrategy.RollingUpdate.SlowStartAdditiveIncrease = &intstr.IntOrString{
Type: intstr.String,
StrVal: defaultRollingUpdateSlowStartAdditiveIncrease,
StrVal: apicommon.DefaultRollingUpdateSlowStartAdditiveIncrease,
}
strategyOverride.RollingUpdate.SlowStartAdditiveIncrease = agent.DeploymentStrategy.RollingUpdate.SlowStartAdditiveIncrease
}
Expand All @@ -553,7 +544,7 @@ func DefaultDatadogAgentSpecDatadogAgentStrategy(agent *DatadogAgentSpecAgentSpe

if agent.DeploymentStrategy.ReconcileFrequency == nil {
agent.DeploymentStrategy.ReconcileFrequency = &metav1.Duration{
Duration: defaultReconcileFrequency,
Duration: apicommon.DefaultReconcileFrequency,
}
strategyOverride.ReconcileFrequency = agent.DeploymentStrategy.ReconcileFrequency
}
Expand Down
49 changes: 25 additions & 24 deletions apis/datadoghq/v1alpha1/datadogagent_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path"
"testing"

apicommon "github.com/DataDog/datadog-operator/apis/datadoghq/common"
commonv1 "github.com/DataDog/datadog-operator/apis/datadoghq/common/v1"
apiutils "github.com/DataDog/datadog-operator/apis/utils"
"github.com/DataDog/datadog-operator/pkg/defaulting"
Expand Down Expand Up @@ -471,14 +472,14 @@ func TestDefaultDatadogAgentSpecAgent(t *testing.T) {
DeploymentStrategy: &DaemonSetDeploymentStrategy{
UpdateStrategyType: (*appsv1.DaemonSetUpdateStrategyType)(apiutils.NewStringPointer("RollingUpdate")),
RollingUpdate: DaemonSetRollingUpdateSpec{
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(defaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: defaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateSlowStartAdditiveIncrease},
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(apicommon.DefaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: apicommon.DefaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateSlowStartAdditiveIncrease},
},
Canary: edsdatadoghqv1alpha1.DefaultExtendedDaemonSetSpecStrategyCanary(testCanary),
ReconcileFrequency: &metav1.Duration{Duration: defaultReconcileFrequency},
ReconcileFrequency: &metav1.Duration{Duration: apicommon.DefaultReconcileFrequency},
},
Rbac: &RbacConfig{Create: apiutils.NewBoolPointer(true)},
Apm: &APMSpec{Enabled: apiutils.NewBoolPointer(false)},
Expand Down Expand Up @@ -521,14 +522,14 @@ func TestDefaultDatadogAgentSpecAgent(t *testing.T) {
DeploymentStrategy: &DaemonSetDeploymentStrategy{
UpdateStrategyType: (*appsv1.DaemonSetUpdateStrategyType)(apiutils.NewStringPointer("RollingUpdate")),
RollingUpdate: DaemonSetRollingUpdateSpec{
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(defaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: defaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateSlowStartAdditiveIncrease},
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(apicommon.DefaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: apicommon.DefaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateSlowStartAdditiveIncrease},
},
Canary: edsdatadoghqv1alpha1.DefaultExtendedDaemonSetSpecStrategyCanary(testCanary),
ReconcileFrequency: &metav1.Duration{Duration: defaultReconcileFrequency},
ReconcileFrequency: &metav1.Duration{Duration: apicommon.DefaultReconcileFrequency},
},
Rbac: &RbacConfig{Create: apiutils.NewBoolPointer(true)},
Apm: &APMSpec{Enabled: apiutils.NewBoolPointer(false)},
Expand Down Expand Up @@ -592,13 +593,13 @@ func TestDefaultDatadogAgentSpecAgent(t *testing.T) {
DeploymentStrategy: &DaemonSetDeploymentStrategy{
UpdateStrategyType: (*appsv1.DaemonSetUpdateStrategyType)(apiutils.NewStringPointer("RollingUpdate")),
RollingUpdate: DaemonSetRollingUpdateSpec{
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(defaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: defaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateSlowStartAdditiveIncrease},
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(apicommon.DefaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: apicommon.DefaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateSlowStartAdditiveIncrease},
},
ReconcileFrequency: &metav1.Duration{Duration: defaultReconcileFrequency},
ReconcileFrequency: &metav1.Duration{Duration: apicommon.DefaultReconcileFrequency},
},
Rbac: &RbacConfig{Create: apiutils.NewBoolPointer(true)},
Apm: &APMSpec{Enabled: apiutils.NewBoolPointer(false)},
Expand Down Expand Up @@ -653,14 +654,14 @@ func TestDefaultDatadogAgentSpecAgent(t *testing.T) {
DeploymentStrategy: &DaemonSetDeploymentStrategy{
UpdateStrategyType: (*appsv1.DaemonSetUpdateStrategyType)(apiutils.NewStringPointer("RollingUpdate")),
RollingUpdate: DaemonSetRollingUpdateSpec{
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(defaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: defaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: defaultRollingUpdateSlowStartAdditiveIncrease},
MaxUnavailable: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxUnavailable},
MaxPodSchedulerFailure: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateMaxPodSchedulerFailure},
MaxParallelPodCreation: apiutils.NewInt32Pointer(apicommon.DefaultRollingUpdateMaxParallelPodCreation),
SlowStartIntervalDuration: &metav1.Duration{Duration: apicommon.DefaultRollingUpdateSlowStartIntervalDuration},
SlowStartAdditiveIncrease: &intstr.IntOrString{Type: intstr.String, StrVal: apicommon.DefaultRollingUpdateSlowStartAdditiveIncrease},
},
Canary: edsdatadoghqv1alpha1.DefaultExtendedDaemonSetSpecStrategyCanary(testCanary),
ReconcileFrequency: &metav1.Duration{Duration: defaultReconcileFrequency},
ReconcileFrequency: &metav1.Duration{Duration: apicommon.DefaultReconcileFrequency},
},
Apm: &APMSpec{
Enabled: apiutils.NewBoolPointer(false),
Expand Down
77 changes: 77 additions & 0 deletions apis/datadoghq/v2alpha1/condition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package v2alpha1

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// UpdateDatadogAgentStatusConditionsFailure used to update the failure StatusConditions
func UpdateDatadogAgentStatusConditionsFailure(status *DatadogAgentStatus, now metav1.Time, conditionType, reason, message string, err error) {
if err != nil {
UpdateDatadogAgentStatusConditions(status, now, conditionType, metav1.ConditionTrue, reason, fmt.Sprintf("msg:%s, err:%v", message, err), true)
} else {
UpdateDatadogAgentStatusConditions(status, now, conditionType, metav1.ConditionFalse, reason, message, true)
}
}

// UpdateDatadogAgentStatusConditions used to update a specific string in conditions
func UpdateDatadogAgentStatusConditions(status *DatadogAgentStatus, now metav1.Time, t string, conditionStatus metav1.ConditionStatus, reason, message string, writeFalseIfNotExist bool) {
idConditionComplete := getIndexForConditionType(status, t)
if idConditionComplete >= 0 {
UpdateDatadogAgentStatusCondition(status.Conditions[idConditionComplete], now, t, conditionStatus, reason, message)
} else if conditionStatus == metav1.ConditionTrue || writeFalseIfNotExist {
// Only add if the condition is True
status.Conditions = append(status.Conditions, NewDatadogAgentStatusCondition(t, conditionStatus, now, reason, message))
}
}

// UpdateDatadogAgentStatusCondition used to update a specific string
func UpdateDatadogAgentStatusCondition(condition metav1.Condition, now metav1.Time, t string, conditionStatus metav1.ConditionStatus, reason, message string) metav1.Condition {
if condition.Status != conditionStatus {
condition.LastTransitionTime = now
condition.Status = conditionStatus
}
condition.LastTransitionTime = now
condition.Message = message
condition.Reason = reason

return condition
}

// SetDatadogAgentStatusCondition use to set a condition
func SetDatadogAgentStatusCondition(status *DatadogAgentStatus, condition *metav1.Condition) {
idConditionComplete := getIndexForConditionType(status, condition.Type)
if idConditionComplete >= 0 {
status.Conditions[idConditionComplete] = *condition
} else {
status.Conditions = append(status.Conditions, *condition)
}
}

// NewDatadogAgentStatusCondition returns new DatadogAgentCondition instance
func NewDatadogAgentStatusCondition(conditionType string, conditionStatus metav1.ConditionStatus, now metav1.Time, reason, message string) metav1.Condition {
return metav1.Condition{
Type: conditionType,
Status: conditionStatus,
LastTransitionTime: now,
Reason: reason,
Message: message,
}
}

func getIndexForConditionType(status *DatadogAgentStatus, t string) int {
idCondition := -1
if status == nil {
return idCondition
}

for i, condition := range status.Conditions {
if condition.Type == t {
idCondition = i
break
}
}

return idCondition
}
13 changes: 13 additions & 0 deletions apis/datadoghq/v2alpha1/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package v2alpha1

const (

// ClusterAgentReconcileConditionType ReconcileConditionType for Cluster Agent component
ClusterAgentReconcileConditionType = "ClusterAgentReconcile"
// AgentReconcileConditionType ReconcileConditionType for Agent component
AgentReconcileConditionType = "AgentReconcile"
// ClusterCheckRunnerReconcileConditionType ReconcileConditionType for Cluster Check Runner component
ClusterCheckRunnerReconcileConditionType = "ClusterCheckRunnerReconcile"
// DatadogAgentReconcileErrorConditionType ReconcileConditionType for DatadogAgent reconcile error
DatadogAgentReconcileErrorConditionType = "DatadogAgentReconcileError"
)
6 changes: 4 additions & 2 deletions apis/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,9 +835,11 @@ type DatadogAgentGenericContainer struct {
// DatadogAgentStatus defines the observed state of DatadogAgent.
// +k8s:openapi-gen=true
type DatadogAgentStatus struct {
// DefaultOverride contains attributes that were not configured that the runtime defaulted.
// Conditions Represents the latest available observations of a DatadogAgent's current state.
// +optional
DefaultOverride *DatadogAgentSpec `json:"defaultOverride,omitempty"`
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions"`
}

// DatadogAgent Deployment with the Datadog Operator.
Expand Down
10 changes: 6 additions & 4 deletions apis/datadoghq/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cda69ab

Please sign in to comment.