package cli import ( "context" models "github.com/portainer/portainer/api/http/models/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // GetEvents gets all the Events for a given namespace and resource // If the user is a kube admin, it returns all events in the namespace // Otherwise, it returns only the events in the non-admin namespaces func (kcl *KubeClient) GetEvents(namespace string, resourceId string) ([]models.K8sEvent, error) { if kcl.IsKubeAdmin { return kcl.fetchAllEvents(namespace, resourceId) } return kcl.fetchEventsForNonAdmin(namespace, resourceId) } // fetchEventsForNonAdmin returns all events in the given namespace and resource // It returns only the events in the non-admin namespaces func (kcl *KubeClient) fetchEventsForNonAdmin(namespace string, resourceId string) ([]models.K8sEvent, error) { if len(kcl.NonAdminNamespaces) == 0 { return nil, nil } events, err := kcl.fetchAllEvents(namespace, resourceId) if err != nil { return nil, err } nonAdminNamespaceSet := kcl.buildNonAdminNamespacesMap() results := make([]models.K8sEvent, 0) for _, event := range events { if _, ok := nonAdminNamespaceSet[event.Namespace]; ok { results = append(results, event) } } return results, nil } // fetchEventsForNonAdmin returns all events in the given namespace and resource // It returns all events in the namespace and resource func (kcl *KubeClient) fetchAllEvents(namespace string, resourceId string) ([]models.K8sEvent, error) { options := metav1.ListOptions{} if resourceId != "" { options.FieldSelector = "involvedObject.uid=" + resourceId } list, err := kcl.cli.CoreV1().Events(namespace).List(context.TODO(), options) if err != nil { return nil, err } results := make([]models.K8sEvent, 0) for _, event := range list.Items { results = append(results, parseEvent(&event)) } return results, nil } func parseEvent(event *corev1.Event) models.K8sEvent { result := models.K8sEvent{ Type: event.Type, Name: event.Name, Message: event.Message, Reason: event.Reason, Namespace: event.Namespace, EventTime: event.EventTime.UTC(), Kind: event.Kind, Count: event.Count, UID: string(event.ObjectMeta.GetUID()), InvolvedObjectKind: models.K8sEventInvolvedObject{ Kind: event.InvolvedObject.Kind, UID: string(event.InvolvedObject.UID), Name: event.InvolvedObject.Name, Namespace: event.InvolvedObject.Namespace, }, } if !event.LastTimestamp.Time.IsZero() { result.LastTimestamp = &event.LastTimestamp.Time } if !event.FirstTimestamp.Time.IsZero() { result.FirstTimestamp = &event.FirstTimestamp.Time } return result }