func getListWatch(kind string, getter cache.Getter, selector labels.Selector) *cache.ListWatch { return &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { logger.Debugf("Running ListFunc for %q", kind) req := getter.Get().Namespace(api.NamespaceAll).Resource(kind). LabelsSelectorParam(selector).FieldsSelectorParam(fields.Everything()) logger.Debugf("Request URL: %v", req.URL()) obj, er := req.Do().Get() if er != nil { logger.Debugf("Got error: %v", er) } return obj, er }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { logger.Debugf("Running WatchFunc for %q", kind) req := getter.Get().Prefix("watch").Namespace(api.NamespaceAll).Resource(kind). LabelsSelectorParam(selector).FieldsSelectorParam(fields.Everything()). Param("resourceVersion", options.ResourceVersion) logger.Debugf("Request URL: %v", req.URL()) w, er := req.Watch() if er != nil { logger.Debugf("Got error: %v", er) } else { logger.Debugf("Set watch for %q", kind) } return w, er }, } }
// GetReplicationControllerPodsEvents gets events associated to pods in replication controller. func GetReplicationControllerPodsEvents(client *client.Client, namespace, replicationControllerName string) ([]api.Event, error) { replicationController, err := client.ReplicationControllers(namespace).Get(replicationControllerName) if err != nil { return nil, err } pods, err := client.Pods(namespace).List(api.ListOptions{ LabelSelector: labels.SelectorFromSet(replicationController.Spec.Selector), FieldSelector: fields.Everything(), }) if err != nil { return nil, err } eventList, err := client.Events(namespace).List(api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything(), }) if err != nil { return nil, err } events := filterEventsByPodsUID(eventList.Items, pods.Items) return events, nil }
// NewClient returns a usable Client. Don't forget to Stop it. func NewClient(addr string, resyncPeriod time.Duration) (Client, error) { c, err := unversioned.New(&unversioned.Config{Host: addr}) if err != nil { return nil, err } podListWatch := cache.NewListWatchFromClient(c, "pods", api.NamespaceAll, fields.Everything()) podStore := cache.NewStore(cache.MetaNamespaceKeyFunc) podReflector := cache.NewReflector(podListWatch, &api.Pod{}, podStore, resyncPeriod) serviceListWatch := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) serviceStore := cache.NewStore(cache.MetaNamespaceKeyFunc) serviceReflector := cache.NewReflector(serviceListWatch, &api.Service{}, serviceStore, resyncPeriod) quit := make(chan struct{}) podReflector.RunUntil(quit) serviceReflector.RunUntil(quit) return &client{ quit: quit, client: c, podReflector: podReflector, podStore: &cache.StoreToPodLister{Store: podStore}, serviceReflector: serviceReflector, serviceStore: &cache.StoreToServiceLister{Store: serviceStore}, }, nil }
// NewNamespaceController creates a new NamespaceController func NewNamespaceController(kubeClient client.Interface, resyncPeriod time.Duration) *NamespaceController { _, controller := framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return kubeClient.Namespaces().List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return kubeClient.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion) }, }, &api.Namespace{}, resyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { namespace := obj.(*api.Namespace) err := syncNamespace(kubeClient, *namespace) if err != nil { glog.Error(err) } }, UpdateFunc: func(oldObj, newObj interface{}) { namespace := newObj.(*api.Namespace) err := syncNamespace(kubeClient, *namespace) if err != nil { glog.Error(err) } }, }, ) return &NamespaceController{ controller: controller, } }
// Based on given selector returns list of services that are candidates for deletion. // Services are matched by replication controllers' label selector. They are deleted if given // label selector is targeting only 1 replication controller. func getServicesForDeletion(client client.Interface, labelSelector labels.Selector, namespace string) ([]api.Service, error) { replicationControllers, err := client.Core().ReplicationControllers(namespace).List(api.ListOptions{ LabelSelector: labelSelector, FieldSelector: fields.Everything(), }) if err != nil { return nil, err } // if label selector is targeting only 1 replication controller // then we can delete services targeted by this label selector, // otherwise we can not delete any services so just return empty list if len(replicationControllers.Items) != 1 { return []api.Service{}, nil } services, err := client.Core().Services(namespace).List(api.ListOptions{ LabelSelector: labelSelector, FieldSelector: fields.Everything(), }) if err != nil { return nil, err } return services.Items, nil }
// NewSourceAPIserver creates config source that watches for changes to the services and endpoints. func NewSourceAPI(c *client.Client, period time.Duration, servicesChan chan<- ServiceUpdate, endpointsChan chan<- EndpointsUpdate) { servicesLW := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) endpointsLW := cache.NewListWatchFromClient(c, "endpoints", api.NamespaceAll, fields.Everything()) newServicesSourceApiFromLW(servicesLW, period, servicesChan) newEndpointsSourceApiFromLW(endpointsLW, period, endpointsChan) }
func newWatcher(kr *kregistry) (registry.Watcher, error) { svi := kr.client.Services(api.NamespaceAll) services, err := svi.List(labels.Everything(), fields.Everything()) if err != nil { return nil, err } watch, err := svi.Watch(labels.Everything(), fields.Everything(), services.ResourceVersion) if err != nil { return nil, err } w := &watcher{ registry: kr, watcher: watch, } go func() { for event := range watch.ResultChan() { w.update(event) } }() return w, nil }
func NewReadOnlyClusterPolicyBindingCache(registry clusterbindingregistry.WatchingRegistry) *readOnlyClusterPolicyBindingCache { ctx := kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceAll) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}) reflector := cache.NewReflector( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return registry.ListClusterPolicyBindings(ctx, labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return registry.WatchClusterPolicyBindings(ctx, labels.Everything(), fields.Everything(), resourceVersion) }, }, &authorizationapi.ClusterPolicyBinding{}, indexer, 2*time.Minute, ) return &readOnlyClusterPolicyBindingCache{ registry: registry, indexer: indexer, reflector: reflector, keyFunc: cache.MetaNamespaceKeyFunc, } }
// NewSourceAPI creates config source that watches for changes to the services and endpoints. func NewSourceAPI(c cache.Getter, period time.Duration, servicesChan chan<- ServiceUpdate, endpointsChan chan<- EndpointsUpdate) { servicesLW := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) cache.NewReflector(servicesLW, &api.Service{}, NewServiceStore(nil, servicesChan), period).Run() endpointsLW := cache.NewListWatchFromClient(c, "endpoints", api.NamespaceAll, fields.Everything()) cache.NewReflector(endpointsLW, &api.Endpoints{}, NewEndpointsStore(nil, endpointsChan), period).Run() }
// In order to process services deleted while controller is down, fill the queue on startup func (e *NetworkController) startUp() { svcList, err := e.client.Services(api.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { glog.Errorf("Unable to list services: %v", err) return } for _, svc := range svcList.Items { if svc.Spec.Type == api.ServiceTypeNetworkProvider { key, err := keyFunc(svc) if err != nil { glog.Errorf("Unable to get key for svc %s", svc.Name) continue } e.queue.Add(key) } } endpointList, err := e.client.Endpoints(api.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { glog.Errorf("Unable to list endpoints: %v", err) return } for _, ep := range endpointList.Items { e.addEndpoint(&ep) } }
func NewImportController(isNamespacer client.ImageStreamsNamespacer, ismNamespacer client.ImageStreamMappingsNamespacer, parallelImports int, resyncInterval time.Duration) *ImportController { c := &ImportController{ streams: isNamespacer, mappings: ismNamespacer, numParallelImports: parallelImports, work: make(chan *api.ImageStream, 20*parallelImports), workingSet: sets.String{}, } _, c.imageStreamController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return c.streams.ImageStreams(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return c.streams.ImageStreams(kapi.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) }, }, &api.ImageStream{}, resyncInterval, framework.ResourceEventHandlerFuncs{ AddFunc: c.imageStreamAdded, UpdateFunc: c.imageStreamUpdated, }, ) return c }
func NewJobController(kubeClient client.Interface) *JobController { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartRecordingToSink(kubeClient.Events("")) jm := &JobController{ kubeClient: kubeClient, podControl: controller.RealPodControl{ KubeClient: kubeClient, Recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "job"}), }, expectations: controller.NewControllerExpectations(), queue: workqueue.New(), } jm.jobStore.Store, jm.jobController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return jm.kubeClient.Experimental().Jobs(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return jm.kubeClient.Experimental().Jobs(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, &experimental.Job{}, replicationcontroller.FullControllerResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: jm.enqueueController, UpdateFunc: func(old, cur interface{}) { if job := cur.(*experimental.Job); !isJobFinished(job) { jm.enqueueController(job) } }, DeleteFunc: jm.enqueueController, }, ) jm.podStore.Store, jm.podController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return jm.kubeClient.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return jm.kubeClient.Pods(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, &api.Pod{}, replicationcontroller.PodRelistPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: jm.addPod, UpdateFunc: jm.updatePod, DeleteFunc: jm.deletePod, }, ) jm.updateHandler = jm.updateJobStatus jm.syncHandler = jm.syncJob jm.podStoreSynced = jm.podController.HasSynced return jm }
func checkExistingRCRecovers(f *Framework) { By("assert that the pre-existing replication controller recovers") podClient := f.Client.Pods(f.Namespace.Name) rcSelector := labels.Set{"name": "baz"}.AsSelector() By("deleting pods from existing replication controller") expectNoError(wait.Poll(time.Millisecond*500, time.Second*60, func() (bool, error) { pods, err := podClient.List(rcSelector, fields.Everything()) if err != nil { Logf("apiserver returned error, as expected before recovery: %v", err) return false, nil } if len(pods.Items) == 0 { return false, nil } for _, pod := range pods.Items { err = podClient.Delete(pod.Name, api.NewDeleteOptions(0)) Expect(err).NotTo(HaveOccurred()) } Logf("apiserver has recovered") return true, nil })) By("waiting for replication controller to recover") expectNoError(wait.Poll(time.Millisecond*500, time.Second*60, func() (bool, error) { pods, err := podClient.List(rcSelector, fields.Everything()) Expect(err).NotTo(HaveOccurred()) for _, pod := range pods.Items { if pod.DeletionTimestamp == nil && api.IsPodReady(&pod) { return true, nil } } return false, nil })) }
// newIPVSController creates a new controller from the given config. func newIPVSController(kubeClient *unversioned.Client, namespace string, useUnicast bool, password string) *ipvsControllerController { ipvsc := ipvsControllerController{ client: kubeClient, queue: workqueue.New(), reloadRateLimiter: util.NewTokenBucketRateLimiter(reloadQPS, int(reloadQPS)), reloadLock: &sync.Mutex{}, } clusterNodes := getClusterNodesIP(kubeClient) nodeInfo, err := getNodeInfo(clusterNodes) if err != nil { glog.Fatalf("Error getting local IP from nodes in the cluster: %v", err) } neighbors := getNodeNeighbors(nodeInfo, clusterNodes) ipvsc.keepalived = &keepalived{ iface: nodeInfo.iface, ip: nodeInfo.ip, netmask: nodeInfo.netmask, nodes: clusterNodes, neighbors: neighbors, priority: getNodePriority(nodeInfo.ip, clusterNodes), useUnicast: useUnicast, password: password, } enqueue := func(obj interface{}) { key, err := keyFunc(obj) if err != nil { glog.Infof("Couldn't get key for object %+v: %v", obj, err) return } ipvsc.queue.Add(key) } eventHandlers := framework.ResourceEventHandlerFuncs{ AddFunc: enqueue, DeleteFunc: enqueue, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { enqueue(cur) } }, } ipvsc.svcLister.Store, ipvsc.svcController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) ipvsc.epLister.Store, ipvsc.epController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &ipvsc }
func RunProjectCache(c client.Interface, defaultNodeSelector string) { if pcache != nil { return } store := cache.NewStore(cache.MetaNamespaceKeyFunc) reflector := cache.NewReflector( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return c.Namespaces().List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return c.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion) }, }, &kapi.Namespace{}, store, 0, ) reflector.Run() pcache = &ProjectCache{ Client: c, Store: store, DefaultNodeSelector: defaultNodeSelector, } }
// NewNamespaceController creates a new NamespaceController func NewNamespaceController(kubeClient client.Interface, experimentalMode bool, resyncPeriod time.Duration) *NamespaceController { var controller *framework.Controller _, controller = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return kubeClient.Namespaces().List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return kubeClient.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion) }, }, &api.Namespace{}, resyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { namespace := obj.(*api.Namespace) if err := syncNamespace(kubeClient, experimentalMode, *namespace); err != nil { if estimate, ok := err.(*contentRemainingError); ok { go func() { // Estimate is the aggregate total of TerminationGracePeriodSeconds, which defaults to 30s // for pods. However, most processes will terminate faster - within a few seconds, probably // with a peak within 5-10s. So this division is a heuristic that avoids waiting the full // duration when in many cases things complete more quickly. The extra second added is to // ensure we never wait 0 seconds. t := estimate.Estimate/2 + 1 glog.V(4).Infof("Content remaining in namespace %s, waiting %d seconds", namespace.Name, t) time.Sleep(time.Duration(t) * time.Second) if err := controller.Requeue(namespace); err != nil { util.HandleError(err) } }() return } util.HandleError(err) } }, UpdateFunc: func(oldObj, newObj interface{}) { namespace := newObj.(*api.Namespace) if err := syncNamespace(kubeClient, experimentalMode, *namespace); err != nil { if estimate, ok := err.(*contentRemainingError); ok { go func() { t := estimate.Estimate/2 + 1 glog.V(4).Infof("Content remaining in namespace %s, waiting %d seconds", namespace.Name, t) time.Sleep(time.Duration(t) * time.Second) if err := controller.Requeue(namespace); err != nil { util.HandleError(err) } }() return } util.HandleError(err) } }, }, ) return &NamespaceController{ controller: controller, } }
// Based on given selector returns list of services that are candidates for deletion. // Services are matched by daemon sets' label selector. They are deleted if given // label selector is targeting only 1 daemon set. func GetServicesForDSDeletion(client client.Interface, labelSelector labels.Selector, namespace string) ([]api.Service, error) { daemonSet, err := client.Extensions().DaemonSets(namespace).List(api.ListOptions{ LabelSelector: labelSelector, FieldSelector: fields.Everything(), }) if err != nil { return nil, err } // if label selector is targeting only 1 daemon set // then we can delete services targeted by this label selector, // otherwise we can not delete any services so just return empty list if len(daemonSet.Items) != 1 { return []api.Service{}, nil } services, err := client.Core().Services(namespace).List(api.ListOptions{ LabelSelector: labelSelector, FieldSelector: fields.Everything(), }) if err != nil { return nil, err } return services.Items, nil }
func TestNewClient(t *testing.T) { o := NewObjects(api.Scheme, api.Scheme) if err := AddObjectsFromPath("../../../../examples/guestbook/frontend-service.yaml", o, api.Scheme); err != nil { t.Fatal(err) } client := &Fake{} client.AddReactor("*", "*", ObjectReaction(o, testapi.Default.RESTMapper())) list, err := client.Services("test").List(labels.Everything(), fields.Everything(), unversioned.ListOptions{}) if err != nil { t.Fatal(err) } if len(list.Items) != 1 { t.Fatalf("unexpected list %#v", list) } // When list is invoked a second time, the same results are returned. list, err = client.Services("test").List(labels.Everything(), fields.Everything(), unversioned.ListOptions{}) if err != nil { t.Fatal(err) } if len(list.Items) != 1 { t.Fatalf("unexpected list %#v", list) } t.Logf("list: %#v", list) }
func (oi *OsdnRegistryInterface) WatchNamespaces(receiver chan *osdnapi.NamespaceEvent, stop chan bool) error { nsEventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) listWatch := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return oi.kClient.Namespaces().List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return oi.kClient.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion) }, } cache.NewReflector(listWatch, &kapi.Namespace{}, nsEventQueue, 4*time.Minute).Run() for { eventType, obj, err := nsEventQueue.Pop() if err != nil { return err } switch eventType { case watch.Added: // we should ignore the modified event because status updates cause unnecessary noise // the only time we would care about modified would be if the node changes its IP address // and hence all nodes need to update their vtep entries for the respective subnet // create nodeEvent ns := obj.(*kapi.Namespace) receiver <- &osdnapi.NamespaceEvent{Type: osdnapi.Added, Name: ns.ObjectMeta.Name} case watch.Deleted: // TODO: There is a chance that a Delete event will not get triggered. // Need to use a periodic sync loop that lists and compares. ns := obj.(*kapi.Namespace) receiver <- &osdnapi.NamespaceEvent{Type: osdnapi.Deleted, Name: ns.ObjectMeta.Name} } } }
func NewKubeletProvider(uri *url.URL) (MetricsSourceProvider, error) { // create clients kubeConfig, kubeletConfig, err := GetKubeConfigs(uri) if err != nil { return nil, err } kubeClient := kube_client.NewOrDie(kubeConfig) kubeletClient, err := NewKubeletClient(kubeletConfig) if err != nil { return nil, err } // Get nodes to test if the client is configured well. Watch gives less error information. if _, err := kubeClient.Nodes().List(kube_api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything()}); err != nil { glog.Errorf("Failed to load nodes: %v", err) } // watch nodes lw := cache.NewListWatchFromClient(kubeClient, "nodes", kube_api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(lw, &kube_api.Node{}, nodeLister.Store, time.Hour) reflector.Run() return &kubeletProvider{ nodeLister: nodeLister, reflector: reflector, kubeletClient: kubeletClient, }, nil }
// Create creates an ImportController. func (f *ImportControllerFactory) Create() controller.RunnableController { lw := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return f.Client.ImageStreams(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return f.Client.ImageStreams(kapi.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) }, } q := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(lw, &api.ImageStream{}, q, 2*time.Minute).Run() c := &ImportController{ streams: f.Client, mappings: f.Client, } return &controller.RetryController{ Queue: q, RetryManager: controller.NewQueueRetryManager( q, cache.MetaNamespaceKeyFunc, func(obj interface{}, err error, retries controller.Retry) bool { util.HandleError(err) return retries.Count < 5 }, kutil.NewTokenBucketRateLimiter(1, 10), ), Handle: func(obj interface{}) error { r := obj.(*api.ImageStream) return c.Next(r) }, } }
// NewDockercfgController returns a new *DockercfgController. func NewDockercfgController(cl client.Interface, options DockercfgControllerOptions) *DockercfgController { e := &DockercfgController{ client: cl, } _, e.serviceAccountController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return e.client.ServiceAccounts(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return e.client.ServiceAccounts(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, &api.ServiceAccount{}, options.Resync, framework.ResourceEventHandlerFuncs{ AddFunc: e.serviceAccountAdded, UpdateFunc: e.serviceAccountUpdated, }, ) e.dockerURL = options.DefaultDockerURL return e }
// newLoadBalancerController creates a new controller from the given config. func newLoadBalancerController(cfg *loadBalancerConfig, kubeClient *unversioned.Client, namespace string) *loadBalancerController { lbc := loadBalancerController{ cfg: cfg, client: kubeClient, queue: workqueue.New(), reloadRateLimiter: util.NewTokenBucketRateLimiter( reloadQPS, int(reloadQPS)), targetService: *targetService, forwardServices: *forwardServices, httpPort: *httpPort, tcpServices: map[string]int{}, } for _, service := range strings.Split(*tcpServices, ",") { portSplit := strings.Split(service, ":") if len(portSplit) != 2 { glog.Errorf("Ignoring misconfigured TCP service %v", service) continue } if port, err := strconv.Atoi(portSplit[1]); err != nil { glog.Errorf("Ignoring misconfigured TCP service %v: %v", service, err) continue } else { lbc.tcpServices[portSplit[0]] = port } } enqueue := func(obj interface{}) { key, err := keyFunc(obj) if err != nil { glog.Infof("Couldn't get key for object %+v: %v", obj, err) return } lbc.queue.Add(key) } eventHandlers := framework.ResourceEventHandlerFuncs{ AddFunc: enqueue, DeleteFunc: enqueue, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { enqueue(cur) } }, } lbc.svcLister.Store, lbc.svcController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) lbc.epLister.Store, lbc.epController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &lbc }
func (a *HorizontalPodAutoscalerController) reconcileAutoscalers() error { ns := api.NamespaceAll list, err := a.expClient.HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) if err != nil { return fmt.Errorf("error listing nodes: %v", err) } for _, hpa := range list.Items { reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Namespace, hpa.Spec.ScaleRef.Name) scale, err := a.expClient.Scales(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name) if err != nil { glog.Warningf("Failed to query scale subresource for %s: %v", reference, err) continue } podList, err := a.client.Pods(hpa.Spec.ScaleRef.Namespace). List(labels.SelectorFromSet(labels.Set(scale.Status.Selector)), fields.Everything()) if err != nil { glog.Warningf("Failed to get pod list for %s: %v", reference, err) continue } podNames := []string{} for _, pod := range podList.Items { podNames = append(podNames, pod.Name) } metric, metricDefined := resourceToMetric[hpa.Spec.Target.Resource] if !metricDefined { glog.Warningf("Heapster metric not defined for %s %v", reference, hpa.Spec.Target.Resource) continue } startTime := time.Now().Add(heapsterQueryStart) metricPath := fmt.Sprintf("/api/v1/model/namespaces/%s/pod-list/%s/metrics/%s", hpa.Spec.ScaleRef.Namespace, strings.Join(podNames, ","), metric) resultRaw, err := a.client. Get(). Prefix("proxy"). Resource("services"). Namespace(heapsterNamespace). Name(heapsterService). Suffix(metricPath). Param("start", startTime.Format(time.RFC3339)). Do(). Raw() if err != nil { glog.Warningf("Failed to get pods metrics for %s: %v", reference, err) continue } glog.Infof("Metrics available for %s: %s", reference, string(resultRaw)) } return nil }
// GetReplicationControllerList returns a list of all Replication Controllers in the cluster. func GetReplicationControllerList(client *client.Client) (*ReplicationControllerList, error) { log.Printf("Getting list of all replication controllers in the cluster") listEverything := api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything(), } replicationControllers, err := client.ReplicationControllers(api.NamespaceAll).List(listEverything) if err != nil { return nil, err } services, err := client.Services(api.NamespaceAll).List(listEverything) if err != nil { return nil, err } pods, err := client.Pods(api.NamespaceAll).List(listEverything) if err != nil { 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 { return GetPodsEventWarnings(eventsList, pods) } // Anonymous callback function to get nodes by their names. getNodeFn := func(nodeName string) (*api.Node, error) { return client.Nodes().Get(nodeName) } result, err := getReplicationControllerList(replicationControllers.Items, services.Items, pods.Items, getPodsEventWarningsFn, getNodeFn) if err != nil { return nil, err } return result, nil }
func doServiceAccountAPIRequests(t *testing.T, c *client.Client, ns string, authenticated bool, canRead bool, canWrite bool) { testSecret := &api.Secret{ ObjectMeta: api.ObjectMeta{Name: "testSecret"}, Data: map[string][]byte{"test": []byte("data")}, } readOps := []testOperation{ func() error { _, err := c.Secrets(ns).List(labels.Everything(), fields.Everything(), unversioned.ListOptions{}) return err }, func() error { _, err := c.Pods(ns).List(labels.Everything(), fields.Everything(), unversioned.ListOptions{}) return err }, } writeOps := []testOperation{ func() error { _, err := c.Secrets(ns).Create(testSecret); return err }, func() error { return c.Secrets(ns).Delete(testSecret.Name) }, } for _, op := range readOps { err := op() unauthorizedError := errors.IsUnauthorized(err) forbiddenError := errors.IsForbidden(err) switch { case !authenticated && !unauthorizedError: t.Fatalf("expected unauthorized error, got %v", err) case authenticated && unauthorizedError: t.Fatalf("unexpected unauthorized error: %v", err) case authenticated && canRead && forbiddenError: t.Fatalf("unexpected forbidden error: %v", err) case authenticated && !canRead && !forbiddenError: t.Fatalf("expected forbidden error, got: %v", err) } } for _, op := range writeOps { err := op() unauthorizedError := errors.IsUnauthorized(err) forbiddenError := errors.IsForbidden(err) switch { case !authenticated && !unauthorizedError: t.Fatalf("expected unauthorized error, got %v", err) case authenticated && unauthorizedError: t.Fatalf("unexpected unauthorized error: %v", err) case authenticated && canWrite && forbiddenError: t.Fatalf("unexpected forbidden error: %v", err) case authenticated && !canWrite && !forbiddenError: t.Fatalf("expected forbidden error, got: %v", err) } } }
// NewPersistentVolumeProvisionerController creates a new PersistentVolumeProvisionerController func NewPersistentVolumeProvisionerController(client controllerClient, syncPeriod time.Duration, plugins []volume.VolumePlugin, provisioner volume.ProvisionableVolumePlugin, cloud cloudprovider.Interface) (*PersistentVolumeProvisionerController, error) { controller := &PersistentVolumeProvisionerController{ client: client, cloud: cloud, provisioner: provisioner, } if err := controller.pluginMgr.InitPlugins(plugins, controller); err != nil { return nil, fmt.Errorf("Could not initialize volume plugins for PersistentVolumeProvisionerController: %+v", err) } glog.V(5).Infof("Initializing provisioner: %s", controller.provisioner.Name()) controller.provisioner.Init(controller) controller.volumeStore, controller.volumeController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return client.ListPersistentVolumes(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVesion string) (watch.Interface, error) { return client.WatchPersistentVolumes(labels.Everything(), fields.Everything(), resourceVesion) }, }, &api.PersistentVolume{}, syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: controller.handleAddVolume, UpdateFunc: controller.handleUpdateVolume, // delete handler not needed in this controller. // volume deletion is handled by the recycler controller }, ) controller.claimStore, controller.claimController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return client.ListPersistentVolumeClaims(api.NamespaceAll, labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return client.WatchPersistentVolumeClaims(api.NamespaceAll, labels.Everything(), fields.Everything(), resourceVersion) }, }, &api.PersistentVolumeClaim{}, syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: controller.handleAddClaim, UpdateFunc: controller.handleUpdateClaim, // delete handler not needed. // normal recycling applies when a claim is deleted. // recycling is handled by the binding controller. }, ) return controller, nil }
// NewTokensController returns a new *TokensController. func NewTokensController(cl client.Interface, options TokensControllerOptions) *TokensController { e := &TokensController{ client: cl, token: options.TokenGenerator, rootCA: options.RootCA, } e.serviceAccounts, e.serviceAccountController = framework.NewIndexerInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return e.client.ServiceAccounts(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { options := api.ListOptions{ResourceVersion: rv} return e.client.ServiceAccounts(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), options) }, }, &api.ServiceAccount{}, options.ServiceAccountResync, framework.ResourceEventHandlerFuncs{ AddFunc: e.serviceAccountAdded, UpdateFunc: e.serviceAccountUpdated, DeleteFunc: e.serviceAccountDeleted, }, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}, ) tokenSelector := fields.SelectorFromSet(map[string]string{client.SecretType: string(api.SecretTypeServiceAccountToken)}) e.secrets, e.secretController = framework.NewIndexerInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return e.client.Secrets(api.NamespaceAll).List(labels.Everything(), tokenSelector) }, WatchFunc: func(rv string) (watch.Interface, error) { options := api.ListOptions{ResourceVersion: rv} return e.client.Secrets(api.NamespaceAll).Watch(labels.Everything(), tokenSelector, options) }, }, &api.Secret{}, options.SecretResync, framework.ResourceEventHandlerFuncs{ AddFunc: e.secretAdded, UpdateFunc: e.secretUpdated, DeleteFunc: e.secretDeleted, }, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}, ) e.serviceAccountsSynced = e.serviceAccountController.HasSynced e.secretsSynced = e.secretController.HasSynced return e }
// NewPersistentVolumeClaimBinder creates a new PersistentVolumeClaimBinder func NewPersistentVolumeClaimBinder(kubeClient client.Interface, syncPeriod time.Duration) *PersistentVolumeClaimBinder { volumeIndex := NewPersistentVolumeOrderedIndex() binderClient := NewBinderClient(kubeClient) binder := &PersistentVolumeClaimBinder{ volumeIndex: volumeIndex, client: binderClient, } _, volumeController := framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return kubeClient.PersistentVolumes().List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { options := api.ListOptions{ResourceVersion: resourceVersion} return kubeClient.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), options) }, }, &api.PersistentVolume{}, // TODO: Can we have much longer period here? syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: binder.addVolume, UpdateFunc: binder.updateVolume, DeleteFunc: binder.deleteVolume, }, ) _, claimController := framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return kubeClient.PersistentVolumeClaims(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { options := api.ListOptions{ResourceVersion: resourceVersion} return kubeClient.PersistentVolumeClaims(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), options) }, }, &api.PersistentVolumeClaim{}, // TODO: Can we have much longer period here? syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: binder.addClaim, UpdateFunc: binder.updateClaim, // no DeleteFunc needed. a claim requires no clean-up. // syncVolume handles the missing claim }, ) binder.claimController = claimController binder.volumeController = volumeController return binder }
// Run event queue for the given resource func (oi *OsdnRegistryInterface) runEventQueue(resourceName string, args interface{}) (*oscache.EventQueue, *cache.Reflector) { eventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) lw := &cache.ListWatch{} var expectedType interface{} switch strings.ToLower(resourceName) { case "hostsubnet": expectedType = &api.HostSubnet{} lw.ListFunc = func() (runtime.Object, error) { return oi.oClient.HostSubnets().List() } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.oClient.HostSubnets().Watch(resourceVersion) } case "node": expectedType = &kapi.Node{} lw.ListFunc = func() (runtime.Object, error) { return oi.kClient.Nodes().List(labels.Everything(), fields.Everything()) } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.kClient.Nodes().Watch(labels.Everything(), fields.Everything(), resourceVersion) } case "namespace": expectedType = &kapi.Namespace{} lw.ListFunc = func() (runtime.Object, error) { return oi.kClient.Namespaces().List(labels.Everything(), fields.Everything()) } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.kClient.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion) } case "netnamespace": expectedType = &api.NetNamespace{} lw.ListFunc = func() (runtime.Object, error) { return oi.oClient.NetNamespaces().List() } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.oClient.NetNamespaces().Watch(resourceVersion) } case "service": expectedType = &kapi.Service{} namespace := args.(string) lw.ListFunc = func() (runtime.Object, error) { return oi.kClient.Services(namespace).List(labels.Everything()) } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.kClient.Services(namespace).Watch(labels.Everything(), fields.Everything(), resourceVersion) } default: log.Fatalf("Unknown resource %s during initialization of event queue", resourceName) } reflector := cache.NewReflector(lw, expectedType, eventQueue, 4*time.Minute) reflector.Run() return eventQueue, reflector }