Skip to content

Commit

Permalink
Add information about current disruption in budgets
Browse files Browse the repository at this point in the history
This helps owners of budget understand what disruptions
are impacting/might impact their budgets
  • Loading branch information
geobeau committed Nov 2, 2023
1 parent 2cfb540 commit 5031694
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 25 deletions.
11 changes: 11 additions & 0 deletions api/v1alpha1/applicationdisruptionbudget_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ type DisruptionBudgetStatus struct {
// Number of disruption currently seen on the cluster
// +kubebuilder:default=0
CurrentDisruptions int `json:"currentDisruptions"`

// Disruptions contains a list of disruptions that are related to the budget
Disruptions []Disruption `json:"disruptions"`
}

// Basic information about disruptions
type Disruption struct {
// Name of the disruption
Name string `json:"name"`
// State of the disruption
State string `json:"state"`
}

//+kubebuilder:object:root=true
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,23 @@ spec:
default: 0
description: Number of disruption currently seen on the cluster
type: integer
disruptions:
description: Disruptions contains a list of disruptions that are related
to the budget
items:
description: Basic information about disruptions
properties:
name:
description: Name of the disruption
type: string
state:
description: State of the disruption
type: string
required:
- name
- state
type: object
type: array
disruptionsAllowed:
default: 0
description: Number of disruption allowed on the nodes of this
Expand All @@ -189,6 +206,7 @@ spec:
type: array
required:
- currentDisruptions
- disruptions
- disruptionsAllowed
type: object
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@ spec:
default: 0
description: Number of disruption currently seen on the cluster
type: integer
disruptions:
description: Disruptions contains a list of disruptions that are related
to the budget
items:
description: Basic information about disruptions
properties:
name:
description: Name of the disruption
type: string
state:
description: State of the disruption
type: string
required:
- name
- state
type: object
type: array
disruptionsAllowed:
default: 0
description: Number of disruption allowed on the nodes of this
Expand All @@ -128,6 +145,7 @@ spec:
type: array
required:
- currentDisruptions
- disruptions
- disruptionsAllowed
type: object
type: object
Expand Down
29 changes: 17 additions & 12 deletions internal/controller/applicationdisruptionbudget_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,15 @@ func (r *ApplicationDisruptionBudgetResolver) Sync(ctx context.Context) error {

nodes := resolver.NodeSetToStringList(nodeNames)

disruptionCount, err := r.ResolveDisruption(ctx)
disruptionCount, disruptions, err := r.ResolveDisruption(ctx)
if err != nil {
return err
}

r.ApplicationDisruptionBudget.Status.WatchedNodes = nodes
r.ApplicationDisruptionBudget.Status.CurrentDisruptions = disruptionCount
r.ApplicationDisruptionBudget.Status.DisruptionsAllowed = r.ApplicationDisruptionBudget.Spec.MaxDisruptions - disruptionCount
r.ApplicationDisruptionBudget.Status.Disruptions = disruptions
return nil
}

Expand Down Expand Up @@ -259,34 +260,38 @@ func (r *ApplicationDisruptionBudgetResolver) GetSelectedNodes(ctx context.Conte
return nodesFromPods.Union(nodesFromPVCs), nil
}

func (r *ApplicationDisruptionBudgetResolver) ResolveDisruption(ctx context.Context) (int, error) {
func (r *ApplicationDisruptionBudgetResolver) ResolveDisruption(ctx context.Context) (int, []nodedisruptionv1alpha1.Disruption, error) {
disruptions := []nodedisruptionv1alpha1.Disruption{}
selectedNodes, err := r.GetSelectedNodes(ctx)
if err != nil {
return 0, err
return 0, disruptions, err
}

disruptions := 0
disruptionCount := 0

opts := []client.ListOption{}
nodeDisruptions := &nodedisruptionv1alpha1.NodeDisruptionList{}

err = r.Client.List(ctx, nodeDisruptions, opts...)
if err != nil {
return 0, err
return 0, disruptions, err
}

for _, nd := range nodeDisruptions.Items {
if nd.Status.State != nodedisruptionv1alpha1.Granted {
continue
}

impactedNodes, err := r.Resolver.GetNodeFromNodeSelector(ctx, nd.Spec.NodeSelector)
if err != nil {
return 0, err
return 0, disruptions, err
}

if selectedNodes.Intersection(impactedNodes).Len() > 0 {
disruptions++
if nd.Status.State == nodedisruptionv1alpha1.Granted {
disruptionCount++
}
disruptions = append(disruptions, nodedisruptionv1alpha1.Disruption{
Name: nd.Name,
State: string(nd.Status.State),
})
}
}
return disruptions, nil
return disruptionCount, disruptions, nil
}
30 changes: 17 additions & 13 deletions internal/controller/nodedisruptionbudget_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (r *NodeDisruptionBudgetResolver) Sync(ctx context.Context) error {

nodes := resolver.NodeSetToStringList(nodeNames)

disruptionCount, err := r.ResolveDisruption(ctx)
disruptionCount, disruptions, err := r.ResolveDisruption(ctx)
if err != nil {
return err
}
Expand All @@ -150,7 +150,7 @@ func (r *NodeDisruptionBudgetResolver) Sync(ctx context.Context) error {
disruptionsForMax := r.NodeDisruptionBudget.Spec.MaxDisruptedNodes - disruptionCount
disruptionsForMin := (len(nodes) - disruptionCount) - r.NodeDisruptionBudget.Spec.MinUndisruptedNodes
r.NodeDisruptionBudget.Status.DisruptionsAllowed = int(math.Min(float64(disruptionsForMax), float64(disruptionsForMin))) - disruptionCount

r.NodeDisruptionBudget.Status.Disruptions = disruptions
return nil
}

Expand Down Expand Up @@ -198,34 +198,38 @@ func (r *NodeDisruptionBudgetResolver) GetSelectedNodes(ctx context.Context) (re
return nodesFromPods, nil
}

func (r *NodeDisruptionBudgetResolver) ResolveDisruption(ctx context.Context) (int, error) {
func (r *NodeDisruptionBudgetResolver) ResolveDisruption(ctx context.Context) (int, []nodedisruptionv1alpha1.Disruption, error) {
disruptions := []nodedisruptionv1alpha1.Disruption{}
selectedNodes, err := r.GetSelectedNodes(ctx)
if err != nil {
return 0, err
return 0, disruptions, err
}

disruptions := 0
disruptionCount := 0

opts := []client.ListOption{}
nodeDisruptions := &nodedisruptionv1alpha1.NodeDisruptionList{}

err = r.Client.List(ctx, nodeDisruptions, opts...)
if err != nil {
return 0, err
return 0, disruptions, err
}

for _, nd := range nodeDisruptions.Items {
if nd.Status.State != nodedisruptionv1alpha1.Granted {
continue
}

impactedNodes, err := r.Resolver.GetNodeFromNodeSelector(ctx, nd.Spec.NodeSelector)
if err != nil {
return 0, err
return 0, disruptions, err
}

if selectedNodes.Intersection(impactedNodes).Len() > 0 {
disruptions++
if nd.Status.State == nodedisruptionv1alpha1.Granted {
disruptionCount++
}
disruptions = append(disruptions, nodedisruptionv1alpha1.Disruption{
Name: nd.Name,
State: string(nd.Status.State),
})
}
}
return disruptions, nil
return disruptionCount, disruptions, err
}

0 comments on commit 5031694

Please sign in to comment.