Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 6 additions & 42 deletions src/app/backend/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package main
import (
"log"

api "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields"
Expand Down Expand Up @@ -142,54 +142,18 @@ func GetReplicationControllerPodsEvents(client *client.Client, namespace, replic
return nil, err
}

events, err := GetPodsEvents(client, pods)

if err != nil {
return nil, err
}

return events, nil
}

// GetPodsEvents gets events associated to given list of pods
// TODO(floreks): refactor this to make single API call instead of N api calls
func GetPodsEvents(client *client.Client, pods *api.PodList) ([]api.Event, error) {
events := make([]api.Event, 0, 0)

for _, pod := range pods.Items {
list, err := GetPodEvents(client, pod)

if err != nil {
return nil, err
}

for _, event := range list.Items {
events = append(events, event)
}

}

return events, nil
}

// GetPodEvents gets events associated to given pod
func GetPodEvents(client client.Interface, pod api.Pod) (*api.EventList, error) {
fieldSelector, err := fields.ParseSelector("involvedObject.name=" + pod.Name)

if err != nil {
return nil, err
}

list, err := client.Events(pod.Namespace).List(api.ListOptions{
eventList, err := client.Events(namespace).List(api.ListOptions{
LabelSelector: labels.Everything(),
FieldSelector: fieldSelector,
FieldSelector: fields.Everything(),
})

if err != nil {
return nil, err
}

return list, nil
events := filterEventsByPodsUID(eventList.Items, pods.Items)

return events, nil
}

// AppendEvents appends events from source slice to target events representation.
Expand Down
78 changes: 51 additions & 27 deletions src/app/backend/eventscommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ package main

import (
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"log"
"k8s.io/kubernetes/pkg/types"
"strings"
)

Expand All @@ -30,48 +29,73 @@ import (
var FailedReasonPartials = []string{"failed", "err", "exceeded", "invalid", "unhealthy",
"mismatch", "insufficient", "conflict", "outof", "nil"}

// GetPodsEventWarnings returns warning pod events based on given list of pods.
// GetPodsEventWarnings returns warning pod events by filtering out events targeting only given pods
// TODO(floreks) : Import and use Set instead of custom function to get rid of duplicates
func GetPodsEventWarnings(client client.Interface, pods []api.Pod) (result []Event, err error) {
func GetPodsEventWarnings(eventList *api.EventList, pods []api.Pod) []Event {
result := make([]Event, 0)
if eventList == nil {
return result
}

// Filter out only warning events
events := getWarningEvents(eventList)
failedPods := make([]api.Pod, 0)

// Filter out only 'failed' pods
for _, pod := range pods {
if !isRunningOrSucceeded(pod) {
log.Printf("Getting warning events from pod: %s", pod.Name)
events, err := GetPodEvents(client, pod)
failedPods = append(failedPods, pod)
}
}

if err != nil {
return nil, err
}
// Filter events by failed pods UID
events = filterEventsByPodsUID(events, failedPods)
events = removeDuplicates(events)

result = getPodsEventWarnings(events)
}
for _, event := range events {
result = append(result, Event{
Message: event.Message,
Reason: event.Reason,
Type: event.Type,
})
}

return removeDuplicates(result), nil
return result
}

// Returns list of Pod Event model objects based on kubernetes API event list object
// Event list object is filtered to get only warning events.
func getPodsEventWarnings(eventList *api.EventList) []Event {
result := make([]Event, 0)
// Returns filtered list of event objects.
// Events list is filtered to get only events targeting pods on the list.
func filterEventsByPodsUID(events []api.Event, pods []api.Pod) []api.Event {
result := make([]api.Event, 0)
podEventMap := make(map[types.UID]bool, 0)

var events []api.Event
if !isTypeFilled(eventList.Items) {
eventList.Items = fillEventsType(eventList.Items)
if len(pods) == 0 || len(events) == 0 {
return result
}

events = filterEventsByType(eventList.Items, api.EventTypeWarning)
for _, pod := range pods {
podEventMap[pod.UID] = true
}

for _, event := range events {
result = append(result, Event{
Message: event.Message,
Reason: event.Reason,
Type: event.Type,
})
if _, exists := podEventMap[event.InvolvedObject.UID]; exists {
result = append(result, event)
}
}

return result
}

// Returns filtered list of event objects.
// Event list object is filtered to get only warning events.
func getWarningEvents(eventList *api.EventList) []api.Event {
if !isTypeFilled(eventList.Items) {
eventList.Items = fillEventsType(eventList.Items)
}

return filterEventsByType(eventList.Items, api.EventTypeWarning)
}

// Filters kubernetes API event objects based on event type.
// Empty string will return all events.
func filterEventsByType(events []api.Event, eventType string) []api.Event {
Expand Down Expand Up @@ -131,9 +155,9 @@ func fillEventsType(events []api.Event) []api.Event {
}

// Removes duplicate strings from the slice
func removeDuplicates(slice []Event) []Event {
func removeDuplicates(slice []api.Event) []api.Event {
visited := make(map[string]bool, 0)
result := make([]Event, 0)
result := make([]api.Event, 0)

for _, elem := range slice {
if !visited[elem.Reason] {
Expand Down
27 changes: 13 additions & 14 deletions src/app/backend/replicationcontrollerlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
)

// GetPodsEventWarningsFunc is a callback function used to get the pod status errors.
type GetPodsEventWarningsFunc func(pods []api.Pod) ([]Event, error)
type GetPodsEventWarningsFunc func(pods []api.Pod) []Event

// GetNodeFunc is a callback function used to get nodes by names.
type GetNodeFunc func(nodeName string) (*api.Node, error)
Expand Down Expand Up @@ -94,17 +94,20 @@ func GetReplicationControllerList(client *client.Client) (*ReplicationController
return nil, err
}

eventsList, err := client.Events(api.NamespaceAll).List(api.ListOptions{
LabelSelector: labels.Everything(),
FieldSelector: fields.Everything(),
})

if err != nil {
return nil, err
}

// Anonymous callback function to get pods warnings.
// Function fulfils GetPodsEventWarningsFunc type contract.
// Based on list of api pods returns list of pod related warning events
getPodsEventWarningsFn := func(pods []api.Pod) ([]Event, error) {
errors, err := GetPodsEventWarnings(client, pods)

if err != nil {
return nil, err
}

return errors, nil
getPodsEventWarningsFn := func(pods []api.Pod) []Event {
return GetPodsEventWarnings(eventsList, pods)
}

// Anonymous callback function to get nodes by their names.
Expand Down Expand Up @@ -155,11 +158,7 @@ func getReplicationControllerList(replicationControllers []api.ReplicationContro
}
}
podInfo := getReplicationControllerPodInfo(&replicationController, matchingPods)
podErrors, err := getPodsEventWarningsFn(matchingPods)

if err != nil {
return nil, err
}
podErrors := getPodsEventWarningsFn(matchingPods)

podInfo.Warnings = podErrors

Expand Down
Loading