Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Commit

Permalink
Merge pull request #69 from bookingcom/isutton/6-capacity-fleet-summary
Browse files Browse the repository at this point in the history
Introduce fleet summary report in Capacity Target
  • Loading branch information
parhamdoustdar authored Mar 19, 2019
2 parents 9cbf71d + 3af17cb commit 5a8ddb1
Show file tree
Hide file tree
Showing 11 changed files with 1,481 additions and 36 deletions.
35 changes: 35 additions & 0 deletions pkg/apis/shipper/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,47 @@ type CapacityTargetStatus struct {
Clusters []ClusterCapacityStatus `json:"clusters,omitempty"`
}

type ClusterCapacityReportContainerBreakdownExample struct {
Pod string `json:"pod"`
Message *string `json:"message,omitempty"`
}

type ClusterCapacityReportContainerStateBreakdown struct {
Count uint32 `json:"count"`
Example ClusterCapacityReportContainerBreakdownExample `json:"example"`
Reason string `json:"reason,omitempty"`
Type string `json:"type"`
}

type ClusterCapacityReportContainerBreakdown struct {
Name string `json:"name"`
States []ClusterCapacityReportContainerStateBreakdown `json:"states"`
}

type ClusterCapacityReportBreakdown struct {
Containers []ClusterCapacityReportContainerBreakdown `json:"containers,omitempty"`
Count uint32 `json:"count"`
Reason string `json:"reason,omitempty"`
Status string `json:"status"`
Type string `json:"type"`
}

type ClusterCapacityReportOwner struct {
Name string `json:"name"`
}

type ClusterCapacityReport struct {
Owner ClusterCapacityReportOwner `json:"owner"`
Breakdown []ClusterCapacityReportBreakdown `json:"breakdown,omitempty"`
}

type ClusterCapacityStatus struct {
Name string `json:"name"`
AvailableReplicas int32 `json:"availableReplicas"`
AchievedPercent int32 `json:"achievedPercent"`
SadPods []PodStatus `json:"sadPods,omitempty"`
Conditions []ClusterCapacityCondition `json:"conditions,omitempty"`
Reports []ClusterCapacityReport `json:"reports,omitempty"`
}

