Files
fission-src/pkg/utils/informer.go
T

153 lines
5.6 KiB
Go

package utils
import (
"context"
"fmt"
"time"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/watch"
k8sInformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
metricsapi "k8s.io/metrics/pkg/apis/metrics"
fv1 "github.com/fission/fission/pkg/apis/core/v1"
"github.com/fission/fission/pkg/generated/clientset/versioned"
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
)
func GetInformersForNamespaces(client versioned.Interface, defaultSync time.Duration, kind string) map[string]cache.SharedIndexInformer {
informers := make(map[string]cache.SharedIndexInformer)
for _, ns := range DefaultNSResolver().Snapshot() {
factory := genInformer.NewFilteredSharedInformerFactory(client, defaultSync, ns, nil).Core().V1()
switch kind {
case fv1.CanaryConfigResource:
informers[ns] = factory.CanaryConfigs().Informer()
case fv1.EnvironmentResource:
informers[ns] = factory.Environments().Informer()
case fv1.FunctionResource:
informers[ns] = factory.Functions().Informer()
case fv1.HttpTriggerResource:
informers[ns] = factory.HTTPTriggers().Informer()
case fv1.KubernetesWatchResource:
informers[ns] = factory.KubernetesWatchTriggers().Informer()
case fv1.MessageQueueResource:
informers[ns] = factory.MessageQueueTriggers().Informer()
case fv1.PackagesResource:
informers[ns] = factory.Packages().Informer()
case fv1.TimeTriggerResource:
informers[ns] = factory.TimeTriggers().Informer()
default:
panic("Unknown kind: " + kind)
}
}
return informers
}
func GetK8sInformersForNamespaces(client kubernetes.Interface, defaultSync time.Duration, kind string) map[string]cache.SharedIndexInformer {
informers := make(map[string]cache.SharedIndexInformer)
namespaces := DefaultNSResolver()
for _, ns := range namespaces.SnapshotWithOptions(WithBuilderNs(), WithFunctionNs(), WithDefaultNs()) {
factory := k8sInformers.NewSharedInformerFactoryWithOptions(client, defaultSync, k8sInformers.WithNamespace(ns))
switch kind {
case fv1.Deployments:
informers[ns] = factory.Apps().V1().Deployments().Informer()
case fv1.ReplicaSets:
informers[ns] = factory.Apps().V1().ReplicaSets().Informer()
case fv1.Pods:
informers[ns] = factory.Core().V1().Pods().Informer()
case fv1.Services:
informers[ns] = factory.Core().V1().Services().Informer()
case fv1.ConfigMaps:
informers[ns] = factory.Core().V1().ConfigMaps().Informer()
case fv1.Secrets:
informers[ns] = factory.Core().V1().Secrets().Informer()
default:
panic("Unknown kind: " + kind)
}
}
return informers
}
func GetInformerEventChecker(ctx context.Context, client kubernetes.Interface, reason string) map[string]cache.SharedInformer {
informers := make(map[string]cache.SharedInformer)
namespaces := DefaultNSResolver()
for _, ns := range namespaces.SnapshotWithOptions(WithBuilderNs(), WithFunctionNs(), WithDefaultNs()) {
informers[ns] = cache.NewSharedInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
options.FieldSelector = fmt.Sprintf("involvedObject.kind=Pod,type=Normal,reason=%s", reason)
return client.CoreV1().Events(ns).List(ctx, options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
options.FieldSelector = fmt.Sprintf("involvedObject.kind=Pod,type=Normal,reason=%s", reason)
return client.CoreV1().Events(ns).Watch(ctx, options)
},
},
&apiv1.Event{},
0,
)
}
return informers
}
func GetInformerFactoryByExecutor(client kubernetes.Interface, labels labels.Selector, defaultResync time.Duration) map[string]k8sInformers.SharedInformerFactory {
informerFactory := make(map[string]k8sInformers.SharedInformerFactory)
namespaces := DefaultNSResolver()
for _, ns := range namespaces.SnapshotWithOptions(WithBuilderNs(), WithFunctionNs(), WithDefaultNs()) {
factory := k8sInformers.NewSharedInformerFactoryWithOptions(client, defaultResync,
k8sInformers.WithTweakListOptions(func(options *metav1.ListOptions) {
options.LabelSelector = labels.String()
}),
k8sInformers.WithNamespace(ns))
informerFactory[ns] = factory
}
return informerFactory
}
func GetInformerFactoryByReadyPod(client kubernetes.Interface, namespace string, labelSelector *metav1.LabelSelector) (k8sInformers.SharedInformerFactory, error) {
informerFactory := k8sInformers.NewSharedInformerFactoryWithOptions(client, 0,
k8sInformers.WithNamespace(namespace),
k8sInformers.WithTweakListOptions(func(options *metav1.ListOptions) {
options.LabelSelector = labels.Set(labelSelector.MatchLabels).AsSelector().String()
options.FieldSelector = "status.phase=Running"
}))
return informerFactory, nil
}
func GetInformerLabelByExecutor(executorType fv1.ExecutorType) (labels.Selector, error) {
executorLabel, err := labels.NewRequirement(fv1.EXECUTOR_TYPE, selection.DoubleEquals, []string{string(executorType)})
if err != nil {
return nil, err
}
labelSelector := labels.NewSelector()
labelSelector.Add(*executorLabel)
return labelSelector, nil
}
func SupportedMetricsAPIVersionAvailable(discoveredAPIGroups *metav1.APIGroupList) bool {
var supportedMetricsAPIVersions = []string{
"v1beta1",
}
for _, discoveredAPIGroup := range discoveredAPIGroups.Groups {
if discoveredAPIGroup.Name != metricsapi.GroupName {
continue
}
for _, version := range discoveredAPIGroup.Versions {
for _, supportedVersion := range supportedMetricsAPIVersions {
if version.Version == supportedVersion {
return true
}
}
}
}
return false
}