Skip to content

Commit

Permalink
[CECO-570] Add operator introspection (#817)
Browse files Browse the repository at this point in the history
* Add operator introspection
  • Loading branch information
khewonc committed Jan 11, 2024
1 parent cd7b487 commit a7cdf15
Show file tree
Hide file tree
Showing 50 changed files with 2,223 additions and 256 deletions.
2 changes: 2 additions & 0 deletions apis/datadoghq/common/const.go
Expand Up @@ -17,6 +17,8 @@ const (
AgentDeploymentNameLabelKey = "agent.datadoghq.com/name"
// AgentDeploymentComponentLabelKey label key use to know with component is it
AgentDeploymentComponentLabelKey = "agent.datadoghq.com/component"
// MD5AgentDeploymentProviderLabelKey label key is used to identify which provider is being used
MD5AgentDeploymentProviderLabelKey = "agent.datadoghq.com/provider"
// MD5AgentDeploymentAnnotationKey annotation key used on a Resource in order to identify which AgentDeployment have been used to generate it.
MD5AgentDeploymentAnnotationKey = "agent.datadoghq.com/agentspechash"
// MD5ChecksumAnnotationKey annotation key is used to identify customConfig configurations
Expand Down
152 changes: 122 additions & 30 deletions apis/datadoghq/v2alpha1/condition.go
Expand Up @@ -155,74 +155,166 @@ func UpdateDeploymentStatus(dep *appsv1.Deployment, depStatus *commonv1.Deployme
}

// UpdateDaemonSetStatus updates a daemonset's DaemonSetStatus
func UpdateDaemonSetStatus(ds *appsv1.DaemonSet, dsStatus *commonv1.DaemonSetStatus, updateTime *metav1.Time) *commonv1.DaemonSetStatus {
func UpdateDaemonSetStatus(ds *appsv1.DaemonSet, dsStatus []*commonv1.DaemonSetStatus, updateTime *metav1.Time) []*commonv1.DaemonSetStatus {
if dsStatus == nil {
dsStatus = &commonv1.DaemonSetStatus{}
dsStatus = []*commonv1.DaemonSetStatus{}
}
if ds == nil {
dsStatus.State = string(DatadogAgentStateFailed)
dsStatus.Status = string(DatadogAgentStateFailed)
dsStatus = append(dsStatus, &commonv1.DaemonSetStatus{
State: string(DatadogAgentStateFailed),
Status: string(DatadogAgentStateFailed),
})
return dsStatus
}

newStatus := commonv1.DaemonSetStatus{
Desired: ds.Status.DesiredNumberScheduled,
Current: ds.Status.CurrentNumberScheduled,
Ready: ds.Status.NumberReady,
Available: ds.Status.NumberAvailable,
UpToDate: ds.Status.UpdatedNumberScheduled,
DaemonsetName: ds.ObjectMeta.Name,
}

if updateTime != nil {
dsStatus.LastUpdate = updateTime
newStatus.LastUpdate = updateTime
}
if hash, ok := ds.Annotations[apicommon.MD5AgentDeploymentAnnotationKey]; ok {
dsStatus.CurrentHash = hash
newStatus.CurrentHash = hash
}
dsStatus.Desired = ds.Status.DesiredNumberScheduled
dsStatus.Current = ds.Status.CurrentNumberScheduled
dsStatus.Ready = ds.Status.NumberReady
dsStatus.Available = ds.Status.NumberAvailable
dsStatus.UpToDate = ds.Status.UpdatedNumberScheduled

var deploymentState DatadogAgentState
switch {
case dsStatus.UpToDate != dsStatus.Desired:
case newStatus.UpToDate != newStatus.Desired:
deploymentState = DatadogAgentStateUpdating
case dsStatus.Ready == 0:
case newStatus.Ready == 0 && newStatus.Desired != 0:
deploymentState = DatadogAgentStateProgressing
default:
deploymentState = DatadogAgentStateRunning
}

dsStatus.State = fmt.Sprintf("%v", deploymentState)
dsStatus.Status = fmt.Sprintf("%v (%d/%d/%d)", deploymentState, dsStatus.Desired, dsStatus.Ready, dsStatus.UpToDate)
dsStatus.DaemonsetName = ds.ObjectMeta.Name
newStatus.State = fmt.Sprintf("%v", deploymentState)
newStatus.Status = fmt.Sprintf("%v (%d/%d/%d)", deploymentState, newStatus.Desired, newStatus.Ready, newStatus.UpToDate)

// match ds name to ds status
found := false
for id := range dsStatus {
if dsStatus[id].DaemonsetName == newStatus.DaemonsetName {
*dsStatus[id] = newStatus
found = true
}
}
if !found {
dsStatus = append(dsStatus, &newStatus)
}

return dsStatus
}

// UpdateExtendedDaemonSetStatus updates an ExtendedDaemonSet's DaemonSetStatus
func UpdateExtendedDaemonSetStatus(eds *edsdatadoghqv1alpha1.ExtendedDaemonSet, dsStatus *commonv1.DaemonSetStatus, updateTime *metav1.Time) *commonv1.DaemonSetStatus {
func UpdateExtendedDaemonSetStatus(eds *edsdatadoghqv1alpha1.ExtendedDaemonSet, dsStatus []*commonv1.DaemonSetStatus, updateTime *metav1.Time) []*commonv1.DaemonSetStatus {
if dsStatus == nil {
dsStatus = &commonv1.DaemonSetStatus{}
dsStatus = []*commonv1.DaemonSetStatus{}
}

newStatus := commonv1.DaemonSetStatus{
Desired: eds.Status.Desired,
Current: eds.Status.Current,
Ready: eds.Status.Ready,
Available: eds.Status.Available,
UpToDate: eds.Status.UpToDate,
DaemonsetName: eds.ObjectMeta.Name,
}

if updateTime != nil {
dsStatus.LastUpdate = updateTime
newStatus.LastUpdate = updateTime
}
if hash, ok := eds.Annotations[apicommon.MD5AgentDeploymentAnnotationKey]; ok {
dsStatus.CurrentHash = hash
newStatus.CurrentHash = hash
}
dsStatus.Desired = eds.Status.Desired
dsStatus.Current = eds.Status.Current
dsStatus.Ready = eds.Status.Ready
dsStatus.Available = eds.Status.Available
dsStatus.UpToDate = eds.Status.UpToDate

var deploymentState DatadogAgentState
switch {
case eds.Status.Canary != nil:
deploymentState = DatadogAgentStateCanary
case dsStatus.UpToDate != dsStatus.Desired:
case newStatus.UpToDate != newStatus.Desired:
deploymentState = DatadogAgentStateUpdating
case dsStatus.Ready == 0:
case newStatus.Ready == 0 && newStatus.Desired != 0:
deploymentState = DatadogAgentStateProgressing
default:
deploymentState = DatadogAgentStateRunning
}

dsStatus.State = fmt.Sprintf("%v", deploymentState)
dsStatus.Status = fmt.Sprintf("%v (%d/%d/%d)", deploymentState, dsStatus.Desired, dsStatus.Ready, dsStatus.UpToDate)
dsStatus.DaemonsetName = eds.ObjectMeta.Name
newStatus.State = fmt.Sprintf("%v", deploymentState)
newStatus.Status = fmt.Sprintf("%v (%d/%d/%d)", deploymentState, newStatus.Desired, newStatus.Ready, newStatus.UpToDate)

// match eds name to eds status
found := false
for id := range dsStatus {
if dsStatus[id].DaemonsetName == newStatus.DaemonsetName {
*dsStatus[id] = newStatus
found = true
}
}
if !found {
dsStatus = append(dsStatus, &newStatus)
}

return dsStatus
}

// UpdateCombinedDaemonSetStatus combines the status of multiple DaemonSetStatus
func UpdateCombinedDaemonSetStatus(dsStatus []*commonv1.DaemonSetStatus) *commonv1.DaemonSetStatus {
combinedStatus := commonv1.DaemonSetStatus{}
if len(dsStatus) == 0 {
return &combinedStatus
}

for _, status := range dsStatus {
combinedStatus.Desired += status.Desired
combinedStatus.Current += status.Current
combinedStatus.Ready += status.Ready
combinedStatus.Available += status.Available
combinedStatus.UpToDate += status.UpToDate
if combinedStatus.LastUpdate.Before(status.LastUpdate) {
combinedStatus.LastUpdate = status.LastUpdate
}
combinedStatus.State = getCombinedState(combinedStatus.State, status.State)
combinedStatus.Status = fmt.Sprintf("%v (%d/%d/%d)", combinedStatus.State, combinedStatus.Desired, combinedStatus.Ready, combinedStatus.UpToDate)
}

return &combinedStatus
}

func getCombinedState(currentState, newState string) string {
currentNum := assignNumeralState(currentState)
newNum := assignNumeralState(newState)

if currentNum == 0 {
return newState
}
if newNum == 0 {
return currentState
}
if currentNum < newNum {
return currentState
}
return newState
}

func assignNumeralState(state string) int {
switch state {
case string(DatadogAgentStateFailed):
return 1
case string(DatadogAgentStateCanary):
return 2
case string(DatadogAgentStateUpdating):
return 3
case string(DatadogAgentStateProgressing):
return 4
case string(DatadogAgentStateRunning):
return 5
default:
return 0
}
}
6 changes: 5 additions & 1 deletion apis/datadoghq/v2alpha1/datadogagent_types.go
Expand Up @@ -1072,7 +1072,11 @@ type DatadogAgentStatus struct {
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions"`
// The actual state of the Agent as an extended daemonset.
// The actual state of the Agent as a daemonset or an extended daemonset.
// +optional
// +listType=atomic
AgentList []*commonv1.DaemonSetStatus `json:"agentList,omitempty"`
// The combined actual state of all Agents as daemonsets or extended daemonsets.
// +optional
Agent *commonv1.DaemonSetStatus `json:"agent,omitempty"`
// The actual state of the Cluster Agent as a deployment.
Expand Down
11 changes: 11 additions & 0 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.

20 changes: 19 additions & 1 deletion apis/datadoghq/v2alpha1/zz_generated.openapi.go

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

2 changes: 1 addition & 1 deletion cmd/kubectl-datadog/get/get.go
Expand Up @@ -152,7 +152,7 @@ func (o *options) runV2() error {
func (o *options) renderTable(statuses []common.StatusWrapper) {
table := newTable(o.Out)
for _, item := range statuses {
data := []string{item.GetObjectMeta().GetName(), item.GetObjectMeta().GetNamespace()}
data := []string{item.GetObjectMeta().GetNamespace(), item.GetObjectMeta().GetName()}
if item.GetAgentStatus() != nil {
data = append(data, item.GetAgentStatus().Status)
} else {
Expand Down
52 changes: 51 additions & 1 deletion config/crd/bases/v1/datadoghq.com_datadogagents.yaml
Expand Up @@ -10959,7 +10959,7 @@ spec:
description: DatadogAgentStatus defines the observed state of DatadogAgent.
properties:
agent:
description: The actual state of the Agent as an extended daemonset.
description: The combined actual state of all Agents as daemonsets or extended daemonsets.
properties:
available:
description: Number of available pods in the DaemonSet.
Expand Down Expand Up @@ -11004,6 +11004,56 @@ spec:
- ready
- upToDate
type: object
agentList:
description: The actual state of the Agent as a daemonset or an extended daemonset.
items:
description: DaemonSetStatus defines the observed state of Agent running as DaemonSet.
properties:
available:
description: Number of available pods in the DaemonSet.
format: int32
type: integer
current:
description: Number of current pods in the DaemonSet.
format: int32
type: integer
currentHash:
description: CurrentHash is the stored hash of the DaemonSet.
type: string
daemonsetName:
description: DaemonsetName corresponds to the name of the created DaemonSet.
type: string
desired:
description: Number of desired pods in the DaemonSet.
format: int32
type: integer
lastUpdate:
description: LastUpdate is the last time the status was updated.
format: date-time
type: string
ready:
description: Number of ready pods in the DaemonSet.
format: int32
type: integer
state:
description: State corresponds to the DaemonSet state.
type: string
status:
description: Status corresponds to the DaemonSet computed status.
type: string
upToDate:
description: Number of up to date pods in the DaemonSet.
format: int32
type: integer
required:
- available
- current
- desired
- ready
- upToDate
type: object
type: array
x-kubernetes-list-type: atomic
clusterAgent:
description: The actual state of the Cluster Agent as a deployment.
properties:
Expand Down

0 comments on commit a7cdf15

Please sign in to comment.