type ClusterConditionType string
Expand Down
135 changes: 135 additions & 0 deletions pkg/apis/shipper/v1alpha1/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,134 @@ func (in *ClusterCapacityCondition) DeepCopy() *ClusterCapacityCondition {
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReport) DeepCopyInto(out *ClusterCapacityReport) {
*out = *in
out.Owner = in.Owner
if in.Breakdown != nil {
in, out := &in.Breakdown, &out.Breakdown
*out = make([]ClusterCapacityReportBreakdown, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReport.
func (in *ClusterCapacityReport) DeepCopy() *ClusterCapacityReport {
if in == nil {
return nil
}
out := new(ClusterCapacityReport)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReportBreakdown) DeepCopyInto(out *ClusterCapacityReportBreakdown) {
*out = *in
if in.Containers != nil {
in, out := &in.Containers, &out.Containers
*out = make([]ClusterCapacityReportContainerBreakdown, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReportBreakdown.
func (in *ClusterCapacityReportBreakdown) DeepCopy() *ClusterCapacityReportBreakdown {
if in == nil {
return nil
}
out := new(ClusterCapacityReportBreakdown)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReportContainerBreakdown) DeepCopyInto(out *ClusterCapacityReportContainerBreakdown) {
*out = *in
if in.States != nil {
in, out := &in.States, &out.States
*out = make([]ClusterCapacityReportContainerStateBreakdown, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReportContainerBreakdown.
func (in *ClusterCapacityReportContainerBreakdown) DeepCopy() *ClusterCapacityReportContainerBreakdown {
if in == nil {
return nil
}
out := new(ClusterCapacityReportContainerBreakdown)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReportContainerBreakdownExample) DeepCopyInto(out *ClusterCapacityReportContainerBreakdownExample) {
*out = *in
if in.Message != nil {
in, out := &in.Message, &out.Message
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReportContainerBreakdownExample.
func (in *ClusterCapacityReportContainerBreakdownExample) DeepCopy() *ClusterCapacityReportContainerBreakdownExample {
if in == nil {
return nil
}
out := new(ClusterCapacityReportContainerBreakdownExample)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReportContainerStateBreakdown) DeepCopyInto(out *ClusterCapacityReportContainerStateBreakdown) {
*out = *in
in.Example.DeepCopyInto(&out.Example)
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReportContainerStateBreakdown.
func (in *ClusterCapacityReportContainerStateBreakdown) DeepCopy() *ClusterCapacityReportContainerStateBreakdown {
if in == nil {
return nil
}
out := new(ClusterCapacityReportContainerStateBreakdown)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityReportOwner) DeepCopyInto(out *ClusterCapacityReportOwner) {
*out = *in
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCapacityReportOwner.
func (in *ClusterCapacityReportOwner) DeepCopy() *ClusterCapacityReportOwner {
if in == nil {
return nil
}
out := new(ClusterCapacityReportOwner)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterCapacityStatus) DeepCopyInto(out *ClusterCapacityStatus) {
*out = *in
Expand All @@ -361,6 +489,13 @@ func (in *ClusterCapacityStatus) DeepCopyInto(out *ClusterCapacityStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Reports != nil {
in, out := &in.Reports, &out.Reports
*out = make([]ClusterCapacityReport, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

Expand Down
65 changes: 65 additions & 0 deletions pkg/controller/capacity/builder/container_breakdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package builder

import (
"sort"

shipper "github.com/bookingcom/shipper/pkg/apis/shipper/v1alpha1"
)

type ContainerStateBreakdown struct {
containerName string
states []*shipper.ClusterCapacityReportContainerStateBreakdown
}

func NewContainerBreakdown(containerName string) *ContainerStateBreakdown {
return &ContainerStateBreakdown{containerName: containerName}
}

func (c *ContainerStateBreakdown) AddOrIncrementState(
podExampleName string,
containerConditionType string,
containerConditionReason string,
containerExampleMessage string,
) *ContainerStateBreakdown {

var m *string
if len(containerExampleMessage) > 0 {
m = &containerExampleMessage
}

for _, s := range c.states {
if s.Type == containerConditionType && s.Reason == containerConditionReason {
s.Count += 1
return c
}
}

breakdown := shipper.ClusterCapacityReportContainerStateBreakdown{
Count: 1,
Type: containerConditionType,
Reason: containerConditionReason,
Example: shipper.ClusterCapacityReportContainerBreakdownExample{
Pod: podExampleName,
Message: m,
},
}
c.states = append(c.states, &breakdown)
return c
}

func (c *ContainerStateBreakdown) Build() shipper.ClusterCapacityReportContainerBreakdown {
stateCount := len(c.states)
orderedStates := make([]shipper.ClusterCapacityReportContainerStateBreakdown, stateCount)
for i, v := range c.states {
orderedStates[i] = *v
}

sort.Slice(orderedStates, func(i, j int) bool {
return orderedStates[i].Type < orderedStates[j].Type
})

return shipper.ClusterCapacityReportContainerBreakdown{
Name: c.containerName,
States: orderedStates,
}
}
90 changes: 90 additions & 0 deletions pkg/controller/capacity/builder/pod_condition_breakdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package builder

import (
"sort"

shipper "github.com/bookingcom/shipper/pkg/apis/shipper/v1alpha1"
)

type containerStateBreakdownBuilders map[string]*ContainerStateBreakdown

func (c containerStateBreakdownBuilders) Get(containerName string) *ContainerStateBreakdown {
var b *ContainerStateBreakdown
var ok bool
if b, ok = c[containerName]; !ok {
b = NewContainerBreakdown(containerName)
c[containerName] = b
}
return b
}

type PodConditionBreakdown struct {
podCount uint32
podConditionType string
podConditionStatus string
podConditionReason string

containerStateBreakdownBuilders containerStateBreakdownBuilders
}

func NewPodConditionBreakdown(
initialPodCount uint32,
podConditionType string,
podConditionStatus string,
podConditionReason string,
) *PodConditionBreakdown {
return &PodConditionBreakdown{
podCount: initialPodCount,
podConditionType: podConditionType,
podConditionStatus: podConditionStatus,
podConditionReason: podConditionReason,
containerStateBreakdownBuilders: make(containerStateBreakdownBuilders),
}
}

func PodConditionBreakdownKey(typ, status, reason string) string {
return typ + status + reason
}

func (p *PodConditionBreakdown) Key() string {
return PodConditionBreakdownKey(p.podConditionType, p.podConditionStatus, p.podConditionReason)
}

func (p *PodConditionBreakdown) AddOrIncrementContainerState(
containerName string,
podExampleName string,
containerConditionType string,
containerConditionReason string,
containerExampleMessage string,
) *PodConditionBreakdown {
p.containerStateBreakdownBuilders.
Get(containerName).
AddOrIncrementState(podExampleName, containerConditionType, containerConditionReason, containerExampleMessage)
return p
}

func (p *PodConditionBreakdown) IncrementCount() *PodConditionBreakdown {
p.podCount += 1
return p
}

func (p *PodConditionBreakdown) Build() shipper.ClusterCapacityReportBreakdown {

orderedContainers := make([]shipper.ClusterCapacityReportContainerBreakdown, 0)

for _, v := range p.containerStateBreakdownBuilders {
orderedContainers = append(orderedContainers, v.Build())
}

sort.Slice(orderedContainers, func(i, j int) bool {
return orderedContainers[i].Name < orderedContainers[j].Name
})

return shipper.ClusterCapacityReportBreakdown{
Type: p.podConditionType,
Status: p.podConditionStatus,
Count: p.podCount,
Reason: p.podConditionReason,
Containers: orderedContainers,
}
}
Loading

0 comments on commit 5a8ddb1

Please sign in to comment.