mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	move client/record
This commit is contained in:
		| @@ -13,12 +13,10 @@ go_library( | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//cmd/cloud-controller-manager/app/options:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/leaderelection:go_default_library", | ||||
|         "//pkg/client/leaderelection/resourcelock:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/cloud:go_default_library", | ||||
| @@ -33,8 +31,11 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apiserver/pkg/server/healthz", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,15 +28,16 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apiserver/pkg/server/healthz" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/tools/clientcmd" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection" | ||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	nodecontroller "k8s.io/kubernetes/pkg/controller/cloud" | ||||
| @@ -123,8 +124,8 @@ func Run(s *options.CloudControllerManagerServer, cloud cloudprovider.Interface) | ||||
|  | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "cloud-controller-manager"}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "cloud-controller-manager"}) | ||||
|  | ||||
| 	run := func(stop <-chan struct{}) { | ||||
| 		rootClientBuilder := controller.SimpleControllerClientBuilder{ | ||||
|   | ||||
| @@ -30,10 +30,8 @@ go_library( | ||||
|         "//pkg/apis/componentconfig:go_default_library", | ||||
|         "//pkg/apis/extensions:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/leaderelection:go_default_library", | ||||
|         "//pkg/client/leaderelection/resourcelock:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/cloudprovider/providers:go_default_library", | ||||
|         "//pkg/cloudprovider/providers/aws:go_default_library", | ||||
| @@ -99,8 +97,11 @@ go_library( | ||||
|         "//vendor:k8s.io/apiserver/pkg/util/feature", | ||||
|         "//vendor:k8s.io/client-go/discovery", | ||||
|         "//vendor:k8s.io/client-go/dynamic", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/cert", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -40,7 +40,7 @@ func startHPAController(ctx ControllerContext) (bool, error) { | ||||
| 	) | ||||
| 	replicaCalc := podautoscaler.NewReplicaCalculator(metricsClient, hpaClient.Core()) | ||||
| 	go podautoscaler.NewHorizontalController( | ||||
| 		hpaClient.Core(), | ||||
| 		ctx.ClientBuilder.ClientGoClientOrDie("horizontal-pod-autoscaler").Core(), | ||||
| 		hpaClient.Extensions(), | ||||
| 		hpaClient.Autoscaling(), | ||||
| 		replicaCalc, | ||||
|   | ||||
| @@ -37,16 +37,17 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apiserver/pkg/server/healthz" | ||||
| 	"k8s.io/client-go/discovery" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/tools/clientcmd" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	certutil "k8s.io/client-go/util/cert" | ||||
| 	"k8s.io/kubernetes/cmd/kube-controller-manager/app/options" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection" | ||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| @@ -144,8 +145,8 @@ func Run(s *options.CMServer) error { | ||||
|  | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "controller-manager"}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "controller-manager"}) | ||||
|  | ||||
| 	run := func(stop <-chan struct{}) { | ||||
| 		rootClientBuilder := controller.SimpleControllerClientBuilder{ | ||||
|   | ||||
| @@ -20,8 +20,6 @@ go_library( | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/internalclientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/proxy:go_default_library", | ||||
|         "//pkg/proxy/config:go_default_library", | ||||
|         "//pkg/proxy/iptables:go_default_library", | ||||
| @@ -44,8 +42,11 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/net", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -32,14 +32,15 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	utilnet "k8s.io/apimachinery/pkg/util/net" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/clientcmd" | ||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/cmd/kube-proxy/app/options" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||
| 	unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/proxy" | ||||
| 	proxyconfig "k8s.io/kubernetes/pkg/proxy/config" | ||||
| 	"k8s.io/kubernetes/pkg/proxy/iptables" | ||||
| @@ -205,7 +206,7 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err | ||||
| 	// Create event recorder | ||||
| 	hostname := nodeutil.GetHostname(config.HostnameOverride) | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "kube-proxy", Host: hostname}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "kube-proxy", Host: hostname}) | ||||
|  | ||||
| 	var proxier proxy.ProxyProvider | ||||
| 	var endpointsHandler proxyconfig.EndpointsConfigHandler | ||||
| @@ -326,7 +327,7 @@ func (s *ProxyServer) Run() error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	s.Broadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: s.Client.Core().Events("")}) | ||||
| 	s.Broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(s.Client.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	// Start up a webserver if requested | ||||
| 	if s.Config.HealthzPort > 0 { | ||||
|   | ||||
| @@ -45,8 +45,6 @@ go_library( | ||||
|         "//pkg/client/chaosclient:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/certificates/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/cloudprovider/providers:go_default_library", | ||||
|         "//pkg/credentialprovider:go_default_library", | ||||
| @@ -115,10 +113,13 @@ go_library( | ||||
|         "//vendor:k8s.io/client-go/kubernetes", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/authentication/v1beta1", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/authorization/v1beta1", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/auth", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/cert", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -44,10 +44,13 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/server/healthz" | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	clientgoclientset "k8s.io/client-go/kubernetes" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	clientauth "k8s.io/client-go/tools/auth" | ||||
| 	"k8s.io/client-go/tools/clientcmd" | ||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	certutil "k8s.io/client-go/util/cert" | ||||
| 	"k8s.io/kubernetes/cmd/kubelet/app/options" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| @@ -57,8 +60,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/capabilities" | ||||
| 	"k8s.io/kubernetes/pkg/client/chaosclient" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/credentialprovider" | ||||
| 	"k8s.io/kubernetes/pkg/features" | ||||
| @@ -362,7 +363,8 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.KubeletDeps) (err error) { | ||||
| 	} | ||||
|  | ||||
| 	if kubeDeps == nil { | ||||
| 		var kubeClient, eventClient *clientset.Clientset | ||||
| 		var kubeClient *clientset.Clientset | ||||
| 		var eventClient v1core.EventsGetter | ||||
| 		var externalKubeClient clientgoclientset.Interface | ||||
| 		var cloud cloudprovider.Interface | ||||
|  | ||||
| @@ -398,7 +400,7 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.KubeletDeps) (err error) { | ||||
| 			eventClientConfig := *clientConfig | ||||
| 			eventClientConfig.QPS = float32(s.EventRecordQPS) | ||||
| 			eventClientConfig.Burst = int(s.EventBurst) | ||||
| 			eventClient, err = clientset.NewForConfig(&eventClientConfig) | ||||
| 			eventClient, err = clientgoclientset.NewForConfig(&eventClientConfig) | ||||
| 			if err != nil { | ||||
| 				glog.Warningf("Failed to create API Server client: %v", err) | ||||
| 			} | ||||
| @@ -698,7 +700,7 @@ func RunKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet | ||||
| 	} | ||||
|  | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	kubeDeps.Recorder = eventBroadcaster.NewRecorder(v1.EventSource{Component: "kubelet", Host: string(nodeName)}) | ||||
| 	kubeDeps.Recorder = eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "kubelet", Host: string(nodeName)}) | ||||
| 	eventBroadcaster.StartLogging(glog.V(3).Infof) | ||||
| 	if kubeDeps.EventClient != nil { | ||||
| 		glog.V(4).Infof("Sending events to api server.") | ||||
|   | ||||
| @@ -19,11 +19,10 @@ go_library( | ||||
|     srcs = ["hollow-node.go"], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/internalclientset:go_default_library", | ||||
|         "//pkg/client/metrics/prometheus:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/kubelet/cadvisor/testing:go_default_library", | ||||
|         "//pkg/kubelet/cm:go_default_library", | ||||
|         "//pkg/kubelet/dockertools:go_default_library", | ||||
| @@ -35,8 +34,10 @@ go_library( | ||||
|         "//vendor:github.com/spf13/pflag", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apiserver/pkg/util/flag", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -21,13 +21,14 @@ import ( | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apiserver/pkg/util/flag" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/tools/clientcmd" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||
| 	_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing" | ||||
| 	"k8s.io/kubernetes/pkg/kubelet/cm" | ||||
| 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | ||||
| @@ -129,7 +130,7 @@ func main() { | ||||
|  | ||||
| 	if config.Morph == "proxy" { | ||||
| 		eventBroadcaster := record.NewBroadcaster() | ||||
| 		recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "kube-proxy", Host: config.NodeName}) | ||||
| 		recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "kube-proxy", Host: config.NodeName}) | ||||
|  | ||||
| 		iptInterface := fakeiptables.NewFake() | ||||
|  | ||||
|   | ||||
| @@ -20,14 +20,15 @@ go_library( | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -23,7 +23,9 @@ import ( | ||||
| 	pkgruntime "k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -32,7 +34,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -80,7 +81,7 @@ type ConfigMapController struct { | ||||
| func NewConfigMapController(client federationclientset.Interface) *ConfigMapController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-configmaps-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-configmaps-controller"}) | ||||
|  | ||||
| 	configmapcontroller := &ConfigMapController{ | ||||
| 		federatedApiClient:    client, | ||||
|   | ||||
| @@ -19,10 +19,8 @@ go_library( | ||||
|         "//federation/pkg/federation-controller/util/deletionhelper:go_default_library", | ||||
|         "//federation/pkg/federation-controller/util/eventsink:go_default_library", | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -30,7 +28,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -26,7 +26,9 @@ import ( | ||||
| 	pkgruntime "k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -34,10 +36,8 @@ import ( | ||||
| 	"k8s.io/kubernetes/federation/pkg/federation-controller/util/deletionhelper" | ||||
| 	"k8s.io/kubernetes/federation/pkg/federation-controller/util/eventsink" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensionsv1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -87,7 +87,7 @@ type DaemonSetController struct { | ||||
| func NewDaemonSetController(client federationclientset.Interface) *DaemonSetController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-daemonset-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-daemonset-controller"}) | ||||
|  | ||||
| 	daemonsetcontroller := &DaemonSetController{ | ||||
| 		federatedApiClient:    client, | ||||
|   | ||||
| @@ -25,7 +25,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -33,7 +32,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
|   | ||||
| @@ -30,7 +30,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	fed "k8s.io/kubernetes/federation/apis/federation" | ||||
| @@ -45,7 +47,6 @@ import ( | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensionsv1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| ) | ||||
|  | ||||
| @@ -104,7 +105,7 @@ type DeploymentController struct { | ||||
| func NewDeploymentController(federationClient fedclientset.Interface) *DeploymentController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(federationClient)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-deployment-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-deployment-controller"}) | ||||
|  | ||||
| 	fdc := &DeploymentController{ | ||||
| 		fedClient:           federationClient, | ||||
|   | ||||
| @@ -22,7 +22,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -31,7 +30,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime/schema", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -27,7 +27,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -38,7 +40,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -119,7 +120,7 @@ func NewIngressController(client federationclientset.Interface) *IngressControll | ||||
| 	glog.V(4).Infof("->NewIngressController V(4)") | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client)) | ||||
| 	recorder := broadcaster.NewRecorder(v1.EventSource{Component: "federated-ingress-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-ingress-controller"}) | ||||
| 	ic := &IngressController{ | ||||
| 		federatedApiClient:    client, | ||||
| 		ingressReviewDelay:    time.Second * 10, | ||||
|   | ||||
| @@ -21,14 +21,15 @@ go_library( | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -24,7 +24,9 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -34,7 +36,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -84,7 +85,7 @@ type NamespaceController struct { | ||||
| func NewNamespaceController(client federationclientset.Interface) *NamespaceController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-namespace-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-namespace-controller"}) | ||||
|  | ||||
| 	nc := &NamespaceController{ | ||||
| 		federatedApiClient:    client, | ||||
|   | ||||
| @@ -26,7 +26,6 @@ go_library( | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -34,7 +33,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
|   | ||||
| @@ -30,7 +30,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	fed "k8s.io/kubernetes/federation/apis/federation" | ||||
| @@ -46,7 +48,6 @@ import ( | ||||
| 	extensionsv1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| ) | ||||
|  | ||||
| @@ -107,7 +108,7 @@ type ReplicaSetController struct { | ||||
| func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSetController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(federationClient)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-replicaset-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-replicaset-controller"}) | ||||
|  | ||||
| 	frsc := &ReplicaSetController{ | ||||
| 		fedClient:           federationClient, | ||||
|   | ||||
| @@ -21,7 +21,6 @@ go_library( | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -29,7 +28,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -25,7 +25,9 @@ import ( | ||||
| 	pkgruntime "k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -35,7 +37,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -85,7 +86,7 @@ type SecretController struct { | ||||
| func NewSecretController(client federationclientset.Interface) *SecretController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client)) | ||||
| 	recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-secrets-controller"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-secrets-controller"}) | ||||
|  | ||||
| 	secretcontroller := &SecretController{ | ||||
| 		federatedApiClient:    client, | ||||
|   | ||||
| @@ -31,7 +31,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -42,8 +41,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -32,7 +32,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	cache "k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationcache "k8s.io/kubernetes/federation/client/cache" | ||||
| @@ -45,7 +47,6 @@ import ( | ||||
| 	v1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| ) | ||||
|  | ||||
| @@ -159,7 +160,7 @@ func New(federationClient fedclientset.Interface, dns dnsprovider.Interface, | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	// federationClient event is not supported yet | ||||
| 	// broadcaster.StartRecordingToSink(&unversioned_core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(v1.EventSource{Component: UserAgentName}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: UserAgentName}) | ||||
|  | ||||
| 	s := &ServiceController{ | ||||
| 		dns:              dns, | ||||
|   | ||||
| @@ -15,9 +15,9 @@ go_library( | ||||
|         "//federation/pkg/federation-controller/util:go_default_library", | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -25,10 +25,10 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/federation/pkg/federation-controller/util" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	api_v1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -14,9 +14,14 @@ go_library( | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//federation/client/clientset_generated/federation_clientset:go_default_library", | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/conversion", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -32,6 +37,7 @@ go_test( | ||||
|         "//vendor:github.com/stretchr/testify/assert", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/testing", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -17,13 +17,20 @@ limitations under the License. | ||||
| package eventsink | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| 	api_v1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	kubev1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| ) | ||||
|  | ||||
| // Implements k8s.io/kubernetes/pkg/client/record.EventSink. | ||||
| // Implements k8s.io/client-go/tools/record.EventSink. | ||||
| type FederatedEventSink struct { | ||||
| 	clientset fedclientset.Interface | ||||
| } | ||||
| @@ -37,14 +44,80 @@ func NewFederatedEventSink(clientset fedclientset.Interface) *FederatedEventSink | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (fes *FederatedEventSink) Create(event *api_v1.Event) (*api_v1.Event, error) { | ||||
| 	return fes.clientset.Core().Events(event.Namespace).Create(event) | ||||
| // TODO this is uses a reflection conversion path and is very expensive.  federation should update to use client-go | ||||
|  | ||||
| var scheme = runtime.NewScheme() | ||||
|  | ||||
| func init() { | ||||
| 	scheme.AddKnownTypes(clientv1.SchemeGroupVersion, | ||||
| 		&clientv1.Event{}, | ||||
| 		&kubev1.Event{}, | ||||
| 	) | ||||
| 	if err := scheme.AddConversionFuncs( | ||||
| 		api.Convert_unversioned_Time_To_unversioned_Time, | ||||
| 	); err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	if err := scheme.AddGeneratedDeepCopyFuncs( | ||||
| 		conversion.GeneratedDeepCopyFunc{ | ||||
| 			Fn:     metav1.DeepCopy_v1_Time, | ||||
| 			InType: reflect.TypeOf(&metav1.Time{}), | ||||
| 		}, | ||||
| 	); err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (fes *FederatedEventSink) Update(event *api_v1.Event) (*api_v1.Event, error) { | ||||
| 	return fes.clientset.Core().Events(event.Namespace).Update(event) | ||||
| func (fes *FederatedEventSink) Create(event *clientv1.Event) (*clientv1.Event, error) { | ||||
| 	kubeEvent := &kubev1.Event{} | ||||
| 	if err := scheme.Convert(event, kubeEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ret, err := fes.clientset.Core().Events(kubeEvent.Namespace).Create(kubeEvent) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	retEvent := &clientv1.Event{} | ||||
| 	if err := scheme.Convert(ret, retEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return retEvent, nil | ||||
| } | ||||
|  | ||||
| func (fes *FederatedEventSink) Patch(event *api_v1.Event, data []byte) (*api_v1.Event, error) { | ||||
| 	return fes.clientset.Core().Events(event.Namespace).Patch(event.Name, types.StrategicMergePatchType, data) | ||||
| func (fes *FederatedEventSink) Update(event *clientv1.Event) (*clientv1.Event, error) { | ||||
| 	kubeEvent := &kubev1.Event{} | ||||
| 	if err := scheme.Convert(event, kubeEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ret, err := fes.clientset.Core().Events(kubeEvent.Namespace).Update(kubeEvent) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	retEvent := &clientv1.Event{} | ||||
| 	if err := scheme.Convert(ret, retEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return retEvent, nil | ||||
| } | ||||
|  | ||||
| func (fes *FederatedEventSink) Patch(event *clientv1.Event, data []byte) (*clientv1.Event, error) { | ||||
| 	kubeEvent := &kubev1.Event{} | ||||
| 	if err := scheme.Convert(event, kubeEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ret, err := fes.clientset.Core().Events(kubeEvent.Namespace).Patch(kubeEvent.Name, types.StrategicMergePatchType, data) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	retEvent := &clientv1.Event{} | ||||
| 	if err := scheme.Convert(ret, retEvent, nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return retEvent, nil | ||||
| } | ||||
|   | ||||
| @@ -21,10 +21,11 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	fakefedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset/fake" | ||||
| 	. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test" | ||||
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubev1 "k8s.io/kubernetes/pkg/api/v1" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| @@ -46,7 +47,7 @@ func TestEventSink(t *testing.T) { | ||||
| 		return true, obj, nil | ||||
| 	}) | ||||
|  | ||||
| 	event := apiv1.Event{ | ||||
| 	event := clientv1.Event{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      "bzium", | ||||
| 			Namespace: "ns", | ||||
| @@ -55,7 +56,7 @@ func TestEventSink(t *testing.T) { | ||||
| 	sink := NewFederatedEventSink(fakeFederationClient) | ||||
| 	eventUpdated, err := sink.Create(&event) | ||||
| 	assert.NoError(t, err) | ||||
| 	eventV1 := GetObjectFromChan(createdChan).(*apiv1.Event) | ||||
| 	eventV1 := GetObjectFromChan(createdChan).(*kubev1.Event) | ||||
| 	assert.NotNil(t, eventV1) | ||||
| 	// Just some simple sanity checks. | ||||
| 	assert.Equal(t, event.Name, eventV1.Name) | ||||
| @@ -63,7 +64,7 @@ func TestEventSink(t *testing.T) { | ||||
|  | ||||
| 	eventUpdated, err = sink.Update(&event) | ||||
| 	assert.NoError(t, err) | ||||
| 	eventV1 = GetObjectFromChan(updateChan).(*apiv1.Event) | ||||
| 	eventV1 = GetObjectFromChan(updateChan).(*kubev1.Event) | ||||
| 	assert.NotNil(t, eventV1) | ||||
| 	// Just some simple sanity checks. | ||||
| 	assert.Equal(t, event.Name, eventV1.Name) | ||||
|   | ||||
| @@ -67,7 +67,6 @@ filegroup( | ||||
|         "//pkg/client/listers/storage/internalversion:all-srcs", | ||||
|         "//pkg/client/listers/storage/v1beta1:all-srcs", | ||||
|         "//pkg/client/metrics:all-srcs", | ||||
|         "//pkg/client/record:all-srcs", | ||||
|         "//pkg/client/retry:all-srcs", | ||||
|         "//pkg/client/testdata:all-srcs", | ||||
|         "//pkg/client/tests:all-srcs", | ||||
|   | ||||
| @@ -37,7 +37,7 @@ var ( | ||||
| // object, or an error if the object doesn't follow the conventions | ||||
| // that would allow this. | ||||
| // TODO: should take a meta.Interface see http://issue.k8s.io/7127 | ||||
| func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*ObjectReference, error) { | ||||
| 	if obj == nil { | ||||
| 		return nil, ErrNilObject | ||||
| 	} | ||||
| @@ -53,7 +53,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| 	kind := gvk.Kind | ||||
| 	if len(kind) == 0 { | ||||
| 		// TODO: this is wrong | ||||
| 		gvks, _, err := Scheme.ObjectKinds(obj) | ||||
| 		gvks, _, err := scheme.ObjectKinds(obj) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| @@ -111,8 +111,8 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| } | ||||
|  | ||||
| // GetPartialReference is exactly like GetReference, but allows you to set the FieldPath. | ||||
| func GetPartialReference(obj runtime.Object, fieldPath string) (*ObjectReference, error) { | ||||
| 	ref, err := GetReference(obj) | ||||
| func GetPartialReference(scheme *runtime.Scheme, obj runtime.Object, fieldPath string) (*ObjectReference, error) { | ||||
| 	ref, err := GetReference(scheme, obj) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -125,7 +125,7 @@ func TestGetReference(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	for name, item := range table { | ||||
| 		ref, err := GetPartialReference(item.obj, item.fieldPath) | ||||
| 		ref, err := GetPartialReference(Scheme, item.obj, item.fieldPath) | ||||
| 		if e, a := item.shouldErr, (err != nil); e != a { | ||||
| 			t.Errorf("%v: expected %v, got %v, err %v", name, e, a, err) | ||||
| 			continue | ||||
|   | ||||
| @@ -23,7 +23,6 @@ import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/api/meta" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| @@ -39,7 +38,7 @@ var ( | ||||
| // object, or an error if the object doesn't follow the conventions | ||||
| // that would allow this. | ||||
| // TODO: should take a meta.Interface see http://issue.k8s.io/7127 | ||||
| func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*ObjectReference, error) { | ||||
| 	if obj == nil { | ||||
| 		return nil, ErrNilObject | ||||
| 	} | ||||
| @@ -55,7 +54,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| 	kind := gvk.Kind | ||||
| 	if len(kind) == 0 { | ||||
| 		// TODO: this is wrong | ||||
| 		gvks, _, err := api.Scheme.ObjectKinds(obj) | ||||
| 		gvks, _, err := scheme.ObjectKinds(obj) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| @@ -113,8 +112,8 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { | ||||
| } | ||||
|  | ||||
| // GetPartialReference is exactly like GetReference, but allows you to set the FieldPath. | ||||
| func GetPartialReference(obj runtime.Object, fieldPath string) (*ObjectReference, error) { | ||||
| 	ref, err := GetReference(obj) | ||||
| func GetPartialReference(scheme *runtime.Scheme, obj runtime.Object, fieldPath string) (*ObjectReference, error) { | ||||
| 	ref, err := GetReference(scheme, obj) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -35,7 +35,7 @@ type EventExpansion interface { | ||||
| 	UpdateWithEventNamespace(event *v1.Event) (*v1.Event, error) | ||||
| 	PatchWithEventNamespace(event *v1.Event, data []byte) (*v1.Event, error) | ||||
| 	// Search finds events about the specified object | ||||
| 	Search(objOrRef runtime.Object) (*v1.EventList, error) | ||||
| 	Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*v1.EventList, error) | ||||
| 	// Returns the appropriate field selector based on the API version being used to communicate with the server. | ||||
| 	// The returned field selector can be used with List and Watch to filter desired events. | ||||
| 	GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector | ||||
| @@ -99,8 +99,8 @@ func (e *events) PatchWithEventNamespace(incompleteEvent *v1.Event, data []byte) | ||||
| // Search finds events about the specified object. The namespace of the | ||||
| // object must match this event's client namespace unless the event client | ||||
| // was made with the "" namespace. | ||||
| func (e *events) Search(objOrRef runtime.Object) (*v1.EventList, error) { | ||||
| 	ref, err := api.GetReference(objOrRef) | ||||
| func (e *events) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*v1.EventList, error) { | ||||
| 	ref, err := api.GetReference(scheme, objOrRef) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -66,7 +66,7 @@ func (c *FakeEvents) PatchWithEventNamespace(event *v1.Event, data []byte) (*v1. | ||||
| } | ||||
|  | ||||
| // Search returns a list of events matching the specified object. | ||||
| func (c *FakeEvents) Search(objOrRef runtime.Object) (*v1.EventList, error) { | ||||
| func (c *FakeEvents) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*v1.EventList, error) { | ||||
| 	action := core.NewRootListAction(eventsResource, api.ListOptions{}) | ||||
| 	if c.ns != "" { | ||||
| 		action = core.NewListAction(eventsResource, c.ns, api.ListOptions{}) | ||||
|   | ||||
| @@ -35,7 +35,7 @@ type EventExpansion interface { | ||||
| 	UpdateWithEventNamespace(event *api.Event) (*api.Event, error) | ||||
| 	PatchWithEventNamespace(event *api.Event, data []byte) (*api.Event, error) | ||||
| 	// Search finds events about the specified object | ||||
| 	Search(objOrRef runtime.Object) (*api.EventList, error) | ||||
| 	Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*api.EventList, error) | ||||
| 	// Returns the appropriate field selector based on the API version being used to communicate with the server. | ||||
| 	// The returned field selector can be used with List and Watch to filter desired events. | ||||
| 	GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector | ||||
| @@ -99,8 +99,8 @@ func (e *events) PatchWithEventNamespace(incompleteEvent *api.Event, data []byte | ||||
| // Search finds events about the specified object. The namespace of the | ||||
| // object must match this event's client namespace unless the event client | ||||
| // was made with the "" namespace. | ||||
| func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) { | ||||
| 	ref, err := api.GetReference(objOrRef) | ||||
| func (e *events) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*api.EventList, error) { | ||||
| 	ref, err := api.GetReference(scheme, objOrRef) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -66,7 +66,7 @@ func (c *FakeEvents) PatchWithEventNamespace(event *api.Event, data []byte) (*ap | ||||
| } | ||||
|  | ||||
| // Search returns a list of events matching the specified object. | ||||
| func (c *FakeEvents) Search(objOrRef runtime.Object) (*api.EventList, error) { | ||||
| func (c *FakeEvents) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*api.EventList, error) { | ||||
| 	action := core.NewRootListAction(eventsResource, metav1.ListOptions{}) | ||||
| 	if c.ns != "" { | ||||
| 		action = core.NewListAction(eventsResource, c.ns, metav1.ListOptions{}) | ||||
|   | ||||
| @@ -33,11 +33,11 @@ go_test( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/fake:go_default_library", | ||||
|         "//pkg/client/leaderelection/resourcelock:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/client-go/testing", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -30,10 +30,10 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	fakeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| 	rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| func TestTryAcquireOrRenew(t *testing.T) { | ||||
|   | ||||
| @@ -17,8 +17,8 @@ go_library( | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ package resourcelock | ||||
|  | ||||
| import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -1,68 +0,0 @@ | ||||
| package(default_visibility = ["//visibility:public"]) | ||||
|  | ||||
| licenses(["notice"]) | ||||
|  | ||||
| load( | ||||
|     "@io_bazel_rules_go//go:def.bzl", | ||||
|     "go_library", | ||||
|     "go_test", | ||||
| ) | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "doc.go", | ||||
|         "event.go", | ||||
|         "events_cache.go", | ||||
|         "fake.go", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:github.com/golang/groupcache/lru", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/strategicpatch", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| go_test( | ||||
|     name = "go_default_test", | ||||
|     srcs = [ | ||||
|         "event_test.go", | ||||
|         "events_cache_test.go", | ||||
|     ], | ||||
|     library = ":go_default_library", | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api/install:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/diff", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/strategicpatch", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [":package-srcs"], | ||||
|     tags = ["automanaged"], | ||||
| ) | ||||
| @@ -1,27 +0,0 @@ | ||||
| reviewers: | ||||
| - lavalamp | ||||
| - smarterclayton | ||||
| - wojtek-t | ||||
| - deads2k | ||||
| - derekwaynecarr | ||||
| - caesarxuchao | ||||
| - vishh | ||||
| - mikedanese | ||||
| - liggitt | ||||
| - nikhiljindal | ||||
| - erictune | ||||
| - pmorie | ||||
| - dchen1107 | ||||
| - saad-ali | ||||
| - luxas | ||||
| - yifan-gu | ||||
| - eparis | ||||
| - mwielgus | ||||
| - timothysc | ||||
| - jsafrane | ||||
| - dims | ||||
| - krousey | ||||
| - a-robinson | ||||
| - aveshagarwal | ||||
| - resouer | ||||
| - cjcullen | ||||
| @@ -1,18 +0,0 @@ | ||||
| /* | ||||
| Copyright 2014 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| // Package record has all client logic for recording and reporting events. | ||||
| package record // import "k8s.io/kubernetes/pkg/client/record" | ||||
| @@ -1,316 +0,0 @@ | ||||
| /* | ||||
| Copyright 2014 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package record | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
|  | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|  | ||||
| const maxTriesPerEvent = 12 | ||||
|  | ||||
| var defaultSleepDuration = 10 * time.Second | ||||
|  | ||||
| const maxQueuedEvents = 1000 | ||||
|  | ||||
| // EventSink knows how to store events (client.Client implements it.) | ||||
| // EventSink must respect the namespace that will be embedded in 'event'. | ||||
| // It is assumed that EventSink will return the same sorts of errors as | ||||
| // pkg/client's REST client. | ||||
| type EventSink interface { | ||||
| 	Create(event *v1.Event) (*v1.Event, error) | ||||
| 	Update(event *v1.Event) (*v1.Event, error) | ||||
| 	Patch(oldEvent *v1.Event, data []byte) (*v1.Event, error) | ||||
| } | ||||
|  | ||||
| // EventRecorder knows how to record events on behalf of an EventSource. | ||||
| type EventRecorder interface { | ||||
| 	// Event constructs an event from the given information and puts it in the queue for sending. | ||||
| 	// 'object' is the object this event is about. Event will make a reference-- or you may also | ||||
| 	// pass a reference to the object directly. | ||||
| 	// 'type' of this event, and can be one of Normal, Warning. New types could be added in future | ||||
| 	// 'reason' is the reason this event is generated. 'reason' should be short and unique; it | ||||
| 	// should be in UpperCamelCase format (starting with a capital letter). "reason" will be used | ||||
| 	// to automate handling of events, so imagine people writing switch statements to handle them. | ||||
| 	// You want to make that easy. | ||||
| 	// 'message' is intended to be human readable. | ||||
| 	// | ||||
| 	// The resulting event will be created in the same namespace as the reference object. | ||||
| 	Event(object runtime.Object, eventtype, reason, message string) | ||||
|  | ||||
| 	// Eventf is just like Event, but with Sprintf for the message field. | ||||
| 	Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) | ||||
|  | ||||
| 	// PastEventf is just like Eventf, but with an option to specify the event's 'timestamp' field. | ||||
| 	PastEventf(object runtime.Object, timestamp metav1.Time, eventtype, reason, messageFmt string, args ...interface{}) | ||||
| } | ||||
|  | ||||
| // EventBroadcaster knows how to receive events and send them to any EventSink, watcher, or log. | ||||
| type EventBroadcaster interface { | ||||
| 	// StartEventWatcher starts sending events received from this EventBroadcaster to the given | ||||
| 	// event handler function. The return value can be ignored or used to stop recording, if | ||||
| 	// desired. | ||||
| 	StartEventWatcher(eventHandler func(*v1.Event)) watch.Interface | ||||
|  | ||||
| 	// StartRecordingToSink starts sending events received from this EventBroadcaster to the given | ||||
| 	// sink. The return value can be ignored or used to stop recording, if desired. | ||||
| 	StartRecordingToSink(sink EventSink) watch.Interface | ||||
|  | ||||
| 	// StartLogging starts sending events received from this EventBroadcaster to the given logging | ||||
| 	// function. The return value can be ignored or used to stop recording, if desired. | ||||
| 	StartLogging(logf func(format string, args ...interface{})) watch.Interface | ||||
|  | ||||
| 	// NewRecorder returns an EventRecorder that can be used to send events to this EventBroadcaster | ||||
| 	// with the event source set to the given event source. | ||||
| 	NewRecorder(source v1.EventSource) EventRecorder | ||||
| } | ||||
|  | ||||
| // Creates a new event broadcaster. | ||||
| func NewBroadcaster() EventBroadcaster { | ||||
| 	return &eventBroadcasterImpl{watch.NewBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration} | ||||
| } | ||||
|  | ||||
| func NewBroadcasterForTests(sleepDuration time.Duration) EventBroadcaster { | ||||
| 	return &eventBroadcasterImpl{watch.NewBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), sleepDuration} | ||||
| } | ||||
|  | ||||
| type eventBroadcasterImpl struct { | ||||
| 	*watch.Broadcaster | ||||
| 	sleepDuration time.Duration | ||||
| } | ||||
|  | ||||
| // StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink. | ||||
| // The return value can be ignored or used to stop recording, if desired. | ||||
| // TODO: make me an object with parameterizable queue length and retry interval | ||||
| func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interface { | ||||
| 	// The default math/rand package functions aren't thread safe, so create a | ||||
| 	// new Rand object for each StartRecording call. | ||||
| 	randGen := rand.New(rand.NewSource(time.Now().UnixNano())) | ||||
| 	eventCorrelator := NewEventCorrelator(clock.RealClock{}) | ||||
| 	return eventBroadcaster.StartEventWatcher( | ||||
| 		func(event *v1.Event) { | ||||
| 			recordToSink(sink, event, eventCorrelator, randGen, eventBroadcaster.sleepDuration) | ||||
| 		}) | ||||
| } | ||||
|  | ||||
| func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, randGen *rand.Rand, sleepDuration time.Duration) { | ||||
| 	// Make a copy before modification, because there could be multiple listeners. | ||||
| 	// Events are safe to copy like this. | ||||
| 	eventCopy := *event | ||||
| 	event = &eventCopy | ||||
| 	result, err := eventCorrelator.EventCorrelate(event) | ||||
| 	if err != nil { | ||||
| 		utilruntime.HandleError(err) | ||||
| 	} | ||||
| 	if result.Skip { | ||||
| 		return | ||||
| 	} | ||||
| 	tries := 0 | ||||
| 	for { | ||||
| 		if recordEvent(sink, result.Event, result.Patch, result.Event.Count > 1, eventCorrelator) { | ||||
| 			break | ||||
| 		} | ||||
| 		tries++ | ||||
| 		if tries >= maxTriesPerEvent { | ||||
| 			glog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event) | ||||
| 			break | ||||
| 		} | ||||
| 		// Randomize the first sleep so that various clients won't all be | ||||
| 		// synced up if the master goes down. | ||||
| 		if tries == 1 { | ||||
| 			time.Sleep(time.Duration(float64(sleepDuration) * randGen.Float64())) | ||||
| 		} else { | ||||
| 			time.Sleep(sleepDuration) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isKeyNotFoundError(err error) bool { | ||||
| 	statusErr, _ := err.(*errors.StatusError) | ||||
|  | ||||
| 	if statusErr != nil && statusErr.Status().Code == http.StatusNotFound { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // recordEvent attempts to write event to a sink. It returns true if the event | ||||
| // was successfully recorded or discarded, false if it should be retried. | ||||
| // If updateExistingEvent is false, it creates a new event, otherwise it updates | ||||
| // existing event. | ||||
| func recordEvent(sink EventSink, event *v1.Event, patch []byte, updateExistingEvent bool, eventCorrelator *EventCorrelator) bool { | ||||
| 	var newEvent *v1.Event | ||||
| 	var err error | ||||
| 	if updateExistingEvent { | ||||
| 		newEvent, err = sink.Patch(event, patch) | ||||
| 	} | ||||
| 	// Update can fail because the event may have been removed and it no longer exists. | ||||
| 	if !updateExistingEvent || (updateExistingEvent && isKeyNotFoundError(err)) { | ||||
| 		// Making sure that ResourceVersion is empty on creation | ||||
| 		event.ResourceVersion = "" | ||||
| 		newEvent, err = sink.Create(event) | ||||
| 	} | ||||
| 	if err == nil { | ||||
| 		// we need to update our event correlator with the server returned state to handle name/resourceversion | ||||
| 		eventCorrelator.UpdateState(newEvent) | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	// If we can't contact the server, then hold everything while we keep trying. | ||||
| 	// Otherwise, something about the event is malformed and we should abandon it. | ||||
| 	switch err.(type) { | ||||
| 	case *restclient.RequestConstructionError: | ||||
| 		// We will construct the request the same next time, so don't keep trying. | ||||
| 		glog.Errorf("Unable to construct event '%#v': '%v' (will not retry!)", event, err) | ||||
| 		return true | ||||
| 	case *errors.StatusError: | ||||
| 		if errors.IsAlreadyExists(err) { | ||||
| 			glog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err) | ||||
| 		} else { | ||||
| 			glog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err) | ||||
| 		} | ||||
| 		return true | ||||
| 	case *errors.UnexpectedObjectError: | ||||
| 		// We don't expect this; it implies the server's response didn't match a | ||||
| 		// known pattern. Go ahead and retry. | ||||
| 	default: | ||||
| 		// This case includes actual http transport errors. Go ahead and retry. | ||||
| 	} | ||||
| 	glog.Errorf("Unable to write event: '%v' (may retry after sleeping)", err) | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // StartLogging starts sending events received from this EventBroadcaster to the given logging function. | ||||
| // The return value can be ignored or used to stop recording, if desired. | ||||
| func (eventBroadcaster *eventBroadcasterImpl) StartLogging(logf func(format string, args ...interface{})) watch.Interface { | ||||
| 	return eventBroadcaster.StartEventWatcher( | ||||
| 		func(e *v1.Event) { | ||||
| 			logf("Event(%#v): type: '%v' reason: '%v' %v", e.InvolvedObject, e.Type, e.Reason, e.Message) | ||||
| 		}) | ||||
| } | ||||
|  | ||||
| // StartEventWatcher starts sending events received from this EventBroadcaster to the given event handler function. | ||||
| // The return value can be ignored or used to stop recording, if desired. | ||||
| func (eventBroadcaster *eventBroadcasterImpl) StartEventWatcher(eventHandler func(*v1.Event)) watch.Interface { | ||||
| 	watcher := eventBroadcaster.Watch() | ||||
| 	go func() { | ||||
| 		defer utilruntime.HandleCrash() | ||||
| 		for { | ||||
| 			watchEvent, open := <-watcher.ResultChan() | ||||
| 			if !open { | ||||
| 				return | ||||
| 			} | ||||
| 			event, ok := watchEvent.Object.(*v1.Event) | ||||
| 			if !ok { | ||||
| 				// This is all local, so there's no reason this should | ||||
| 				// ever happen. | ||||
| 				continue | ||||
| 			} | ||||
| 			eventHandler(event) | ||||
| 		} | ||||
| 	}() | ||||
| 	return watcher | ||||
| } | ||||
|  | ||||
| // NewRecorder returns an EventRecorder that records events with the given event source. | ||||
| func (eventBroadcaster *eventBroadcasterImpl) NewRecorder(source v1.EventSource) EventRecorder { | ||||
| 	return &recorderImpl{source, eventBroadcaster.Broadcaster, clock.RealClock{}} | ||||
| } | ||||
|  | ||||
| type recorderImpl struct { | ||||
| 	source v1.EventSource | ||||
| 	*watch.Broadcaster | ||||
| 	clock clock.Clock | ||||
| } | ||||
|  | ||||
| func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp metav1.Time, eventtype, reason, message string) { | ||||
| 	ref, err := v1.GetReference(object) | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v' '%v'", object, err, eventtype, reason, message) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if !validateEventType(eventtype) { | ||||
| 		glog.Errorf("Unsupported event type: '%v'", eventtype) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	event := recorder.makeEvent(ref, eventtype, reason, message) | ||||
| 	event.Source = recorder.source | ||||
|  | ||||
| 	go func() { | ||||
| 		// NOTE: events should be a non-blocking operation | ||||
| 		defer utilruntime.HandleCrash() | ||||
| 		recorder.Action(watch.Added, event) | ||||
| 	}() | ||||
| } | ||||
|  | ||||
| func validateEventType(eventtype string) bool { | ||||
| 	switch eventtype { | ||||
| 	case v1.EventTypeNormal, v1.EventTypeWarning: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (recorder *recorderImpl) Event(object runtime.Object, eventtype, reason, message string) { | ||||
| 	recorder.generateEvent(object, metav1.Now(), eventtype, reason, message) | ||||
| } | ||||
|  | ||||
| func (recorder *recorderImpl) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { | ||||
| 	recorder.Event(object, eventtype, reason, fmt.Sprintf(messageFmt, args...)) | ||||
| } | ||||
|  | ||||
| func (recorder *recorderImpl) PastEventf(object runtime.Object, timestamp metav1.Time, eventtype, reason, messageFmt string, args ...interface{}) { | ||||
| 	recorder.generateEvent(object, timestamp, eventtype, reason, fmt.Sprintf(messageFmt, args...)) | ||||
| } | ||||
|  | ||||
| func (recorder *recorderImpl) makeEvent(ref *v1.ObjectReference, eventtype, reason, message string) *v1.Event { | ||||
| 	t := metav1.Time{Time: recorder.clock.Now()} | ||||
| 	namespace := ref.Namespace | ||||
| 	if namespace == "" { | ||||
| 		namespace = metav1.NamespaceDefault | ||||
| 	} | ||||
| 	return &v1.Event{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()), | ||||
| 			Namespace: namespace, | ||||
| 		}, | ||||
| 		InvolvedObject: *ref, | ||||
| 		Reason:         reason, | ||||
| 		Message:        message, | ||||
| 		FirstTimestamp: t, | ||||
| 		LastTimestamp:  t, | ||||
| 		Count:          1, | ||||
| 		Type:           eventtype, | ||||
| 	} | ||||
| } | ||||
| @@ -1,914 +0,0 @@ | ||||
| /* | ||||
| Copyright 2014 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package record | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	k8sruntime "k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/strategicpatch" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	_ "k8s.io/kubernetes/pkg/api/install" // To register api.Pod used in tests below | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| ) | ||||
|  | ||||
| type testEventSink struct { | ||||
| 	OnCreate func(e *v1.Event) (*v1.Event, error) | ||||
| 	OnUpdate func(e *v1.Event) (*v1.Event, error) | ||||
| 	OnPatch  func(e *v1.Event, p []byte) (*v1.Event, error) | ||||
| } | ||||
|  | ||||
| // CreateEvent records the event for testing. | ||||
| func (t *testEventSink) Create(e *v1.Event) (*v1.Event, error) { | ||||
| 	if t.OnCreate != nil { | ||||
| 		return t.OnCreate(e) | ||||
| 	} | ||||
| 	return e, nil | ||||
| } | ||||
|  | ||||
| // UpdateEvent records the event for testing. | ||||
| func (t *testEventSink) Update(e *v1.Event) (*v1.Event, error) { | ||||
| 	if t.OnUpdate != nil { | ||||
| 		return t.OnUpdate(e) | ||||
| 	} | ||||
| 	return e, nil | ||||
| } | ||||
|  | ||||
| // PatchEvent records the event for testing. | ||||
| func (t *testEventSink) Patch(e *v1.Event, p []byte) (*v1.Event, error) { | ||||
| 	if t.OnPatch != nil { | ||||
| 		return t.OnPatch(e, p) | ||||
| 	} | ||||
| 	return e, nil | ||||
| } | ||||
|  | ||||
| type OnCreateFunc func(*v1.Event) (*v1.Event, error) | ||||
|  | ||||
| func OnCreateFactory(testCache map[string]*v1.Event, createEvent chan<- *v1.Event) OnCreateFunc { | ||||
| 	return func(event *v1.Event) (*v1.Event, error) { | ||||
| 		testCache[getEventKey(event)] = event | ||||
| 		createEvent <- event | ||||
| 		return event, nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type OnPatchFunc func(*v1.Event, []byte) (*v1.Event, error) | ||||
|  | ||||
| func OnPatchFactory(testCache map[string]*v1.Event, patchEvent chan<- *v1.Event) OnPatchFunc { | ||||
| 	return func(event *v1.Event, patch []byte) (*v1.Event, error) { | ||||
| 		cachedEvent, found := testCache[getEventKey(event)] | ||||
| 		if !found { | ||||
| 			return nil, fmt.Errorf("unexpected error: couldn't find Event in testCache.") | ||||
| 		} | ||||
| 		originalData, err := json.Marshal(cachedEvent) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("unexpected error: %v", err) | ||||
| 		} | ||||
| 		patched, err := strategicpatch.StrategicMergePatch(originalData, patch, event) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("unexpected error: %v", err) | ||||
| 		} | ||||
| 		patchedObj := &v1.Event{} | ||||
| 		err = json.Unmarshal(patched, patchedObj) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("unexpected error: %v", err) | ||||
| 		} | ||||
| 		patchEvent <- patchedObj | ||||
| 		return patchedObj, nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestEventf(t *testing.T) { | ||||
| 	testPod := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			SelfLink:  "/api/version/pods/foo", | ||||
| 			Name:      "foo", | ||||
| 			Namespace: "baz", | ||||
| 			UID:       "bar", | ||||
| 		}, | ||||
| 	} | ||||
| 	testPod2 := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			SelfLink:  "/api/version/pods/foo", | ||||
| 			Name:      "foo", | ||||
| 			Namespace: "baz", | ||||
| 			UID:       "differentUid", | ||||
| 		}, | ||||
| 	} | ||||
| 	testRef, err := v1.GetPartialReference(testPod, "spec.containers[2]") | ||||
| 	testRef2, err := v1.GetPartialReference(testPod2, "spec.containers[3]") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	table := []struct { | ||||
| 		obj          k8sruntime.Object | ||||
| 		eventtype    string | ||||
| 		reason       string | ||||
| 		messageFmt   string | ||||
| 		elements     []interface{} | ||||
| 		expect       *v1.Event | ||||
| 		expectLog    string | ||||
| 		expectUpdate bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testPod, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Killed", | ||||
| 			messageFmt: "some other verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 				}, | ||||
| 				Reason:  "Killed", | ||||
| 				Message: "some other verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   2, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   3, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Stopped", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Stopped", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Stopped", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Stopped", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   2, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	testCache := map[string]*v1.Event{} | ||||
| 	logCalled := make(chan struct{}) | ||||
| 	createEvent := make(chan *v1.Event) | ||||
| 	updateEvent := make(chan *v1.Event) | ||||
| 	patchEvent := make(chan *v1.Event) | ||||
| 	testEvents := testEventSink{ | ||||
| 		OnCreate: OnCreateFactory(testCache, createEvent), | ||||
| 		OnUpdate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			updateEvent <- event | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 		OnPatch: OnPatchFactory(testCache, patchEvent), | ||||
| 	} | ||||
| 	eventBroadcaster := NewBroadcasterForTests(0) | ||||
| 	sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) | ||||
|  | ||||
| 	clock := clock.NewFakeClock(time.Now()) | ||||
| 	recorder := recorderWithFakeClock(v1.EventSource{Component: "eventTest"}, eventBroadcaster, clock) | ||||
| 	for index, item := range table { | ||||
| 		clock.Step(1 * time.Second) | ||||
| 		logWatcher := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) { | ||||
| 			if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a { | ||||
| 				t.Errorf("Expected '%v', got '%v'", e, a) | ||||
| 			} | ||||
| 			logCalled <- struct{}{} | ||||
| 		}) | ||||
| 		recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...) | ||||
|  | ||||
| 		<-logCalled | ||||
|  | ||||
| 		// validate event | ||||
| 		if item.expectUpdate { | ||||
| 			actualEvent := <-patchEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} else { | ||||
| 			actualEvent := <-createEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} | ||||
| 		logWatcher.Stop() | ||||
| 	} | ||||
| 	sinkWatcher.Stop() | ||||
| } | ||||
|  | ||||
| func recorderWithFakeClock(eventSource v1.EventSource, eventBroadcaster EventBroadcaster, clock clock.Clock) EventRecorder { | ||||
| 	return &recorderImpl{eventSource, eventBroadcaster.(*eventBroadcasterImpl).Broadcaster, clock} | ||||
| } | ||||
|  | ||||
| func TestWriteEventError(t *testing.T) { | ||||
| 	type entry struct { | ||||
| 		timesToSendError int | ||||
| 		attemptsWanted   int | ||||
| 		err              error | ||||
| 	} | ||||
| 	table := map[string]*entry{ | ||||
| 		"giveUp1": { | ||||
| 			timesToSendError: 1000, | ||||
| 			attemptsWanted:   1, | ||||
| 			err:              &restclient.RequestConstructionError{}, | ||||
| 		}, | ||||
| 		"giveUp2": { | ||||
| 			timesToSendError: 1000, | ||||
| 			attemptsWanted:   1, | ||||
| 			err:              &errors.StatusError{}, | ||||
| 		}, | ||||
| 		"retry1": { | ||||
| 			timesToSendError: 1000, | ||||
| 			attemptsWanted:   12, | ||||
| 			err:              &errors.UnexpectedObjectError{}, | ||||
| 		}, | ||||
| 		"retry2": { | ||||
| 			timesToSendError: 1000, | ||||
| 			attemptsWanted:   12, | ||||
| 			err:              fmt.Errorf("A weird error"), | ||||
| 		}, | ||||
| 		"succeedEventually": { | ||||
| 			timesToSendError: 2, | ||||
| 			attemptsWanted:   2, | ||||
| 			err:              fmt.Errorf("A weird error"), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	eventCorrelator := NewEventCorrelator(clock.RealClock{}) | ||||
| 	randGen := rand.New(rand.NewSource(time.Now().UnixNano())) | ||||
|  | ||||
| 	for caseName, ent := range table { | ||||
| 		attempts := 0 | ||||
| 		sink := &testEventSink{ | ||||
| 			OnCreate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 				attempts++ | ||||
| 				if attempts < ent.timesToSendError { | ||||
| 					return nil, ent.err | ||||
| 				} | ||||
| 				return event, nil | ||||
| 			}, | ||||
| 		} | ||||
| 		ev := &v1.Event{} | ||||
| 		recordToSink(sink, ev, eventCorrelator, randGen, 0) | ||||
| 		if attempts != ent.attemptsWanted { | ||||
| 			t.Errorf("case %v: wanted %d, got %d attempts", caseName, ent.attemptsWanted, attempts) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestUpdateExpiredEvent(t *testing.T) { | ||||
| 	eventCorrelator := NewEventCorrelator(clock.RealClock{}) | ||||
| 	randGen := rand.New(rand.NewSource(time.Now().UnixNano())) | ||||
|  | ||||
| 	var createdEvent *v1.Event | ||||
|  | ||||
| 	sink := &testEventSink{ | ||||
| 		OnPatch: func(*v1.Event, []byte) (*v1.Event, error) { | ||||
| 			return nil, &errors.StatusError{ | ||||
| 				ErrStatus: metav1.Status{ | ||||
| 					Code:   http.StatusNotFound, | ||||
| 					Reason: metav1.StatusReasonNotFound, | ||||
| 				}} | ||||
| 		}, | ||||
| 		OnCreate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			createdEvent = event | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	ev := &v1.Event{} | ||||
| 	ev.ResourceVersion = "updated-resource-version" | ||||
| 	ev.Count = 2 | ||||
| 	recordToSink(sink, ev, eventCorrelator, randGen, 0) | ||||
|  | ||||
| 	if createdEvent == nil { | ||||
| 		t.Error("Event did not get created after patch failed") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if createdEvent.ResourceVersion != "" { | ||||
| 		t.Errorf("Event did not have its resource version cleared, was %s", createdEvent.ResourceVersion) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLotsOfEvents(t *testing.T) { | ||||
| 	recorderCalled := make(chan struct{}) | ||||
| 	loggerCalled := make(chan struct{}) | ||||
|  | ||||
| 	// Fail each event a few times to ensure there's some load on the tested code. | ||||
| 	var counts [1000]int | ||||
| 	testEvents := testEventSink{ | ||||
| 		OnCreate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			num, err := strconv.Atoi(event.Message) | ||||
| 			if err != nil { | ||||
| 				t.Error(err) | ||||
| 				return event, nil | ||||
| 			} | ||||
| 			counts[num]++ | ||||
| 			if counts[num] < 5 { | ||||
| 				return nil, fmt.Errorf("fake error") | ||||
| 			} | ||||
| 			recorderCalled <- struct{}{} | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	eventBroadcaster := NewBroadcasterForTests(0) | ||||
| 	sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) | ||||
| 	logWatcher := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) { | ||||
| 		loggerCalled <- struct{}{} | ||||
| 	}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "eventTest"}) | ||||
| 	ref := &v1.ObjectReference{ | ||||
| 		Kind:       "Pod", | ||||
| 		Name:       "foo", | ||||
| 		Namespace:  "baz", | ||||
| 		UID:        "bar", | ||||
| 		APIVersion: "version", | ||||
| 	} | ||||
| 	for i := 0; i < maxQueuedEvents; i++ { | ||||
| 		// we need to vary the reason to prevent aggregation | ||||
| 		go recorder.Eventf(ref, v1.EventTypeNormal, "Reason-"+string(i), strconv.Itoa(i)) | ||||
| 	} | ||||
| 	// Make sure no events were dropped by either of the listeners. | ||||
| 	for i := 0; i < maxQueuedEvents; i++ { | ||||
| 		<-recorderCalled | ||||
| 		<-loggerCalled | ||||
| 	} | ||||
| 	// Make sure that every event was attempted 5 times | ||||
| 	for i := 0; i < maxQueuedEvents; i++ { | ||||
| 		if counts[i] < 5 { | ||||
| 			t.Errorf("Only attempted to record event '%d' %d times.", i, counts[i]) | ||||
| 		} | ||||
| 	} | ||||
| 	sinkWatcher.Stop() | ||||
| 	logWatcher.Stop() | ||||
| } | ||||
|  | ||||
| func TestEventfNoNamespace(t *testing.T) { | ||||
| 	testPod := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			SelfLink: "/api/version/pods/foo", | ||||
| 			Name:     "foo", | ||||
| 			UID:      "bar", | ||||
| 		}, | ||||
| 	} | ||||
| 	testRef, err := v1.GetPartialReference(testPod, "spec.containers[2]") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	table := []struct { | ||||
| 		obj          k8sruntime.Object | ||||
| 		eventtype    string | ||||
| 		reason       string | ||||
| 		messageFmt   string | ||||
| 		elements     []interface{} | ||||
| 		expect       *v1.Event | ||||
| 		expectLog    string | ||||
| 		expectUpdate bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "default", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	testCache := map[string]*v1.Event{} | ||||
| 	logCalled := make(chan struct{}) | ||||
| 	createEvent := make(chan *v1.Event) | ||||
| 	updateEvent := make(chan *v1.Event) | ||||
| 	patchEvent := make(chan *v1.Event) | ||||
| 	testEvents := testEventSink{ | ||||
| 		OnCreate: OnCreateFactory(testCache, createEvent), | ||||
| 		OnUpdate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			updateEvent <- event | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 		OnPatch: OnPatchFactory(testCache, patchEvent), | ||||
| 	} | ||||
| 	eventBroadcaster := NewBroadcasterForTests(0) | ||||
| 	sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) | ||||
|  | ||||
| 	clock := clock.NewFakeClock(time.Now()) | ||||
| 	recorder := recorderWithFakeClock(v1.EventSource{Component: "eventTest"}, eventBroadcaster, clock) | ||||
|  | ||||
| 	for index, item := range table { | ||||
| 		clock.Step(1 * time.Second) | ||||
| 		logWatcher := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) { | ||||
| 			if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a { | ||||
| 				t.Errorf("Expected '%v', got '%v'", e, a) | ||||
| 			} | ||||
| 			logCalled <- struct{}{} | ||||
| 		}) | ||||
| 		recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...) | ||||
|  | ||||
| 		<-logCalled | ||||
|  | ||||
| 		// validate event | ||||
| 		if item.expectUpdate { | ||||
| 			actualEvent := <-patchEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} else { | ||||
| 			actualEvent := <-createEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} | ||||
|  | ||||
| 		logWatcher.Stop() | ||||
| 	} | ||||
| 	sinkWatcher.Stop() | ||||
| } | ||||
|  | ||||
| func TestMultiSinkCache(t *testing.T) { | ||||
| 	testPod := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			SelfLink:  "/api/version/pods/foo", | ||||
| 			Name:      "foo", | ||||
| 			Namespace: "baz", | ||||
| 			UID:       "bar", | ||||
| 		}, | ||||
| 	} | ||||
| 	testPod2 := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			SelfLink:  "/api/version/pods/foo", | ||||
| 			Name:      "foo", | ||||
| 			Namespace: "baz", | ||||
| 			UID:       "differentUid", | ||||
| 		}, | ||||
| 	} | ||||
| 	testRef, err := v1.GetPartialReference(testPod, "spec.containers[2]") | ||||
| 	testRef2, err := v1.GetPartialReference(testPod2, "spec.containers[3]") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	table := []struct { | ||||
| 		obj          k8sruntime.Object | ||||
| 		eventtype    string | ||||
| 		reason       string | ||||
| 		messageFmt   string | ||||
| 		elements     []interface{} | ||||
| 		expect       *v1.Event | ||||
| 		expectLog    string | ||||
| 		expectUpdate bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testPod, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Killed", | ||||
| 			messageFmt: "some other verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 				}, | ||||
| 				Reason:  "Killed", | ||||
| 				Message: "some other verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   2, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Started", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "bar", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[2]", | ||||
| 				}, | ||||
| 				Reason:  "Started", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   3, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Stopped", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Stopped", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   1, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`, | ||||
| 			expectUpdate: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			obj:        testRef2, | ||||
| 			eventtype:  v1.EventTypeNormal, | ||||
| 			reason:     "Stopped", | ||||
| 			messageFmt: "some verbose message: %v", | ||||
| 			elements:   []interface{}{1}, | ||||
| 			expect: &v1.Event{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:      "foo", | ||||
| 					Namespace: "baz", | ||||
| 				}, | ||||
| 				InvolvedObject: v1.ObjectReference{ | ||||
| 					Kind:       "Pod", | ||||
| 					Name:       "foo", | ||||
| 					Namespace:  "baz", | ||||
| 					UID:        "differentUid", | ||||
| 					APIVersion: "version", | ||||
| 					FieldPath:  "spec.containers[3]", | ||||
| 				}, | ||||
| 				Reason:  "Stopped", | ||||
| 				Message: "some verbose message: 1", | ||||
| 				Source:  v1.EventSource{Component: "eventTest"}, | ||||
| 				Count:   2, | ||||
| 				Type:    v1.EventTypeNormal, | ||||
| 			}, | ||||
| 			expectLog:    `Event(v1.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`, | ||||
| 			expectUpdate: true, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	testCache := map[string]*v1.Event{} | ||||
| 	createEvent := make(chan *v1.Event) | ||||
| 	updateEvent := make(chan *v1.Event) | ||||
| 	patchEvent := make(chan *v1.Event) | ||||
| 	testEvents := testEventSink{ | ||||
| 		OnCreate: OnCreateFactory(testCache, createEvent), | ||||
| 		OnUpdate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			updateEvent <- event | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 		OnPatch: OnPatchFactory(testCache, patchEvent), | ||||
| 	} | ||||
|  | ||||
| 	testCache2 := map[string]*v1.Event{} | ||||
| 	createEvent2 := make(chan *v1.Event) | ||||
| 	updateEvent2 := make(chan *v1.Event) | ||||
| 	patchEvent2 := make(chan *v1.Event) | ||||
| 	testEvents2 := testEventSink{ | ||||
| 		OnCreate: OnCreateFactory(testCache2, createEvent2), | ||||
| 		OnUpdate: func(event *v1.Event) (*v1.Event, error) { | ||||
| 			updateEvent2 <- event | ||||
| 			return event, nil | ||||
| 		}, | ||||
| 		OnPatch: OnPatchFactory(testCache2, patchEvent2), | ||||
| 	} | ||||
|  | ||||
| 	eventBroadcaster := NewBroadcasterForTests(0) | ||||
| 	clock := clock.NewFakeClock(time.Now()) | ||||
| 	recorder := recorderWithFakeClock(v1.EventSource{Component: "eventTest"}, eventBroadcaster, clock) | ||||
|  | ||||
| 	sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) | ||||
| 	for index, item := range table { | ||||
| 		clock.Step(1 * time.Second) | ||||
| 		recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...) | ||||
|  | ||||
| 		// validate event | ||||
| 		if item.expectUpdate { | ||||
| 			actualEvent := <-patchEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} else { | ||||
| 			actualEvent := <-createEvent | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Another StartRecordingToSink call should start to record events with new clean cache. | ||||
| 	sinkWatcher2 := eventBroadcaster.StartRecordingToSink(&testEvents2) | ||||
| 	for index, item := range table { | ||||
| 		clock.Step(1 * time.Second) | ||||
| 		recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...) | ||||
|  | ||||
| 		// validate event | ||||
| 		if item.expectUpdate { | ||||
| 			actualEvent := <-patchEvent2 | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} else { | ||||
| 			actualEvent := <-createEvent2 | ||||
| 			validateEvent(strconv.Itoa(index), actualEvent, item.expect, t) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	sinkWatcher.Stop() | ||||
| 	sinkWatcher2.Stop() | ||||
| } | ||||
| @@ -1,360 +0,0 @@ | ||||
| /* | ||||
| Copyright 2015 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package record | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/golang/groupcache/lru" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/util/strategicpatch" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	maxLruCacheEntries = 4096 | ||||
|  | ||||
| 	// if we see the same event that varies only by message | ||||
| 	// more than 10 times in a 10 minute period, aggregate the event | ||||
| 	defaultAggregateMaxEvents         = 10 | ||||
| 	defaultAggregateIntervalInSeconds = 600 | ||||
| ) | ||||
|  | ||||
| // getEventKey builds unique event key based on source, involvedObject, reason, message | ||||
| func getEventKey(event *v1.Event) string { | ||||
| 	return strings.Join([]string{ | ||||
| 		event.Source.Component, | ||||
| 		event.Source.Host, | ||||
| 		event.InvolvedObject.Kind, | ||||
| 		event.InvolvedObject.Namespace, | ||||
| 		event.InvolvedObject.Name, | ||||
| 		string(event.InvolvedObject.UID), | ||||
| 		event.InvolvedObject.APIVersion, | ||||
| 		event.Type, | ||||
| 		event.Reason, | ||||
| 		event.Message, | ||||
| 	}, | ||||
| 		"") | ||||
| } | ||||
|  | ||||
| // EventFilterFunc is a function that returns true if the event should be skipped | ||||
| type EventFilterFunc func(event *v1.Event) bool | ||||
|  | ||||
| // DefaultEventFilterFunc returns false for all incoming events | ||||
| func DefaultEventFilterFunc(event *v1.Event) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // EventAggregatorKeyFunc is responsible for grouping events for aggregation | ||||
| // It returns a tuple of the following: | ||||
| // aggregateKey - key the identifies the aggregate group to bucket this event | ||||
| // localKey - key that makes this event in the local group | ||||
| type EventAggregatorKeyFunc func(event *v1.Event) (aggregateKey string, localKey string) | ||||
|  | ||||
| // EventAggregatorByReasonFunc aggregates events by exact match on event.Source, event.InvolvedObject, event.Type and event.Reason | ||||
| func EventAggregatorByReasonFunc(event *v1.Event) (string, string) { | ||||
| 	return strings.Join([]string{ | ||||
| 		event.Source.Component, | ||||
| 		event.Source.Host, | ||||
| 		event.InvolvedObject.Kind, | ||||
| 		event.InvolvedObject.Namespace, | ||||
| 		event.InvolvedObject.Name, | ||||
| 		string(event.InvolvedObject.UID), | ||||
| 		event.InvolvedObject.APIVersion, | ||||
| 		event.Type, | ||||
| 		event.Reason, | ||||
| 	}, | ||||
| 		""), event.Message | ||||
| } | ||||
|  | ||||
| // EventAggregatorMessageFunc is responsible for producing an aggregation message | ||||
| type EventAggregatorMessageFunc func(event *v1.Event) string | ||||
|  | ||||
| // EventAggregratorByReasonMessageFunc returns an aggregate message by prefixing the incoming message | ||||
| func EventAggregatorByReasonMessageFunc(event *v1.Event) string { | ||||
| 	return "(events with common reason combined)" | ||||
| } | ||||
|  | ||||
| // EventAggregator identifies similar events and aggregates them into a single event | ||||
| type EventAggregator struct { | ||||
| 	sync.RWMutex | ||||
|  | ||||
| 	// The cache that manages aggregation state | ||||
| 	cache *lru.Cache | ||||
|  | ||||
| 	// The function that groups events for aggregation | ||||
| 	keyFunc EventAggregatorKeyFunc | ||||
|  | ||||
| 	// The function that generates a message for an aggregate event | ||||
| 	messageFunc EventAggregatorMessageFunc | ||||
|  | ||||
| 	// The maximum number of events in the specified interval before aggregation occurs | ||||
| 	maxEvents int | ||||
|  | ||||
| 	// The amount of time in seconds that must transpire since the last occurrence of a similar event before it's considered new | ||||
| 	maxIntervalInSeconds int | ||||
|  | ||||
| 	// clock is used to allow for testing over a time interval | ||||
| 	clock clock.Clock | ||||
| } | ||||
|  | ||||
| // NewEventAggregator returns a new instance of an EventAggregator | ||||
| func NewEventAggregator(lruCacheSize int, keyFunc EventAggregatorKeyFunc, messageFunc EventAggregatorMessageFunc, | ||||
| 	maxEvents int, maxIntervalInSeconds int, clock clock.Clock) *EventAggregator { | ||||
| 	return &EventAggregator{ | ||||
| 		cache:                lru.New(lruCacheSize), | ||||
| 		keyFunc:              keyFunc, | ||||
| 		messageFunc:          messageFunc, | ||||
| 		maxEvents:            maxEvents, | ||||
| 		maxIntervalInSeconds: maxIntervalInSeconds, | ||||
| 		clock:                clock, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // aggregateRecord holds data used to perform aggregation decisions | ||||
| type aggregateRecord struct { | ||||
| 	// we track the number of unique local keys we have seen in the aggregate set to know when to actually aggregate | ||||
| 	// if the size of this set exceeds the max, we know we need to aggregate | ||||
| 	localKeys sets.String | ||||
| 	// The last time at which the aggregate was recorded | ||||
| 	lastTimestamp metav1.Time | ||||
| } | ||||
|  | ||||
| // EventAggregate identifies similar events and groups into a common event if required | ||||
| func (e *EventAggregator) EventAggregate(newEvent *v1.Event) (*v1.Event, error) { | ||||
| 	aggregateKey, localKey := e.keyFunc(newEvent) | ||||
| 	now := metav1.NewTime(e.clock.Now()) | ||||
| 	record := aggregateRecord{localKeys: sets.NewString(), lastTimestamp: now} | ||||
| 	e.Lock() | ||||
| 	defer e.Unlock() | ||||
| 	value, found := e.cache.Get(aggregateKey) | ||||
| 	if found { | ||||
| 		record = value.(aggregateRecord) | ||||
| 	} | ||||
|  | ||||
| 	// if the last event was far enough in the past, it is not aggregated, and we must reset state | ||||
| 	maxInterval := time.Duration(e.maxIntervalInSeconds) * time.Second | ||||
| 	interval := now.Time.Sub(record.lastTimestamp.Time) | ||||
| 	if interval > maxInterval { | ||||
| 		record = aggregateRecord{localKeys: sets.NewString()} | ||||
| 	} | ||||
| 	record.localKeys.Insert(localKey) | ||||
| 	record.lastTimestamp = now | ||||
| 	e.cache.Add(aggregateKey, record) | ||||
|  | ||||
| 	if record.localKeys.Len() < e.maxEvents { | ||||
| 		return newEvent, nil | ||||
| 	} | ||||
|  | ||||
| 	// do not grow our local key set any larger than max | ||||
| 	record.localKeys.PopAny() | ||||
|  | ||||
| 	// create a new aggregate event | ||||
| 	eventCopy := &v1.Event{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      fmt.Sprintf("%v.%x", newEvent.InvolvedObject.Name, now.UnixNano()), | ||||
| 			Namespace: newEvent.Namespace, | ||||
| 		}, | ||||
| 		Count:          1, | ||||
| 		FirstTimestamp: now, | ||||
| 		InvolvedObject: newEvent.InvolvedObject, | ||||
| 		LastTimestamp:  now, | ||||
| 		Message:        e.messageFunc(newEvent), | ||||
| 		Type:           newEvent.Type, | ||||
| 		Reason:         newEvent.Reason, | ||||
| 		Source:         newEvent.Source, | ||||
| 	} | ||||
| 	return eventCopy, nil | ||||
| } | ||||
|  | ||||
| // eventLog records data about when an event was observed | ||||
| type eventLog struct { | ||||
| 	// The number of times the event has occurred since first occurrence. | ||||
| 	count int | ||||
|  | ||||
| 	// The time at which the event was first recorded. | ||||
| 	firstTimestamp metav1.Time | ||||
|  | ||||
| 	// The unique name of the first occurrence of this event | ||||
| 	name string | ||||
|  | ||||
| 	// Resource version returned from previous interaction with server | ||||
| 	resourceVersion string | ||||
| } | ||||
|  | ||||
| // eventLogger logs occurrences of an event | ||||
| type eventLogger struct { | ||||
| 	sync.RWMutex | ||||
| 	cache *lru.Cache | ||||
| 	clock clock.Clock | ||||
| } | ||||
|  | ||||
| // newEventLogger observes events and counts their frequencies | ||||
| func newEventLogger(lruCacheEntries int, clock clock.Clock) *eventLogger { | ||||
| 	return &eventLogger{cache: lru.New(lruCacheEntries), clock: clock} | ||||
| } | ||||
|  | ||||
| // eventObserve records the event, and determines if its frequency should update | ||||
| func (e *eventLogger) eventObserve(newEvent *v1.Event) (*v1.Event, []byte, error) { | ||||
| 	var ( | ||||
| 		patch []byte | ||||
| 		err   error | ||||
| 	) | ||||
| 	key := getEventKey(newEvent) | ||||
| 	eventCopy := *newEvent | ||||
| 	event := &eventCopy | ||||
|  | ||||
| 	e.Lock() | ||||
| 	defer e.Unlock() | ||||
|  | ||||
| 	lastObservation := e.lastEventObservationFromCache(key) | ||||
|  | ||||
| 	// we have seen this event before, so we must prepare a patch | ||||
| 	if lastObservation.count > 0 { | ||||
| 		// update the event based on the last observation so patch will work as desired | ||||
| 		event.Name = lastObservation.name | ||||
| 		event.ResourceVersion = lastObservation.resourceVersion | ||||
| 		event.FirstTimestamp = lastObservation.firstTimestamp | ||||
| 		event.Count = int32(lastObservation.count) + 1 | ||||
|  | ||||
| 		eventCopy2 := *event | ||||
| 		eventCopy2.Count = 0 | ||||
| 		eventCopy2.LastTimestamp = metav1.NewTime(time.Unix(0, 0)) | ||||
|  | ||||
| 		newData, _ := json.Marshal(event) | ||||
| 		oldData, _ := json.Marshal(eventCopy2) | ||||
| 		patch, err = strategicpatch.CreateTwoWayMergePatch(oldData, newData, event) | ||||
| 	} | ||||
|  | ||||
| 	// record our new observation | ||||
| 	e.cache.Add( | ||||
| 		key, | ||||
| 		eventLog{ | ||||
| 			count:           int(event.Count), | ||||
| 			firstTimestamp:  event.FirstTimestamp, | ||||
| 			name:            event.Name, | ||||
| 			resourceVersion: event.ResourceVersion, | ||||
| 		}, | ||||
| 	) | ||||
| 	return event, patch, err | ||||
| } | ||||
|  | ||||
| // updateState updates its internal tracking information based on latest server state | ||||
| func (e *eventLogger) updateState(event *v1.Event) { | ||||
| 	key := getEventKey(event) | ||||
| 	e.Lock() | ||||
| 	defer e.Unlock() | ||||
| 	// record our new observation | ||||
| 	e.cache.Add( | ||||
| 		key, | ||||
| 		eventLog{ | ||||
| 			count:           int(event.Count), | ||||
| 			firstTimestamp:  event.FirstTimestamp, | ||||
| 			name:            event.Name, | ||||
| 			resourceVersion: event.ResourceVersion, | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // lastEventObservationFromCache returns the event from the cache, reads must be protected via external lock | ||||
| func (e *eventLogger) lastEventObservationFromCache(key string) eventLog { | ||||
| 	value, ok := e.cache.Get(key) | ||||
| 	if ok { | ||||
| 		observationValue, ok := value.(eventLog) | ||||
| 		if ok { | ||||
| 			return observationValue | ||||
| 		} | ||||
| 	} | ||||
| 	return eventLog{} | ||||
| } | ||||
|  | ||||
| // EventCorrelator processes all incoming events and performs analysis to avoid overwhelming the system.  It can filter all | ||||
| // incoming events to see if the event should be filtered from further processing.  It can aggregate similar events that occur | ||||
| // frequently to protect the system from spamming events that are difficult for users to distinguish.  It performs de-duplication | ||||
| // to ensure events that are observed multiple times are compacted into a single event with increasing counts. | ||||
| type EventCorrelator struct { | ||||
| 	// the function to filter the event | ||||
| 	filterFunc EventFilterFunc | ||||
| 	// the object that performs event aggregation | ||||
| 	aggregator *EventAggregator | ||||
| 	// the object that observes events as they come through | ||||
| 	logger *eventLogger | ||||
| } | ||||
|  | ||||
| // EventCorrelateResult is the result of a Correlate | ||||
| type EventCorrelateResult struct { | ||||
| 	// the event after correlation | ||||
| 	Event *v1.Event | ||||
| 	// if provided, perform a strategic patch when updating the record on the server | ||||
| 	Patch []byte | ||||
| 	// if true, do no further processing of the event | ||||
| 	Skip bool | ||||
| } | ||||
|  | ||||
| // NewEventCorrelator returns an EventCorrelator configured with default values. | ||||
| // | ||||
| // The EventCorrelator is responsible for event filtering, aggregating, and counting | ||||
| // prior to interacting with the API server to record the event. | ||||
| // | ||||
| // The default behavior is as follows: | ||||
| //   * No events are filtered from being recorded | ||||
| //   * Aggregation is performed if a similar event is recorded 10 times in a | ||||
| //     in a 10 minute rolling interval.  A similar event is an event that varies only by | ||||
| //     the Event.Message field.  Rather than recording the precise event, aggregation | ||||
| //     will create a new event whose message reports that it has combined events with | ||||
| //     the same reason. | ||||
| //   * Events are incrementally counted if the exact same event is encountered multiple | ||||
| //     times. | ||||
| func NewEventCorrelator(clock clock.Clock) *EventCorrelator { | ||||
| 	cacheSize := maxLruCacheEntries | ||||
| 	return &EventCorrelator{ | ||||
| 		filterFunc: DefaultEventFilterFunc, | ||||
| 		aggregator: NewEventAggregator( | ||||
| 			cacheSize, | ||||
| 			EventAggregatorByReasonFunc, | ||||
| 			EventAggregatorByReasonMessageFunc, | ||||
| 			defaultAggregateMaxEvents, | ||||
| 			defaultAggregateIntervalInSeconds, | ||||
| 			clock), | ||||
| 		logger: newEventLogger(cacheSize, clock), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // EventCorrelate filters, aggregates, counts, and de-duplicates all incoming events | ||||
| func (c *EventCorrelator) EventCorrelate(newEvent *v1.Event) (*EventCorrelateResult, error) { | ||||
| 	if c.filterFunc(newEvent) { | ||||
| 		return &EventCorrelateResult{Skip: true}, nil | ||||
| 	} | ||||
| 	aggregateEvent, err := c.aggregator.EventAggregate(newEvent) | ||||
| 	if err != nil { | ||||
| 		return &EventCorrelateResult{}, err | ||||
| 	} | ||||
| 	observedEvent, patch, err := c.logger.eventObserve(aggregateEvent) | ||||
| 	return &EventCorrelateResult{Event: observedEvent, Patch: patch}, err | ||||
| } | ||||
|  | ||||
| // UpdateState based on the latest observed state from server | ||||
| func (c *EventCorrelator) UpdateState(event *v1.Event) { | ||||
| 	c.logger.updateState(event) | ||||
| } | ||||
| @@ -1,254 +0,0 @@ | ||||
| /* | ||||
| Copyright 2015 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package record | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/diff" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| ) | ||||
|  | ||||
| func makeObjectReference(kind, name, namespace string) v1.ObjectReference { | ||||
| 	return v1.ObjectReference{ | ||||
| 		Kind:       kind, | ||||
| 		Name:       name, | ||||
| 		Namespace:  namespace, | ||||
| 		UID:        "C934D34AFB20242", | ||||
| 		APIVersion: "version", | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func makeEvent(reason, message string, involvedObject v1.ObjectReference) v1.Event { | ||||
| 	eventTime := metav1.Now() | ||||
| 	event := v1.Event{ | ||||
| 		Reason:         reason, | ||||
| 		Message:        message, | ||||
| 		InvolvedObject: involvedObject, | ||||
| 		Source: v1.EventSource{ | ||||
| 			Component: "kubelet", | ||||
| 			Host:      "kublet.node1", | ||||
| 		}, | ||||
| 		Count:          1, | ||||
| 		FirstTimestamp: eventTime, | ||||
| 		LastTimestamp:  eventTime, | ||||
| 		Type:           v1.EventTypeNormal, | ||||
| 	} | ||||
| 	return event | ||||
| } | ||||
|  | ||||
| func makeEvents(num int, template v1.Event) []v1.Event { | ||||
| 	events := []v1.Event{} | ||||
| 	for i := 0; i < num; i++ { | ||||
| 		events = append(events, template) | ||||
| 	} | ||||
| 	return events | ||||
| } | ||||
|  | ||||
| func makeUniqueEvents(num int) []v1.Event { | ||||
| 	events := []v1.Event{} | ||||
| 	kind := "Pod" | ||||
| 	for i := 0; i < num; i++ { | ||||
| 		reason := strings.Join([]string{"reason", string(i)}, "-") | ||||
| 		message := strings.Join([]string{"message", string(i)}, "-") | ||||
| 		name := strings.Join([]string{"pod", string(i)}, "-") | ||||
| 		namespace := strings.Join([]string{"ns", string(i)}, "-") | ||||
| 		involvedObject := makeObjectReference(kind, name, namespace) | ||||
| 		events = append(events, makeEvent(reason, message, involvedObject)) | ||||
| 	} | ||||
| 	return events | ||||
| } | ||||
|  | ||||
| func makeSimilarEvents(num int, template v1.Event, messagePrefix string) []v1.Event { | ||||
| 	events := makeEvents(num, template) | ||||
| 	for i := range events { | ||||
| 		events[i].Message = strings.Join([]string{messagePrefix, string(i), events[i].Message}, "-") | ||||
| 	} | ||||
| 	return events | ||||
| } | ||||
|  | ||||
| func setCount(event v1.Event, count int) v1.Event { | ||||
| 	event.Count = int32(count) | ||||
| 	return event | ||||
| } | ||||
|  | ||||
| func validateEvent(messagePrefix string, actualEvent *v1.Event, expectedEvent *v1.Event, t *testing.T) (*v1.Event, error) { | ||||
| 	recvEvent := *actualEvent | ||||
| 	expectCompression := expectedEvent.Count > 1 | ||||
| 	t.Logf("%v - expectedEvent.Count is %d\n", messagePrefix, expectedEvent.Count) | ||||
| 	// Just check that the timestamp was set. | ||||
| 	if recvEvent.FirstTimestamp.IsZero() || recvEvent.LastTimestamp.IsZero() { | ||||
| 		t.Errorf("%v - timestamp wasn't set: %#v", messagePrefix, recvEvent) | ||||
| 	} | ||||
| 	actualFirstTimestamp := recvEvent.FirstTimestamp | ||||
| 	actualLastTimestamp := recvEvent.LastTimestamp | ||||
| 	if actualFirstTimestamp.Equal(actualLastTimestamp) { | ||||
| 		if expectCompression { | ||||
| 			t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent) | ||||
| 		} | ||||
| 	} else { | ||||
| 		if expectedEvent.Count == 1 { | ||||
| 			t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurrence of the event, but were different. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent) | ||||
| 		} | ||||
| 	} | ||||
| 	// Temp clear time stamps for comparison because actual values don't matter for comparison | ||||
| 	recvEvent.FirstTimestamp = expectedEvent.FirstTimestamp | ||||
| 	recvEvent.LastTimestamp = expectedEvent.LastTimestamp | ||||
| 	// Check that name has the right prefix. | ||||
| 	if n, en := recvEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) { | ||||
| 		t.Errorf("%v - Name '%v' does not contain prefix '%v'", messagePrefix, n, en) | ||||
| 	} | ||||
| 	recvEvent.Name = expectedEvent.Name | ||||
| 	if e, a := expectedEvent, &recvEvent; !reflect.DeepEqual(e, a) { | ||||
| 		t.Errorf("%v - diff: %s", messagePrefix, diff.ObjectGoPrintDiff(e, a)) | ||||
| 	} | ||||
| 	recvEvent.FirstTimestamp = actualFirstTimestamp | ||||
| 	recvEvent.LastTimestamp = actualLastTimestamp | ||||
| 	return actualEvent, nil | ||||
| } | ||||
|  | ||||
| // TestDefaultEventFilterFunc ensures that no events are filtered | ||||
| func TestDefaultEventFilterFunc(t *testing.T) { | ||||
| 	event := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other")) | ||||
| 	if DefaultEventFilterFunc(&event) { | ||||
| 		t.Fatalf("DefaultEventFilterFunc should always return false") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestEventAggregatorByReasonFunc ensures that two events are aggregated if they vary only by event.message | ||||
| func TestEventAggregatorByReasonFunc(t *testing.T) { | ||||
| 	event1 := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other")) | ||||
| 	event2 := makeEvent("end-of-world", "it was awful", makeObjectReference("Pod", "pod1", "other")) | ||||
| 	event3 := makeEvent("nevermind", "it was a bug", makeObjectReference("Pod", "pod1", "other")) | ||||
|  | ||||
| 	aggKey1, localKey1 := EventAggregatorByReasonFunc(&event1) | ||||
| 	aggKey2, localKey2 := EventAggregatorByReasonFunc(&event2) | ||||
| 	aggKey3, _ := EventAggregatorByReasonFunc(&event3) | ||||
|  | ||||
| 	if aggKey1 != aggKey2 { | ||||
| 		t.Errorf("Expected %v equal %v", aggKey1, aggKey2) | ||||
| 	} | ||||
| 	if localKey1 == localKey2 { | ||||
| 		t.Errorf("Expected %v to not equal %v", aggKey1, aggKey3) | ||||
| 	} | ||||
| 	if aggKey1 == aggKey3 { | ||||
| 		t.Errorf("Expected %v to not equal %v", aggKey1, aggKey3) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestEventAggregatorByReasonMessageFunc validates the proper output for an aggregate message | ||||
| func TestEventAggregatorByReasonMessageFunc(t *testing.T) { | ||||
| 	expected := "(events with common reason combined)" | ||||
| 	event1 := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other")) | ||||
| 	if actual := EventAggregatorByReasonMessageFunc(&event1); expected != actual { | ||||
| 		t.Errorf("Expected %v got %v", expected, actual) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestEventCorrelator validates proper counting, aggregation of events | ||||
| func TestEventCorrelator(t *testing.T) { | ||||
| 	firstEvent := makeEvent("first", "i am first", makeObjectReference("Pod", "my-pod", "my-ns")) | ||||
| 	duplicateEvent := makeEvent("duplicate", "me again", makeObjectReference("Pod", "my-pod", "my-ns")) | ||||
| 	uniqueEvent := makeEvent("unique", "snowflake", makeObjectReference("Pod", "my-pod", "my-ns")) | ||||
| 	similarEvent := makeEvent("similar", "similar message", makeObjectReference("Pod", "my-pod", "my-ns")) | ||||
| 	aggregateEvent := makeEvent(similarEvent.Reason, EventAggregatorByReasonMessageFunc(&similarEvent), similarEvent.InvolvedObject) | ||||
| 	scenario := map[string]struct { | ||||
| 		previousEvents  []v1.Event | ||||
| 		newEvent        v1.Event | ||||
| 		expectedEvent   v1.Event | ||||
| 		intervalSeconds int | ||||
| 	}{ | ||||
| 		"create-a-single-event": { | ||||
| 			previousEvents:  []v1.Event{}, | ||||
| 			newEvent:        firstEvent, | ||||
| 			expectedEvent:   setCount(firstEvent, 1), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"the-same-event-should-just-count": { | ||||
| 			previousEvents:  makeEvents(1, duplicateEvent), | ||||
| 			newEvent:        duplicateEvent, | ||||
| 			expectedEvent:   setCount(duplicateEvent, 2), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"the-same-event-should-just-count-even-if-more-than-aggregate": { | ||||
| 			previousEvents:  makeEvents(defaultAggregateMaxEvents, duplicateEvent), | ||||
| 			newEvent:        duplicateEvent, | ||||
| 			expectedEvent:   setCount(duplicateEvent, defaultAggregateMaxEvents+1), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"create-many-unique-events": { | ||||
| 			previousEvents:  makeUniqueEvents(30), | ||||
| 			newEvent:        uniqueEvent, | ||||
| 			expectedEvent:   setCount(uniqueEvent, 1), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"similar-events-should-aggregate-event": { | ||||
| 			previousEvents:  makeSimilarEvents(defaultAggregateMaxEvents-1, similarEvent, similarEvent.Message), | ||||
| 			newEvent:        similarEvent, | ||||
| 			expectedEvent:   setCount(aggregateEvent, 1), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"similar-events-many-times-should-count-the-aggregate": { | ||||
| 			previousEvents:  makeSimilarEvents(defaultAggregateMaxEvents, similarEvent, similarEvent.Message), | ||||
| 			newEvent:        similarEvent, | ||||
| 			expectedEvent:   setCount(aggregateEvent, 2), | ||||
| 			intervalSeconds: 5, | ||||
| 		}, | ||||
| 		"similar-events-whose-interval-is-greater-than-aggregate-interval-do-not-aggregate": { | ||||
| 			previousEvents:  makeSimilarEvents(defaultAggregateMaxEvents-1, similarEvent, similarEvent.Message), | ||||
| 			newEvent:        similarEvent, | ||||
| 			expectedEvent:   setCount(similarEvent, 1), | ||||
| 			intervalSeconds: defaultAggregateIntervalInSeconds, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for testScenario, testInput := range scenario { | ||||
| 		eventInterval := time.Duration(testInput.intervalSeconds) * time.Second | ||||
| 		clock := clock.IntervalClock{Time: time.Now(), Duration: eventInterval} | ||||
| 		correlator := NewEventCorrelator(&clock) | ||||
| 		for i := range testInput.previousEvents { | ||||
| 			event := testInput.previousEvents[i] | ||||
| 			now := metav1.NewTime(clock.Now()) | ||||
| 			event.FirstTimestamp = now | ||||
| 			event.LastTimestamp = now | ||||
| 			result, err := correlator.EventCorrelate(&event) | ||||
| 			if err != nil { | ||||
| 				t.Errorf("scenario %v: unexpected error playing back prevEvents %v", testScenario, err) | ||||
| 			} | ||||
| 			correlator.UpdateState(result.Event) | ||||
| 		} | ||||
|  | ||||
| 		// update the input to current clock value | ||||
| 		now := metav1.NewTime(clock.Now()) | ||||
| 		testInput.newEvent.FirstTimestamp = now | ||||
| 		testInput.newEvent.LastTimestamp = now | ||||
| 		result, err := correlator.EventCorrelate(&testInput.newEvent) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("scenario %v: unexpected error correlating input event %v", testScenario, err) | ||||
| 		} | ||||
|  | ||||
| 		_, err = validateEvent(testScenario, result.Event, &testInput.expectedEvent, t) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("scenario %v: unexpected error validating result %v", testScenario, err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1,54 +0,0 @@ | ||||
| /* | ||||
| Copyright 2015 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package record | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| ) | ||||
|  | ||||
| // FakeRecorder is used as a fake during tests. It is thread safe. It is usable | ||||
| // when created manually and not by NewFakeRecorder, however all events may be | ||||
| // thrown away in this case. | ||||
| type FakeRecorder struct { | ||||
| 	Events chan string | ||||
| } | ||||
|  | ||||
| func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { | ||||
| 	if f.Events != nil { | ||||
| 		f.Events <- fmt.Sprintf("%s %s %s", eventtype, reason, message) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { | ||||
| 	if f.Events != nil { | ||||
| 		f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f *FakeRecorder) PastEventf(object runtime.Object, timestamp metav1.Time, eventtype, reason, messageFmt string, args ...interface{}) { | ||||
| } | ||||
|  | ||||
| // NewFakeRecorder creates new fake event recorder with event channel with | ||||
| // buffer of given size. | ||||
| func NewFakeRecorder(bufferSize int) *FakeRecorder { | ||||
| 	return &FakeRecorder{ | ||||
| 		Events: make(chan string, bufferSize), | ||||
| 	} | ||||
| } | ||||
| @@ -25,7 +25,6 @@ go_library( | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/serviceaccount:go_default_library", | ||||
|         "//pkg/util/hash:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
| @@ -41,8 +40,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/apiserver/pkg/authentication/serviceaccount", | ||||
|         "//vendor:k8s.io/client-go/kubernetes", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|         "//vendor:k8s.io/client-go/util/integer", | ||||
|     ], | ||||
| @@ -58,7 +59,6 @@ go_test( | ||||
|         "//pkg/api/testapi:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/securitycontext:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/equality", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -67,6 +67,7 @@ go_test( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/uuid", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|         "//vendor:k8s.io/client-go/util/testing", | ||||
|     ], | ||||
|   | ||||
| @@ -22,9 +22,7 @@ go_library( | ||||
|         "//pkg/apis/certificates/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/certificates/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/cloudflare/cfssl/config", | ||||
|         "//vendor:github.com/cloudflare/cfssl/helpers", | ||||
| @@ -36,7 +34,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -25,13 +25,13 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	certificates "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -64,7 +64,7 @@ func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Du | ||||
| 	// Send events to the apiserver | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	s, err := NewCFSSLSigner(caCertFile, caKeyFile) | ||||
| 	if err != nil { | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount" | ||||
| 	clientgoclientset "k8s.io/client-go/kubernetes" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| @@ -43,6 +44,8 @@ type ControllerClientBuilder interface { | ||||
| 	ConfigOrDie(name string) *restclient.Config | ||||
| 	Client(name string) (clientset.Interface, error) | ||||
| 	ClientOrDie(name string) clientset.Interface | ||||
| 	ClientGoClient(name string) (clientgoclientset.Interface, error) | ||||
| 	ClientGoClientOrDie(name string) clientgoclientset.Interface | ||||
| } | ||||
|  | ||||
| // SimpleControllerClientBuilder returns a fixed client with different user agents | ||||
| @@ -80,6 +83,22 @@ func (b SimpleControllerClientBuilder) ClientOrDie(name string) clientset.Interf | ||||
| 	return client | ||||
| } | ||||
|  | ||||
| func (b SimpleControllerClientBuilder) ClientGoClient(name string) (clientgoclientset.Interface, error) { | ||||
| 	clientConfig, err := b.Config(name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return clientgoclientset.NewForConfig(clientConfig) | ||||
| } | ||||
|  | ||||
| func (b SimpleControllerClientBuilder) ClientGoClientOrDie(name string) clientgoclientset.Interface { | ||||
| 	client, err := b.ClientGoClient(name) | ||||
| 	if err != nil { | ||||
| 		glog.Fatal(err) | ||||
| 	} | ||||
| 	return client | ||||
| } | ||||
|  | ||||
| // SAControllerClientBuilder is a ControllerClientBuilder that returns clients identifying as | ||||
| // service accounts | ||||
| type SAControllerClientBuilder struct { | ||||
| @@ -184,3 +203,19 @@ func (b SAControllerClientBuilder) ClientOrDie(name string) clientset.Interface | ||||
| 	} | ||||
| 	return client | ||||
| } | ||||
|  | ||||
| func (b SAControllerClientBuilder) ClientGoClient(name string) (clientgoclientset.Interface, error) { | ||||
| 	clientConfig, err := b.Config(name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return clientgoclientset.NewForConfig(clientConfig) | ||||
| } | ||||
|  | ||||
| func (b SAControllerClientBuilder) ClientGoClientOrDie(name string) clientgoclientset.Interface { | ||||
| 	client, err := b.ClientGoClient(name) | ||||
| 	if err != nil { | ||||
| 		glog.Fatal(err) | ||||
| 	} | ||||
| 	return client | ||||
| } | ||||
|   | ||||
| @@ -13,10 +13,9 @@ go_library( | ||||
|     srcs = ["nodecontroller.go"], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
| @@ -24,6 +23,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -33,9 +35,9 @@ go_test( | ||||
|     library = ":go_default_library", | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/fake:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/cloudprovider/providers/fake:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
| @@ -44,6 +46,8 @@ go_test( | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -26,10 +26,12 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| ) | ||||
| @@ -63,11 +65,11 @@ func NewCloudNodeController( | ||||
| 	nodeMonitorPeriod time.Duration) (*CloudNodeController, error) { | ||||
|  | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "cloudcontrollermanager"}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "cloudcontrollermanager"}) | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	if kubeClient != nil { | ||||
| 		glog.V(0).Infof("Sending events to api server.") | ||||
| 		eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 		eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	} else { | ||||
| 		glog.V(0).Infof("No api server defined - no events will be sent to API server.") | ||||
| 	} | ||||
|   | ||||
| @@ -27,7 +27,9 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| @@ -105,7 +107,7 @@ func TestNodeDeleted(t *testing.T) { | ||||
| 		nodeInformer:      factory.Nodes(), | ||||
| 		cloud:             &fakecloud.FakeCloud{Err: cloudprovider.InstanceNotFound}, | ||||
| 		nodeMonitorPeriod: 5 * time.Second, | ||||
| 		recorder:          eventBroadcaster.NewRecorder(v1.EventSource{Component: "controllermanager"}), | ||||
| 		recorder:          eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "controllermanager"}), | ||||
| 	} | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/client-go/util/integer" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| @@ -38,7 +39,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/api/validation" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -424,7 +424,7 @@ func getPodsAnnotationSet(template *v1.PodTemplateSpec, object runtime.Object) ( | ||||
| 	for k, v := range template.Annotations { | ||||
| 		desiredAnnotations[k] = v | ||||
| 	} | ||||
| 	createdByRef, err := v1.GetReference(object) | ||||
| 	createdByRef, err := v1.GetReference(api.Scheme, object) | ||||
| 	if err != nil { | ||||
| 		return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -34,13 +34,13 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/uuid" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	utiltesting "k8s.io/client-go/util/testing" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/testapi" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/securitycontext" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -22,8 +22,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/batch/v2alpha1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:github.com/robfig/cron", | ||||
| @@ -36,6 +34,9 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -50,9 +51,9 @@ go_test( | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/batch/v2alpha1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -41,11 +41,13 @@ import ( | ||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	batch "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| ) | ||||
|  | ||||
| @@ -63,7 +65,7 @@ func NewCronJobController(kubeClient clientset.Interface) *CronJobController { | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	// TODO: remove the wrapper when every clients have moved to use the clientset. | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil { | ||||
| 		metrics.RegisterMetricAndTrackRateLimiterUsage("cronjob_controller", kubeClient.Core().RESTClient().GetRateLimiter()) | ||||
| @@ -74,7 +76,7 @@ func NewCronJobController(kubeClient clientset.Interface) *CronJobController { | ||||
| 		jobControl: realJobControl{KubeClient: kubeClient}, | ||||
| 		sjControl:  &realSJControl{KubeClient: kubeClient}, | ||||
| 		podControl: &realPodControl{KubeClient: kubeClient}, | ||||
| 		recorder:   eventBroadcaster.NewRecorder(v1.EventSource{Component: "cronjob-controller"}), | ||||
| 		recorder:   eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "cronjob-controller"}), | ||||
| 	} | ||||
|  | ||||
| 	return jm | ||||
| @@ -308,5 +310,5 @@ func SyncOne(sj batch.CronJob, js []batch.Job, now time.Time, jc jobControlInter | ||||
| } | ||||
|  | ||||
| func getRef(object runtime.Object) (*v1.ObjectReference, error) { | ||||
| 	return v1.GetReference(object) | ||||
| 	return v1.GetReference(api.Scheme, object) | ||||
| } | ||||
|   | ||||
| @@ -23,9 +23,9 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	batch "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| // schedule is hourly on the hour | ||||
|   | ||||
| @@ -22,10 +22,10 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/labels" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	batch "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| // sjControlInterface is an interface that knows how to update CronJob status | ||||
|   | ||||
| @@ -215,7 +215,7 @@ func getTimeHash(scheduledTime time.Time) int64 { | ||||
|  | ||||
| // makeCreatedByRefJson makes a json string with an object reference for use in "created-by" annotation value | ||||
| func makeCreatedByRefJson(object runtime.Object) (string, error) { | ||||
| 	createdByRef, err := v1.GetReference(object) | ||||
| 	createdByRef, err := v1.GetReference(api.Scheme, object) | ||||
| 	if err != nil { | ||||
| 		return "", fmt.Errorf("unable to get controller reference: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -20,10 +20,8 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
| @@ -35,7 +33,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
| @@ -60,6 +61,7 @@ go_test( | ||||
|         "//vendor:k8s.io/apiserver/pkg/storage/names", | ||||
|         "//vendor:k8s.io/client-go/testing", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,16 +28,17 @@ import ( | ||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	unversionedextensions "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -99,17 +100,17 @@ func NewDaemonSetsController(daemonSetInformer informers.DaemonSetInformer, podI | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	// TODO: remove the wrapper when every clients have moved to use the clientset. | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil { | ||||
| 		metrics.RegisterMetricAndTrackRateLimiterUsage("daemon_controller", kubeClient.Core().RESTClient().GetRateLimiter()) | ||||
| 	} | ||||
| 	dsc := &DaemonSetsController{ | ||||
| 		kubeClient:    kubeClient, | ||||
| 		eventRecorder: eventBroadcaster.NewRecorder(v1.EventSource{Component: "daemonset-controller"}), | ||||
| 		eventRecorder: eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "daemonset-controller"}), | ||||
| 		podControl: controller.RealPodControl{ | ||||
| 			KubeClient: kubeClient, | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(v1.EventSource{Component: "daemon-set"}), | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "daemon-set"}), | ||||
| 		}, | ||||
| 		burstReplicas: BurstReplicas, | ||||
| 		expectations:  controller.NewControllerExpectations(), | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/storage/names" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/testapi" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| @@ -151,6 +152,7 @@ func newTestController(initialObjects ...runtime.Object) (*DaemonSetsController, | ||||
| 	informerFactory := informers.NewSharedInformerFactory(clientset, nil, controller.NoResyncPeriodFunc()) | ||||
|  | ||||
| 	manager := NewDaemonSetsController(informerFactory.DaemonSets(), informerFactory.Pods(), informerFactory.Nodes(), clientset, 0) | ||||
| 	manager.eventRecorder = record.NewFakeRecorder(100) | ||||
|  | ||||
| 	manager.podStoreSynced = alwaysReady | ||||
| 	manager.nodeStoreSynced = alwaysReady | ||||
|   | ||||
| @@ -24,9 +24,7 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/deployment/util:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
| @@ -41,7 +39,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/integer", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| @@ -62,7 +63,6 @@ go_test( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/fake:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/deployment/util:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
| @@ -72,6 +72,7 @@ go_test( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/intstr", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/uuid", | ||||
|         "//vendor:k8s.io/client-go/testing", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -35,14 +35,16 @@ import ( | ||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/deployment/util" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| @@ -105,14 +107,14 @@ func NewDeploymentController(dInformer informers.DeploymentInformer, rsInformer | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	// TODO: remove the wrapper when every clients have moved to use the clientset. | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: client.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(client.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	if client != nil && client.Core().RESTClient().GetRateLimiter() != nil { | ||||
| 		metrics.RegisterMetricAndTrackRateLimiterUsage("deployment_controller", client.Core().RESTClient().GetRateLimiter()) | ||||
| 	} | ||||
| 	dc := &DeploymentController{ | ||||
| 		client:        client, | ||||
| 		eventRecorder: eventBroadcaster.NewRecorder(v1.EventSource{Component: "deployment-controller"}), | ||||
| 		eventRecorder: eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "deployment-controller"}), | ||||
| 		queue:         workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "deployment"), | ||||
| 		progressQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "progress-check"), | ||||
| 	} | ||||
|   | ||||
| @@ -27,11 +27,11 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| 	"k8s.io/apimachinery/pkg/util/uuid" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/deployment/util" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| @@ -69,6 +70,7 @@ func TestScaleDownOldReplicaSets(t *testing.T) { | ||||
| 		kc := fake.NewSimpleClientset(expected...) | ||||
| 		informers := informers.NewSharedInformerFactory(kc, nil, controller.NoResyncPeriodFunc()) | ||||
| 		c := NewDeploymentController(informers.Deployments(), informers.ReplicaSets(), informers.Pods(), kc) | ||||
| 		c.eventRecorder = &record.FakeRecorder{} | ||||
|  | ||||
| 		c.scaleDownOldReplicaSetsForRecreate(oldRSs, test.d) | ||||
| 		for j := range oldRSs { | ||||
|   | ||||
| @@ -21,9 +21,9 @@ import ( | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| func TestDeploymentController_reconcileNewReplicaSet(t *testing.T) { | ||||
|   | ||||
| @@ -23,9 +23,9 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| 	testclient "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
|   | ||||
| @@ -19,10 +19,8 @@ go_library( | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/apis/policy/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/policy/v1beta1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -32,7 +30,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
| @@ -49,12 +50,13 @@ go_test( | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/apis/policy/v1beta1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/intstr", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/uuid", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -28,7 +28,10 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| @@ -36,10 +39,8 @@ import ( | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	policy "k8s.io/kubernetes/pkg/apis/policy/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	policyclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/policy/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| @@ -115,7 +116,7 @@ func NewDisruptionController(podInformer cache.SharedIndexInformer, kubeClient c | ||||
| 		recheckQueue:  workqueue.NewNamedDelayingQueue("disruption-recheck"), | ||||
| 		broadcaster:   record.NewBroadcaster(), | ||||
| 	} | ||||
| 	dc.recorder = dc.broadcaster.NewRecorder(v1.EventSource{Component: "controllermanager"}) | ||||
| 	dc.recorder = dc.broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "controllermanager"}) | ||||
|  | ||||
| 	dc.getUpdater = func() updater { return dc.writePdbStatus } | ||||
|  | ||||
| @@ -319,7 +320,7 @@ func (dc *DisruptionController) Run(stopCh <-chan struct{}) { | ||||
| 	glog.V(0).Infof("Starting disruption controller") | ||||
| 	if dc.kubeClient != nil { | ||||
| 		glog.V(0).Infof("Sending events to api server.") | ||||
| 		dc.broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: dc.kubeClient.Core().Events("")}) | ||||
| 		dc.broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(dc.kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	} else { | ||||
| 		glog.V(0).Infof("No api server defined - no events will be sent to API server.") | ||||
| 	} | ||||
|   | ||||
| @@ -26,7 +26,9 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| 	"k8s.io/apimachinery/pkg/util/uuid" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| @@ -34,7 +36,6 @@ import ( | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	policy "k8s.io/kubernetes/pkg/apis/policy/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| ) | ||||
|  | ||||
| @@ -98,7 +99,7 @@ func newFakeDisruptionController() (*DisruptionController, *pdbStates) { | ||||
| 		broadcaster: record.NewBroadcaster(), | ||||
| 	} | ||||
|  | ||||
| 	dc.recorder = dc.broadcaster.NewRecorder(v1.EventSource{Component: "disruption_test"}) | ||||
| 	dc.recorder = dc.broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "disruption_test"}) | ||||
|  | ||||
| 	return dc, ps | ||||
| } | ||||
|   | ||||
| @@ -17,13 +17,12 @@ go_library( | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/batch/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/listers/batch/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
| @@ -32,7 +31,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -27,15 +27,17 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	batch "k8s.io/kubernetes/pkg/apis/batch/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	batchv1listers "k8s.io/kubernetes/pkg/client/listers/batch/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -76,7 +78,7 @@ func NewJobController(podInformer cache.SharedIndexInformer, jobInformer informe | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	// TODO: remove the wrapper when every clients have moved to use the clientset. | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil { | ||||
| 		metrics.RegisterMetricAndTrackRateLimiterUsage("job_controller", kubeClient.Core().RESTClient().GetRateLimiter()) | ||||
| @@ -86,11 +88,11 @@ func NewJobController(podInformer cache.SharedIndexInformer, jobInformer informe | ||||
| 		kubeClient: kubeClient, | ||||
| 		podControl: controller.RealPodControl{ | ||||
| 			KubeClient: kubeClient, | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(v1.EventSource{Component: "job-controller"}), | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "job-controller"}), | ||||
| 		}, | ||||
| 		expectations: controller.NewControllerExpectations(), | ||||
| 		queue:        workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "job"), | ||||
| 		recorder:     eventBroadcaster.NewRecorder(v1.EventSource{Component: "job-controller"}), | ||||
| 		recorder:     eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "job-controller"}), | ||||
| 	} | ||||
|  | ||||
| 	jobInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ | ||||
|   | ||||
| @@ -24,9 +24,7 @@ go_library( | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/kubelet/util/format:go_default_library", | ||||
| @@ -46,7 +44,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -26,9 +26,11 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
| @@ -75,7 +77,7 @@ type rangeAllocator struct { | ||||
| // can initialize its CIDR map. NodeList is only nil in testing. | ||||
| func NewCIDRRangeAllocator(client clientset.Interface, clusterCIDR *net.IPNet, serviceCIDR *net.IPNet, subNetMaskSize int, nodeList *v1.NodeList) (CIDRAllocator, error) { | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "cidrAllocator"}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "cidrAllocator"}) | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
|  | ||||
| 	ra := &rangeAllocator{ | ||||
|   | ||||
| @@ -27,11 +27,11 @@ import ( | ||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/kubelet/util/format" | ||||
| 	"k8s.io/kubernetes/pkg/util/node" | ||||
|   | ||||
| @@ -31,14 +31,15 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -186,11 +187,11 @@ func NewNodeController( | ||||
| 	nodeCIDRMaskSize int, | ||||
| 	allocateNodeCIDRs bool) (*NodeController, error) { | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "controllermanager"}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "controllermanager"}) | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	if kubeClient != nil { | ||||
| 		glog.V(0).Infof("Sending events to api server.") | ||||
| 		eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 		eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	} else { | ||||
| 		glog.V(0).Infof("No api server defined - no events will be sent to API server.") | ||||
| 	} | ||||
|   | ||||
| @@ -24,6 +24,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -29,6 +29,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| @@ -226,8 +227,8 @@ func (m *FakeNodeHandler) Patch(name string, pt types.PatchType, data []byte, su | ||||
|  | ||||
| // FakeRecorder is used as a fake during testing. | ||||
| type FakeRecorder struct { | ||||
| 	source v1.EventSource | ||||
| 	Events []*v1.Event | ||||
| 	source clientv1.EventSource | ||||
| 	Events []*clientv1.Event | ||||
| 	clock  clock.Clock | ||||
| } | ||||
|  | ||||
| @@ -246,7 +247,7 @@ func (f *FakeRecorder) PastEventf(obj runtime.Object, timestamp metav1.Time, eve | ||||
| } | ||||
|  | ||||
| func (f *FakeRecorder) generateEvent(obj runtime.Object, timestamp metav1.Time, eventtype, reason, message string) { | ||||
| 	ref, err := v1.GetReference(obj) | ||||
| 	ref, err := v1.GetReference(api.Scheme, obj) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| @@ -258,19 +259,30 @@ func (f *FakeRecorder) generateEvent(obj runtime.Object, timestamp metav1.Time, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f *FakeRecorder) makeEvent(ref *v1.ObjectReference, eventtype, reason, message string) *v1.Event { | ||||
| func (f *FakeRecorder) makeEvent(ref *v1.ObjectReference, eventtype, reason, message string) *clientv1.Event { | ||||
| 	fmt.Println("make event") | ||||
| 	t := metav1.Time{Time: f.clock.Now()} | ||||
| 	namespace := ref.Namespace | ||||
| 	if namespace == "" { | ||||
| 		namespace = metav1.NamespaceDefault | ||||
| 	} | ||||
| 	return &v1.Event{ | ||||
|  | ||||
| 	clientref := clientv1.ObjectReference{ | ||||
| 		Kind:            ref.Kind, | ||||
| 		Namespace:       ref.Namespace, | ||||
| 		Name:            ref.Name, | ||||
| 		UID:             ref.UID, | ||||
| 		APIVersion:      ref.APIVersion, | ||||
| 		ResourceVersion: ref.ResourceVersion, | ||||
| 		FieldPath:       ref.FieldPath, | ||||
| 	} | ||||
|  | ||||
| 	return &clientv1.Event{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()), | ||||
| 			Namespace: namespace, | ||||
| 		}, | ||||
| 		InvolvedObject: *ref, | ||||
| 		InvolvedObject: clientref, | ||||
| 		Reason:         reason, | ||||
| 		Message:        message, | ||||
| 		FirstTimestamp: t, | ||||
| @@ -283,8 +295,8 @@ func (f *FakeRecorder) makeEvent(ref *v1.ObjectReference, eventtype, reason, mes | ||||
| // NewFakeRecorder returns a pointer to a newly constructed FakeRecorder. | ||||
| func NewFakeRecorder() *FakeRecorder { | ||||
| 	return &FakeRecorder{ | ||||
| 		source: v1.EventSource{Component: "nodeControllerTest"}, | ||||
| 		Events: []*v1.Event{}, | ||||
| 		source: clientv1.EventSource{Component: "nodeControllerTest"}, | ||||
| 		Events: []*clientv1.Event{}, | ||||
| 		clock:  clock.NewFakeClock(time.Now()), | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -17,13 +17,13 @@ go_library( | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/autoscaling/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/autoscaling/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller/podautoscaler/metrics:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/resource", | ||||
| @@ -33,7 +33,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -46,13 +49,14 @@ go_test( | ||||
|     library = ":go_default_library", | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/unversioned:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/autoscaling/install:go_default_library", | ||||
|         "//pkg/apis/autoscaling/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/install:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/fake:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller/podautoscaler/metrics:go_default_library", | ||||
|         "//vendor:github.com/stretchr/testify/assert", | ||||
|         "//vendor:github.com/stretchr/testify/require", | ||||
| @@ -60,8 +64,12 @@ go_test( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/fake", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/testing", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/heapster/metrics/api/v1/types", | ||||
|         "//vendor:k8s.io/heapster/metrics/apis/metrics/v1alpha1", | ||||
|     ], | ||||
|   | ||||
| @@ -28,14 +28,16 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling/v1" | ||||
| 	extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/autoscaling/v1" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	unversionedextensions "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -112,7 +114,7 @@ func newInformer(controller *HorizontalController, resyncPeriod time.Duration) ( | ||||
| func NewHorizontalController(evtNamespacer v1core.EventsGetter, scaleNamespacer unversionedextensions.ScalesGetter, hpaNamespacer unversionedautoscaling.HorizontalPodAutoscalersGetter, replicaCalc *ReplicaCalculator, resyncPeriod time.Duration) *HorizontalController { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: evtNamespacer.Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(v1.EventSource{Component: "horizontal-pod-autoscaler"}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "horizontal-pod-autoscaler"}) | ||||
|  | ||||
| 	controller := &HorizontalController{ | ||||
| 		replicaCalc:     replicaCalc, | ||||
|   | ||||
| @@ -31,21 +31,27 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	clientfake "k8s.io/client-go/kubernetes/fake" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/unversioned" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	autoscaling "k8s.io/kubernetes/pkg/apis/autoscaling/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics" | ||||
|  | ||||
| 	heapster "k8s.io/heapster/metrics/api/v1/types" | ||||
| 	metricsapi "k8s.io/heapster/metrics/apis/metrics/v1alpha1" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	_ "k8s.io/kubernetes/pkg/apis/autoscaling/install" | ||||
| 	_ "k8s.io/kubernetes/pkg/apis/extensions/install" | ||||
| ) | ||||
|  | ||||
| func (w fakeResponseWrapper) DoRaw() ([]byte, error) { | ||||
| @@ -418,28 +424,6 @@ func (tc *testCase) prepareTestClient(t *testing.T) *fake.Clientset { | ||||
| 		return true, obj, nil | ||||
| 	}) | ||||
|  | ||||
| 	fakeClient.AddReactor("*", "events", func(action core.Action) (handled bool, ret runtime.Object, err error) { | ||||
| 		tc.Lock() | ||||
| 		defer tc.Unlock() | ||||
|  | ||||
| 		obj := action.(core.CreateAction).GetObject().(*v1.Event) | ||||
| 		if tc.verifyEvents { | ||||
| 			switch obj.Reason { | ||||
| 			case "SuccessfulRescale": | ||||
| 				assert.Equal(t, fmt.Sprintf("New size: %d; reason: CPU utilization above target", tc.desiredReplicas), obj.Message) | ||||
| 			case "DesiredReplicasComputed": | ||||
| 				assert.Equal(t, fmt.Sprintf( | ||||
| 					"Computed the desired num of replicas: %d (avgCPUutil: %d, current replicas: %d)", | ||||
| 					tc.desiredReplicas, | ||||
| 					(int64(tc.reportedLevels[0])*100)/tc.reportedCPURequests[0].MilliValue(), tc.initialReplicas), obj.Message) | ||||
| 			default: | ||||
| 				assert.False(t, true, fmt.Sprintf("Unexpected event: %s / %s", obj.Reason, obj.Message)) | ||||
| 			} | ||||
| 		} | ||||
| 		tc.eventCreated = true | ||||
| 		return true, obj, nil | ||||
| 	}) | ||||
|  | ||||
| 	fakeWatch := watch.NewFake() | ||||
| 	fakeClient.AddWatchReactor("*", core.DefaultWatchReactor(fakeWatch, nil)) | ||||
|  | ||||
| @@ -461,9 +445,32 @@ func (tc *testCase) runTest(t *testing.T) { | ||||
| 	testClient := tc.prepareTestClient(t) | ||||
| 	metricsClient := metrics.NewHeapsterMetricsClient(testClient, metrics.DefaultHeapsterNamespace, metrics.DefaultHeapsterScheme, metrics.DefaultHeapsterService, metrics.DefaultHeapsterPort) | ||||
|  | ||||
| 	eventClient := &clientfake.Clientset{} | ||||
| 	eventClient.AddReactor("*", "events", func(action core.Action) (handled bool, ret runtime.Object, err error) { | ||||
| 		tc.Lock() | ||||
| 		defer tc.Unlock() | ||||
|  | ||||
| 		obj := action.(core.CreateAction).GetObject().(*clientv1.Event) | ||||
| 		if tc.verifyEvents { | ||||
| 			switch obj.Reason { | ||||
| 			case "SuccessfulRescale": | ||||
| 				assert.Equal(t, fmt.Sprintf("New size: %d; reason: CPU utilization above target", tc.desiredReplicas), obj.Message) | ||||
| 			case "DesiredReplicasComputed": | ||||
| 				assert.Equal(t, fmt.Sprintf( | ||||
| 					"Computed the desired num of replicas: %d (avgCPUutil: %d, current replicas: %d)", | ||||
| 					tc.desiredReplicas, | ||||
| 					(int64(tc.reportedLevels[0])*100)/tc.reportedCPURequests[0].MilliValue(), tc.initialReplicas), obj.Message) | ||||
| 			default: | ||||
| 				assert.False(t, true, fmt.Sprintf("Unexpected event: %s / %s", obj.Reason, obj.Message)) | ||||
| 			} | ||||
| 		} | ||||
| 		tc.eventCreated = true | ||||
| 		return true, obj, nil | ||||
| 	}) | ||||
|  | ||||
| 	broadcaster := record.NewBroadcasterForTests(0) | ||||
| 	broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: testClient.Core().Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(v1.EventSource{Component: "horizontal-pod-autoscaler"}) | ||||
| 	broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: eventClient.Core().Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "horizontal-pod-autoscaler"}) | ||||
|  | ||||
| 	replicaCalc := &ReplicaCalculator{ | ||||
| 		metricsClient: metricsClient, | ||||
|   | ||||
| @@ -21,10 +21,8 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
| @@ -36,7 +34,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -33,15 +33,17 @@ import ( | ||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -100,13 +102,13 @@ func NewReplicaSetController(rsInformer informers.ReplicaSetInformer, podInforme | ||||
| 	} | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	rsc := &ReplicaSetController{ | ||||
| 		kubeClient: kubeClient, | ||||
| 		podControl: controller.RealPodControl{ | ||||
| 			KubeClient: kubeClient, | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(v1.EventSource{Component: "replicaset-controller"}), | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "replicaset-controller"}), | ||||
| 		}, | ||||
| 		burstReplicas: burstReplicas, | ||||
| 		expectations:  controller.NewUIDTrackingControllerExpectations(controller.NewControllerExpectations()), | ||||
|   | ||||
| @@ -17,11 +17,11 @@ go_library( | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
| @@ -34,7 +34,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apiserver/pkg/util/trace", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -33,13 +33,15 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	utiltrace "k8s.io/apiserver/pkg/util/trace" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -110,13 +112,13 @@ func NewReplicationManager(podInformer, rcInformer cache.SharedIndexInformer, ku | ||||
|  | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
|  | ||||
| 	rm := &ReplicationManager{ | ||||
| 		kubeClient: kubeClient, | ||||
| 		podControl: controller.RealPodControl{ | ||||
| 			KubeClient: kubeClient, | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(v1.EventSource{Component: "replication-controller"}), | ||||
| 			Recorder:   eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "replication-controller"}), | ||||
| 		}, | ||||
| 		burstReplicas: burstReplicas, | ||||
| 		expectations:  controller.NewUIDTrackingControllerExpectations(controller.NewControllerExpectations()), | ||||
|   | ||||
| @@ -16,11 +16,10 @@ go_library( | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
| @@ -32,7 +31,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
| @@ -49,6 +51,7 @@ go_test( | ||||
|         "//pkg/cloudprovider/providers/fake:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/types", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -32,13 +32,15 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| @@ -101,8 +103,8 @@ type ServiceController struct { | ||||
| // (like load balancers) in sync with the registry. | ||||
| func New(cloud cloudprovider.Interface, kubeClient clientset.Interface, clusterName string) (*ServiceController, error) { | ||||
| 	broadcaster := record.NewBroadcaster() | ||||
| 	broadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(v1.EventSource{Component: "service-controller"}) | ||||
| 	broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "service-controller"}) | ||||
|  | ||||
| 	if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil { | ||||
| 		metrics.RegisterMetricAndTrackRateLimiterUsage("service_controller", kubeClient.Core().RESTClient().GetRateLimiter()) | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/testapi" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" | ||||
| @@ -96,6 +97,7 @@ func TestCreateExternalLoadBalancer(t *testing.T) { | ||||
| 		cloud.Region = region | ||||
| 		client := &fake.Clientset{} | ||||
| 		controller, _ := New(cloud, client, "test-cluster") | ||||
| 		controller.eventRecorder = record.NewFakeRecorder(100) | ||||
| 		controller.init() | ||||
| 		cloud.Calls = nil     // ignore any cloud calls made in init() | ||||
| 		client.ClearActions() // ignore any client calls made in init() | ||||
| @@ -220,6 +222,7 @@ func TestUpdateNodesInExternalLoadBalancer(t *testing.T) { | ||||
| 		cloud.Region = region | ||||
| 		client := &fake.Clientset{} | ||||
| 		controller, _ := New(cloud, client, "test-cluster2") | ||||
| 		controller.eventRecorder = record.NewFakeRecorder(100) | ||||
| 		controller.init() | ||||
| 		cloud.Calls = nil // ignore any cloud calls made in init() | ||||
|  | ||||
|   | ||||
| @@ -20,14 +20,13 @@ go_library( | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/api/v1/pod:go_default_library", | ||||
|         "//pkg/apis/apps/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/apps/v1beta1:go_default_library", | ||||
|         "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:gopkg.in/inf.v0", | ||||
| @@ -41,7 +40,10 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/kubernetes/typed/core/v1", | ||||
|         "//vendor:k8s.io/client-go/pkg/api/v1", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/tools/record", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -26,10 +26,10 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	apipod "k8s.io/kubernetes/pkg/api/v1/pod" | ||||
| 	apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| ) | ||||
|  | ||||
| func dec(i int64, exponent int) *inf.Dec { | ||||
|   | ||||
| @@ -23,13 +23,15 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	v1core "k8s.io/client-go/kubernetes/typed/core/v1" | ||||
| 	clientv1 "k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/errors" | ||||
| @@ -87,8 +89,8 @@ type StatefulSetController struct { | ||||
| func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient clientset.Interface, resyncPeriod time.Duration) *StatefulSetController { | ||||
| 	eventBroadcaster := record.NewBroadcaster() | ||||
| 	eventBroadcaster.StartLogging(glog.Infof) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "statefulset"}) | ||||
| 	eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")}) | ||||
| 	recorder := eventBroadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "statefulset"}) | ||||
| 	pc := &apiServerPetClient{kubeClient, recorder, &defaultPetHealthChecker{}} | ||||
|  | ||||
| 	psc := &StatefulSetController{ | ||||
|   | ||||
| @@ -23,10 +23,10 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/client-go/tools/record" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 deads2k
					deads2k