Merge pull request #36673 from caesarxuchao/convert-to-versioned-API

Convert to use versioned api
This commit is contained in:
Saad Ali 2016-11-23 17:31:40 -08:00 committed by GitHub
commit 1dfd64f437
941 changed files with 23326 additions and 17977 deletions

View File

@ -253,7 +253,7 @@ func Run(s *options.ServerRunOptions) error {
if err != nil {
glog.Errorf("Failed to create clientset: %v", err)
}
sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute)
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
authorizationConfig := authorizer.AuthorizationConfig{
PolicyFile: s.GenericServerRunOptions.AuthorizationPolicyFile,

View File

@ -21,11 +21,12 @@ go_library(
"//cmd/kube-controller-manager/app/options:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apimachinery/registered:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/componentconfig:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/clientset_generated/release_1_5/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",

View File

@ -34,10 +34,11 @@ import (
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/batch"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/core/v1"
"k8s.io/kubernetes/pkg/client/leaderelection"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/client/record"
@ -159,8 +160,8 @@ func Run(s *options.CMServer) error {
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(glog.Infof)
eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")})
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "controller-manager"})
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")})
recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "controller-manager"})
run := func(stop <-chan struct{}) {
rootClientBuilder := controller.SimpleControllerClientBuilder{
@ -194,7 +195,7 @@ func Run(s *options.CMServer) error {
// TODO: enable other lock types
rl := resourcelock.EndpointsLock{
EndpointsMeta: api.ObjectMeta{
EndpointsMeta: v1.ObjectMeta{
Namespace: "kube-system",
Name: "kube-controller-manager",
},
@ -225,7 +226,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl
return rootClientBuilder.ClientOrDie(serviceAccountName)
}
discoveryClient := client("controller-discovery").Discovery()
sharedInformers := informers.NewSharedInformerFactory(client("shared-informers"), ResyncPeriod(s)())
sharedInformers := informers.NewSharedInformerFactory(client("shared-informers"), nil, ResyncPeriod(s)())
// always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
if len(s.ServiceAccountKeyFile) > 0 {
@ -392,7 +393,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl
return gvr, nil
}
}
namespaceController := namespacecontroller.NewNamespaceController(namespaceKubeClient, namespaceClientPool, gvrFn, s.NamespaceSyncPeriod.Duration, api.FinalizerKubernetes)
namespaceController := namespacecontroller.NewNamespaceController(namespaceKubeClient, namespaceClientPool, gvrFn, s.NamespaceSyncPeriod.Duration, v1.FinalizerKubernetes)
go namespaceController.Run(int(s.ConcurrentNamespaceSyncs), wait.NeverStop)
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))

View File

@ -17,7 +17,7 @@ go_library(
deps = [
"//cmd/kube-dns/app/options:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/dns:go_default_library",

View File

@ -30,7 +30,7 @@ import (
"k8s.io/kubernetes/cmd/kube-dns/app/options"
"k8s.io/kubernetes/pkg/api/unversioned"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/restclient"
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
kdns "k8s.io/kubernetes/pkg/dns"

View File

@ -20,6 +20,7 @@ go_library(
deps = [
"//cmd/kube-proxy/app/options:go_default_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",

View File

@ -30,6 +30,7 @@ import (
"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"
@ -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(api.EventSource{Component: "kube-proxy", Host: hostname})
recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "kube-proxy", Host: hostname})
var proxier proxy.ProxyProvider
var endpointsHandler proxyconfig.EndpointsConfigHandler
@ -468,7 +469,7 @@ func getNodeIP(client clientset.Interface, hostname string) net.IP {
glog.Warningf("Failed to retrieve node info: %v", err)
return nil
}
nodeIP, err = nodeutil.GetNodeHostIP(node)
nodeIP, err = nodeutil.InternalGetNodeHostIP(node)
if err != nil {
glog.Warningf("Failed to retrieve node IP: %v", err)
return nil

View File

@ -32,8 +32,8 @@ go_library(
"//pkg/api/resource:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/client/unversioned/clientcmd/api:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",

View File

@ -25,21 +25,23 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/images"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/api/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
"k8s.io/kubernetes/pkg/util/intstr"
)
func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
privilegedTrue := true
return api.PodSpec{
SecurityContext: &api.PodSecurityContext{HostNetwork: true},
Containers: []api.Container{{
return v1.PodSpec{
HostNetwork: true,
SecurityContext: &v1.PodSecurityContext{},
Containers: []v1.Container{{
Name: kubeProxy,
Image: images.GetCoreImage(images.KubeProxyImage, cfg, kubeadmapi.GlobalEnvParams.HyperkubeImage),
Command: append(getProxyCommand(cfg), "--kubeconfig=/run/kubeconfig"),
SecurityContext: &api.SecurityContext{Privileged: &privilegedTrue},
VolumeMounts: []api.VolumeMount{
SecurityContext: &v1.SecurityContext{Privileged: &privilegedTrue},
VolumeMounts: []v1.VolumeMount{
{
Name: "dbus",
MountPath: "/var/run/dbus",
@ -62,33 +64,33 @@ func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
},
},
}},
Volumes: []api.Volume{
Volumes: []v1.Volume{
{
Name: "kubeconfig",
VolumeSource: api.VolumeSource{
HostPath: &api.HostPathVolumeSource{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")},
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")},
},
},
{
Name: "dbus",
VolumeSource: api.VolumeSource{
HostPath: &api.HostPathVolumeSource{Path: "/var/run/dbus"},
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{Path: "/var/run/dbus"},
},
},
},
}
}
func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
dnsPodResources := api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("100m"),
api.ResourceName(api.ResourceMemory): resource.MustParse("170Mi"),
dnsPodResources := v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("100m"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("170Mi"),
}
healthzPodResources := api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10m"),
api.ResourceName(api.ResourceMemory): resource.MustParse("50Mi"),
healthzPodResources := v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("10m"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("50Mi"),
}
kubeDNSPort := int32(10053)
@ -101,13 +103,13 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
nslookup, kubeDNSPort,
)
return api.PodSpec{
Containers: []api.Container{
return v1.PodSpec{
Containers: []v1.Container{
// DNS server
{
Name: "kube-dns",
Image: images.GetAddonImage(images.KubeDNSImage),
Resources: api.ResourceRequirements{
Resources: v1.ResourceRequirements{
Limits: dnsPodResources,
Requests: dnsPodResources,
},
@ -116,12 +118,12 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
fmt.Sprintf("--dns-port=%d", kubeDNSPort),
// TODO __PILLAR__FEDERATIONS__DOMAIN__MAP__
},
LivenessProbe: &api.Probe{
Handler: api.Handler{
HTTPGet: &api.HTTPGetAction{
LivenessProbe: &v1.Probe{
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Path: "/healthz",
Port: intstr.FromInt(8080),
Scheme: api.URISchemeHTTP,
Scheme: v1.URISchemeHTTP,
},
},
InitialDelaySeconds: 60,
@ -131,27 +133,27 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
},
// # we poll on pod startup for the Kubernetes master service and
// # only setup the /readiness HTTP server once that's available.
ReadinessProbe: &api.Probe{
Handler: api.Handler{
HTTPGet: &api.HTTPGetAction{
ReadinessProbe: &v1.Probe{
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Path: "/readiness",
Port: intstr.FromInt(8081),
Scheme: api.URISchemeHTTP,
Scheme: v1.URISchemeHTTP,
},
},
InitialDelaySeconds: 30,
TimeoutSeconds: 5,
},
Ports: []api.ContainerPort{
Ports: []v1.ContainerPort{
{
ContainerPort: kubeDNSPort,
Name: "dns-local",
Protocol: api.ProtocolUDP,
Protocol: v1.ProtocolUDP,
},
{
ContainerPort: kubeDNSPort,
Name: "dns-tcp-local",
Protocol: api.ProtocolTCP,
Protocol: v1.ProtocolTCP,
},
},
},
@ -159,7 +161,7 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
{
Name: "dnsmasq",
Image: images.GetAddonImage(images.KubeDNSmasqImage),
Resources: api.ResourceRequirements{
Resources: v1.ResourceRequirements{
Limits: dnsPodResources,
Requests: dnsPodResources,
},
@ -168,16 +170,16 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
"--no-resolv",
fmt.Sprintf("--server=127.0.0.1#%d", kubeDNSPort),
},
Ports: []api.ContainerPort{
Ports: []v1.ContainerPort{
{
ContainerPort: dnsmasqPort,
Name: "dns",
Protocol: api.ProtocolUDP,
Protocol: v1.ProtocolUDP,
},
{
ContainerPort: dnsmasqPort,
Name: "dns-tcp",
Protocol: api.ProtocolTCP,
Protocol: v1.ProtocolTCP,
},
},
},
@ -185,7 +187,7 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
{
Name: "healthz",
Image: images.GetAddonImage(images.KubeExechealthzImage),
Resources: api.ResourceRequirements{
Resources: v1.ResourceRequirements{
Limits: healthzPodResources,
Requests: healthzPodResources,
},
@ -194,18 +196,18 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
"-port=8080",
"-quiet",
},
Ports: []api.ContainerPort{{
Ports: []v1.ContainerPort{{
ContainerPort: 8080,
Protocol: api.ProtocolTCP,
Protocol: v1.ProtocolTCP,
}},
},
},
DNSPolicy: api.DNSDefault,
DNSPolicy: v1.DNSDefault,
}
}
func createKubeDNSServiceSpec(cfg *kubeadmapi.MasterConfiguration) (*api.ServiceSpec, error) {
func createKubeDNSServiceSpec(cfg *kubeadmapi.MasterConfiguration) (*v1.ServiceSpec, error) {
_, n, err := net.ParseCIDR(cfg.Networking.ServiceSubnet)
if err != nil {
return nil, fmt.Errorf("could not parse %q: %v", cfg.Networking.ServiceSubnet, err)
@ -215,11 +217,11 @@ func createKubeDNSServiceSpec(cfg *kubeadmapi.MasterConfiguration) (*api.Service
return nil, fmt.Errorf("unable to allocate IP address for kube-dns addon from the given CIDR (%q) [%v]", cfg.Networking.ServiceSubnet, err)
}
svc := &api.ServiceSpec{
svc := &v1.ServiceSpec{
Selector: map[string]string{"name": "kube-dns"},
Ports: []api.ServicePort{
{Name: "dns", Port: 53, Protocol: api.ProtocolUDP},
{Name: "dns-tcp", Port: 53, Protocol: api.ProtocolTCP},
Ports: []v1.ServicePort{
{Name: "dns", Port: 53, Protocol: v1.ProtocolUDP},
{Name: "dns-tcp", Port: 53, Protocol: v1.ProtocolTCP},
},
ClusterIP: ip.String(),
}

View File

@ -26,8 +26,9 @@ import (
"k8s.io/kubernetes/pkg/api"
apierrs "k8s.io/kubernetes/pkg/api/errors"
unversionedapi "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/api/v1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/util/wait"
@ -55,7 +56,7 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
start := time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
cs, err := client.ComponentStatuses().List(api.ListOptions{})
cs, err := client.ComponentStatuses().List(v1.ListOptions{})
if err != nil {
return false, nil
}
@ -66,7 +67,7 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
}
for _, item := range cs.Items {
for _, condition := range item.Conditions {
if condition.Type != api.ComponentHealthy {
if condition.Type != v1.ComponentHealthy {
fmt.Printf("<master/apiclient> control plane component %q is still unhealthy: %#v\n", item.ObjectMeta.Name, item.Conditions)
return false, nil
}
@ -80,7 +81,7 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
fmt.Println("<master/apiclient> waiting for at least one node to register and become ready")
start = time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
nodeList, err := client.Nodes().List(api.ListOptions{})
nodeList, err := client.Nodes().List(v1.ListOptions{})
if err != nil {
fmt.Println("<master/apiclient> temporarily unable to list nodes (will retry)")
return false, nil
@ -89,7 +90,7 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
return false, nil
}
n := &nodeList.Items[0]
if !api.IsNodeReady(n) {
if !v1.IsNodeReady(n) {
fmt.Println("<master/apiclient> first node has registered, but is not ready yet")
return false, nil
}
@ -110,24 +111,24 @@ func standardLabels(n string) map[string]string {
}
}
func NewDaemonSet(daemonName string, podSpec api.PodSpec) *extensions.DaemonSet {
func NewDaemonSet(daemonName string, podSpec v1.PodSpec) *extensions.DaemonSet {
l := standardLabels(daemonName)
return &extensions.DaemonSet{
ObjectMeta: api.ObjectMeta{Name: daemonName},
ObjectMeta: v1.ObjectMeta{Name: daemonName},
Spec: extensions.DaemonSetSpec{
Selector: &unversionedapi.LabelSelector{MatchLabels: l},
Template: api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{Labels: l},
Template: v1.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{Labels: l},
Spec: podSpec,
},
},
}
}
func NewService(serviceName string, spec api.ServiceSpec) *api.Service {
func NewService(serviceName string, spec v1.ServiceSpec) *v1.Service {
l := standardLabels(serviceName)
return &api.Service{
ObjectMeta: api.ObjectMeta{
return &v1.Service{
ObjectMeta: v1.ObjectMeta{
Name: serviceName,
Labels: l,
},
@ -135,15 +136,15 @@ func NewService(serviceName string, spec api.ServiceSpec) *api.Service {
}
}
func NewDeployment(deploymentName string, replicas int32, podSpec api.PodSpec) *extensions.Deployment {
func NewDeployment(deploymentName string, replicas int32, podSpec v1.PodSpec) *extensions.Deployment {
l := standardLabels(deploymentName)
return &extensions.Deployment{
ObjectMeta: api.ObjectMeta{Name: deploymentName},
ObjectMeta: v1.ObjectMeta{Name: deploymentName},
Spec: extensions.DeploymentSpec{
Replicas: replicas,
Replicas: &replicas,
Selector: &unversionedapi.LabelSelector{MatchLabels: l},
Template: api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{Labels: l},
Template: v1.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{Labels: l},
Spec: podSpec,
},
},
@ -152,8 +153,8 @@ func NewDeployment(deploymentName string, replicas int32, podSpec api.PodSpec) *
// It's safe to do this for alpha, as we don't have HA and there is no way we can get
// more then one node here (TODO(phase1+) use os.Hostname)
func findMyself(client *clientset.Clientset) (*api.Node, error) {
nodeList, err := client.Nodes().List(api.ListOptions{})
func findMyself(client *clientset.Clientset) (*v1.Node, error) {
nodeList, err := client.Nodes().List(v1.ListOptions{})
if err != nil {
return nil, fmt.Errorf("unable to list nodes [%v]", err)
}
@ -173,8 +174,8 @@ func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, sched
n.ObjectMeta.Labels[unversionedapi.NodeLabelKubeadmAlphaRole] = unversionedapi.NodeLabelRoleMaster
if !schedulable {
taintsAnnotation, _ := json.Marshal([]api.Taint{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
n.ObjectMeta.Annotations[api.TaintsAnnotationKey] = string(taintsAnnotation)
taintsAnnotation, _ := json.Marshal([]v1.Taint{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
n.ObjectMeta.Annotations[v1.TaintsAnnotationKey] = string(taintsAnnotation)
}
if _, err := client.Nodes().Update(n); err != nil {
@ -199,50 +200,51 @@ func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, schedulable bo
return nil
}
func SetMasterTaintTolerations(meta *api.ObjectMeta) {
tolerationsAnnotation, _ := json.Marshal([]api.Toleration{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
func SetMasterTaintTolerations(meta *v1.ObjectMeta) {
tolerationsAnnotation, _ := json.Marshal([]v1.Toleration{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
if meta.Annotations == nil {
meta.Annotations = map[string]string{}
}
meta.Annotations[api.TolerationsAnnotationKey] = string(tolerationsAnnotation)
meta.Annotations[v1.TolerationsAnnotationKey] = string(tolerationsAnnotation)
}
// SetNodeAffinity is a basic helper to set meta.Annotations[api.AffinityAnnotationKey] for one or more api.NodeSelectorRequirement(s)
func SetNodeAffinity(meta *api.ObjectMeta, expr ...api.NodeSelectorRequirement) {
nodeAffinity := &api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{{MatchExpressions: expr}},
// SetNodeAffinity is a basic helper to set meta.Annotations[v1.AffinityAnnotationKey] for one or more v1.NodeSelectorRequirement(s)
func SetNodeAffinity(meta *v1.ObjectMeta, expr ...v1.NodeSelectorRequirement) {
nodeAffinity := &v1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
NodeSelectorTerms: []v1.NodeSelectorTerm{{MatchExpressions: expr}},
},
}
affinityAnnotation, _ := json.Marshal(api.Affinity{NodeAffinity: nodeAffinity})
affinityAnnotation, _ := json.Marshal(v1.Affinity{NodeAffinity: nodeAffinity})
if meta.Annotations == nil {
meta.Annotations = map[string]string{}
}
meta.Annotations[api.AffinityAnnotationKey] = string(affinityAnnotation)
meta.Annotations[v1.AffinityAnnotationKey] = string(affinityAnnotation)
}
// MasterNodeAffinity returns api.NodeSelectorRequirement to be used with SetNodeAffinity to set affinity to master node
func MasterNodeAffinity() api.NodeSelectorRequirement {
return api.NodeSelectorRequirement{
// MasterNodeAffinity returns v1.NodeSelectorRequirement to be used with SetNodeAffinity to set affinity to master node
func MasterNodeAffinity() v1.NodeSelectorRequirement {
return v1.NodeSelectorRequirement{
Key: unversionedapi.NodeLabelKubeadmAlphaRole,
Operator: api.NodeSelectorOpIn,
Operator: v1.NodeSelectorOpIn,
Values: []string{unversionedapi.NodeLabelRoleMaster},
}
}
// NativeArchitectureNodeAffinity returns api.NodeSelectorRequirement to be used with SetNodeAffinity to nodes with CPU architecture
// NativeArchitectureNodeAffinity returns v1.NodeSelectorRequirement to be used with SetNodeAffinity to nodes with CPU architecture
// the same as master node
func NativeArchitectureNodeAffinity() api.NodeSelectorRequirement {
return api.NodeSelectorRequirement{
Key: "beta.kubernetes.io/arch", Operator: api.NodeSelectorOpIn, Values: []string{runtime.GOARCH},
func NativeArchitectureNodeAffinity() v1.NodeSelectorRequirement {
return v1.NodeSelectorRequirement{
Key: "beta.kubernetes.io/arch", Operator: v1.NodeSelectorOpIn, Values: []string{runtime.GOARCH},
}
}
func createDummyDeployment(client *clientset.Clientset) {
fmt.Println("<master/apiclient> attempting a test deployment")
dummyDeployment := NewDeployment("dummy", 1, api.PodSpec{
SecurityContext: &api.PodSecurityContext{HostNetwork: true},
Containers: []api.Container{{
dummyDeployment := NewDeployment("dummy", 1, v1.PodSpec{
HostNetwork: true,
SecurityContext: &v1.PodSecurityContext{},
Containers: []v1.Container{{
Name: "dummy",
Image: images.GetAddonImage("pause"),
}},
@ -271,7 +273,7 @@ func createDummyDeployment(client *clientset.Clientset) {
fmt.Println("<master/apiclient> test deployment succeeded")
if err := client.Extensions().Deployments(api.NamespaceSystem).Delete("dummy", &api.DeleteOptions{}); err != nil {
if err := client.Extensions().Deployments(api.NamespaceSystem).Delete("dummy", &v1.DeleteOptions{}); err != nil {
fmt.Printf("<master/apiclient> failed to delete test deployment [%v] (will ignore)", err)
}
}

View File

@ -25,15 +25,16 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/api/v1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
certutil "k8s.io/kubernetes/pkg/util/cert"
"k8s.io/kubernetes/pkg/util/wait"
)
type kubeDiscovery struct {
Deployment *extensions.Deployment
Secret *api.Secret
Secret *v1.Secret
}
const (
@ -61,29 +62,30 @@ func encodeKubeDiscoverySecretData(cfg *kubeadmapi.MasterConfiguration, caCert *
return data
}
func newKubeDiscoveryPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
return api.PodSpec{
func newKubeDiscoveryPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
return v1.PodSpec{
// We have to use host network namespace, as `HostPort`/`HostIP` are Docker's
// buisness and CNI support isn't quite there yet (except for kubenet)
// (see https://github.com/kubernetes/kubernetes/issues/31307)
// TODO update this when #31307 is resolved
SecurityContext: &api.PodSecurityContext{HostNetwork: true},
Containers: []api.Container{{
HostNetwork: true,
SecurityContext: &v1.PodSecurityContext{},
Containers: []v1.Container{{
Name: kubeDiscoveryName,
Image: kubeadmapi.GlobalEnvParams.DiscoveryImage,
Command: []string{"/usr/local/bin/kube-discovery"},
VolumeMounts: []api.VolumeMount{{
VolumeMounts: []v1.VolumeMount{{
Name: kubeDiscoverySecretName,
MountPath: "/tmp/secret", // TODO use a shared constant
ReadOnly: true,
}},
Ports: []api.ContainerPort{
Ports: []v1.ContainerPort{
// TODO when CNI issue (#31307) is resolved, we should consider adding
// `HostIP: s.API.AdvertiseAddrs[0]`, if there is only one address`
{Name: "http", ContainerPort: kubeadmapiext.DefaultDiscoveryBindPort, HostPort: cfg.Discovery.BindPort},
},
SecurityContext: &api.SecurityContext{
SELinuxOptions: &api.SELinuxOptions{
SecurityContext: &v1.SecurityContext{
SELinuxOptions: &v1.SELinuxOptions{
// TODO: This implies our discovery container is not being restricted by
// SELinux. This is not optimal and would be nice to adjust in future
// so it can read /tmp/secret, but for now this avoids recommending
@ -92,10 +94,10 @@ func newKubeDiscoveryPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
},
},
}},
Volumes: []api.Volume{{
Volumes: []v1.Volume{{
Name: kubeDiscoverySecretName,
VolumeSource: api.VolumeSource{
Secret: &api.SecretVolumeSource{SecretName: kubeDiscoverySecretName},
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{SecretName: kubeDiscoverySecretName},
}},
},
}
@ -104,9 +106,9 @@ func newKubeDiscoveryPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
func newKubeDiscovery(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certificate) kubeDiscovery {
kd := kubeDiscovery{
Deployment: NewDeployment(kubeDiscoveryName, 1, newKubeDiscoveryPodSpec(cfg)),
Secret: &api.Secret{
ObjectMeta: api.ObjectMeta{Name: kubeDiscoverySecretName},
Type: api.SecretTypeOpaque,
Secret: &v1.Secret{
ObjectMeta: v1.ObjectMeta{Name: kubeDiscoverySecretName},
Type: v1.SecretTypeOpaque,
Data: encodeKubeDiscoverySecretData(cfg, caCert),
},
}

View File

@ -22,8 +22,8 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//pkg/apis/certificates:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/clientset_generated/release_1_5/typed/certificates/v1alpha1:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/client/unversioned/clientcmd/api:go_default_library",
"//pkg/kubelet/util/csr:go_default_library",

View File

@ -25,8 +25,8 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/apis/certificates"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
certclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
certclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/certificates/v1alpha1"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/wait"
@ -34,7 +34,7 @@ import (
// ConnectionDetails represents a master API endpoint connection
type ConnectionDetails struct {
CertClient *certclient.CertificatesClient
CertClient *certclient.CertificatesV1alpha1Client
Endpoint string
CACert []byte
NodeName types.NodeName
@ -82,7 +82,7 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub
// connection established, stop all wait threads
close(stopChan)
result <- &ConnectionDetails{
CertClient: clientSet.CertificatesClient,
CertClient: clientSet.CertificatesV1alpha1Client,
Endpoint: apiEndpoint,
CACert: caCert,
NodeName: nodeName,

View File

@ -23,6 +23,7 @@ go_library(
deps = [
"//cmd/kubelet/app/options:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/componentconfig:go_default_library",
"//pkg/apis/componentconfig/v1alpha1:go_default_library",
"//pkg/auth/authenticator:go_default_library",
@ -31,11 +32,11 @@ go_library(
"//pkg/auth/group:go_default_library",
"//pkg/capabilities:go_default_library",
"//pkg/client/chaosclient:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/authentication/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/authorization/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/clientset_generated/release_1_5/typed/authentication/v1beta1:go_default_library",
"//pkg/client/clientset_generated/release_1_5/typed/authorization/v1beta1:go_default_library",
"//pkg/client/clientset_generated/release_1_5/typed/certificates/v1alpha1:go_default_library",
"//pkg/client/clientset_generated/release_1_5/typed/core/v1:go_default_library",
"//pkg/client/record:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/unversioned/auth:go_default_library",

View File

@ -26,9 +26,9 @@ import (
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/group"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/internalversion"
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/internalversion"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authentication/v1beta1"
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authorization/v1beta1"
alwaysallowauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/pkg/kubelet/server"
"k8s.io/kubernetes/pkg/types"
@ -40,7 +40,7 @@ import (
webhooksar "k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook"
)
func buildAuth(nodeName types.NodeName, client internalclientset.Interface, config componentconfig.KubeletConfiguration) (server.AuthInterface, error) {
func buildAuth(nodeName types.NodeName, client clientset.Interface, config componentconfig.KubeletConfiguration) (server.AuthInterface, error) {
// Get clients, if provided
var (
tokenClient authenticationclient.TokenReviewInterface

View File

@ -25,7 +25,7 @@ import (
"github.com/golang/glog"
unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion"
unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/certificates/v1alpha1"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"

View File

@ -38,12 +38,13 @@ import (
"k8s.io/kubernetes/cmd/kubelet/app/options"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/componentconfig"
componentconfigv1alpha1 "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/client/chaosclient"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/core/v1"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/restclient"
clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth"
@ -170,7 +171,7 @@ func getRemoteKubeletConfig(s *options.KubeletServer, kubeDeps *kubelet.KubeletD
return "", err
}
configmap, err := func() (*api.ConfigMap, error) {
configmap, err := func() (*v1.ConfigMap, error) {
var nodename types.NodeName
hostname := nodeutil.GetHostname(s.HostnameOverride)
@ -186,14 +187,14 @@ func getRemoteKubeletConfig(s *options.KubeletServer, kubeDeps *kubelet.KubeletD
return nil, err
}
// look for kubelet-<node-name> configmap from "kube-system"
configmap, err := kubeClient.CoreClient.ConfigMaps("kube-system").Get(fmt.Sprintf("kubelet-%s", nodename))
configmap, err := kubeClient.CoreV1Client.ConfigMaps("kube-system").Get(fmt.Sprintf("kubelet-%s", nodename))
if err != nil {
return nil, err
}
return configmap, nil
}
// No cloud provider yet, so can't get the nodename via Cloud.Instances().CurrentNodeName(hostname), try just using the hostname
configmap, err := kubeClient.CoreClient.ConfigMaps("kube-system").Get(fmt.Sprintf("kubelet-%s", hostname))
configmap, err := kubeClient.CoreV1Client.ConfigMaps("kube-system").Get(fmt.Sprintf("kubelet-%s", hostname))
if err != nil {
return nil, fmt.Errorf("cloud provider was nil, and attempt to use hostname to find config resulted in: %v", err)
}
@ -660,11 +661,11 @@ func RunKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet
}
eventBroadcaster := record.NewBroadcaster()
kubeDeps.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: "kubelet", Host: string(nodeName)})
kubeDeps.Recorder = eventBroadcaster.NewRecorder(v1.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.")
eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeDeps.EventClient.Events("")})
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeDeps.EventClient.Events("")})
} else {
glog.Warning("No api server defined - no events will be sent to API server.")
}

View File

@ -15,8 +15,9 @@ go_binary(
srcs = ["hollow-node.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/metrics/prometheus:go_default_library",
"//pkg/client/record:go_default_library",
"//pkg/client/restclient:go_default_library",

View File

@ -19,8 +19,9 @@ package main
import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/restclient"
@ -96,10 +97,14 @@ func main() {
glog.Fatalf("Failed to create a ClientConfig: %v. Exiting.", err)
}
clientset, err := internalclientset.NewForConfig(clientConfig)
clientset, err := clientset.NewForConfig(clientConfig)
if err != nil {
glog.Fatalf("Failed to create a ClientSet: %v. Exiting.", err)
}
internalClientset, err := internalclientset.NewForConfig(clientConfig)
if err != nil {
glog.Fatalf("Failed to create an internal ClientSet: %v. Exiting.", err)
}
if config.Morph == "kubelet" {
cadvisorInterface := new(cadvisortest.Fake)
@ -124,7 +129,7 @@ func main() {
if config.Morph == "proxy" {
eventBroadcaster := record.NewBroadcaster()
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "kube-proxy", Host: config.NodeName})
recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "kube-proxy", Host: config.NodeName})
iptInterface := fakeiptables.NewFake()
@ -134,7 +139,7 @@ func main() {
endpointsConfig := proxyconfig.NewEndpointsConfig()
endpointsConfig.RegisterHandler(&kubemark.FakeProxyHandler{})
hollowProxy := kubemark.NewHollowProxyOrDie(config.NodeName, clientset, endpointsConfig, serviceConfig, iptInterface, eventBroadcaster, recorder)
hollowProxy := kubemark.NewHollowProxyOrDie(config.NodeName, internalClientset, endpointsConfig, serviceConfig, iptInterface, eventBroadcaster, recorder)
hollowProxy.Run()
}
}

View File

@ -143,7 +143,7 @@ func Run(s *options.ServerRunOptions) error {
if err != nil {
glog.Errorf("Failed to create clientset: %v", err)
}
sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute)
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
authorizationConfig := authorizer.AuthorizationConfig{
PolicyFile: s.GenericServerRunOptions.AuthorizationPolicyFile,

View File

@ -24,8 +24,6 @@ import (
federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
cluster_cache "k8s.io/kubernetes/federation/client/cache"
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/controller"
@ -66,13 +64,11 @@ func NewclusterController(federationClient federationclientset.Interface, cluste
}
cc.clusterStore.Store, cc.clusterController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return cc.federationClient.Federation().Clusters().List(versionedOptions)
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return cc.federationClient.Federation().Clusters().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return cc.federationClient.Federation().Clusters().Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return cc.federationClient.Federation().Clusters().Watch(options)
},
},
&federation_v1beta1.Cluster{},

View File

@ -79,7 +79,7 @@ type ConfigMapController struct {
func NewConfigMapController(client federationclientset.Interface) *ConfigMapController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-configmaps-controller"})
recorder := broadcaster.NewRecorder(api_v1.EventSource{Component: "federated-configmaps-controller"})
configmapcontroller := &ConfigMapController{
federatedApiClient: client,
@ -98,13 +98,11 @@ func NewConfigMapController(client federationclientset.Interface) *ConfigMapCont
// Start informer on federated API servers on configmaps that should be federated.
configmapcontroller.configmapInformerStore, configmapcontroller.configmapInformerController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().ConfigMaps(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return client.Core().ConfigMaps(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().ConfigMaps(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return client.Core().ConfigMaps(api_v1.NamespaceAll).Watch(options)
},
},
&api_v1.ConfigMap{},
@ -117,13 +115,11 @@ func NewConfigMapController(client federationclientset.Interface) *ConfigMapCont
func(cluster *federation_api.Cluster, targetClient kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().ConfigMaps(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return targetClient.Core().ConfigMaps(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().ConfigMaps(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return targetClient.Core().ConfigMaps(api_v1.NamespaceAll).Watch(options)
},
},
&api_v1.ConfigMap{},

View File

@ -87,7 +87,7 @@ type DaemonSetController struct {
func NewDaemonSetController(client federationclientset.Interface) *DaemonSetController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-daemonset-controller"})
recorder := broadcaster.NewRecorder(api_v1.EventSource{Component: "federated-daemonset-controller"})
daemonsetcontroller := &DaemonSetController{
federatedApiClient: client,
@ -106,13 +106,11 @@ func NewDaemonSetController(client federationclientset.Interface) *DaemonSetCont
// Start informer in federated API servers on daemonsets that should be federated.
daemonsetcontroller.daemonsetInformerStore, daemonsetcontroller.daemonsetInformerController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Extensions().DaemonSets(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return client.Extensions().DaemonSets(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Extensions().DaemonSets(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return client.Extensions().DaemonSets(api_v1.NamespaceAll).Watch(options)
},
},
&extensionsv1.DaemonSet{},
@ -125,13 +123,11 @@ func NewDaemonSetController(client federationclientset.Interface) *DaemonSetCont
func(cluster *federation_api.Cluster, targetClient kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Extensions().DaemonSets(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return targetClient.Extensions().DaemonSets(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Extensions().DaemonSets(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return targetClient.Extensions().DaemonSets(api_v1.NamespaceAll).Watch(options)
},
},
&extensionsv1.DaemonSet{},

View File

@ -104,7 +104,7 @@ type DeploymentController struct {
func NewDeploymentController(federationClient fedclientset.Interface) *DeploymentController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(federationClient))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-deployment-controller"})
recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-deployment-controller"})
fdc := &DeploymentController{
fedClient: federationClient,
@ -123,13 +123,11 @@ func NewDeploymentController(federationClient fedclientset.Interface) *Deploymen
deploymentFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Extensions().Deployments(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return clientset.Extensions().Deployments(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Extensions().Deployments(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return clientset.Extensions().Deployments(apiv1.NamespaceAll).Watch(options)
},
},
&extensionsv1.Deployment{},
@ -152,13 +150,11 @@ func NewDeploymentController(federationClient fedclientset.Interface) *Deploymen
podFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Core().Pods(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return clientset.Core().Pods(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Core().Pods(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return clientset.Core().Pods(apiv1.NamespaceAll).Watch(options)
},
},
&apiv1.Pod{},
@ -174,13 +170,11 @@ func NewDeploymentController(federationClient fedclientset.Interface) *Deploymen
fdc.deploymentStore, fdc.deploymentController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return fdc.fedClient.Extensions().Deployments(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return fdc.fedClient.Extensions().Deployments(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return fdc.fedClient.Extensions().Deployments(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return fdc.fedClient.Extensions().Deployments(apiv1.NamespaceAll).Watch(options)
},
},
&extensionsv1.Deployment{},

View File

@ -108,7 +108,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(api.EventSource{Component: "federated-ingress-controller"})
recorder := broadcaster.NewRecorder(v1.EventSource{Component: "federated-ingress-controller"})
ic := &IngressController{
federatedApiClient: client,
ingressReviewDelay: time.Second * 10,
@ -129,13 +129,11 @@ func NewIngressController(client federationclientset.Interface) *IngressControll
// Start informer in federated API servers on ingresses that should be federated.
ic.ingressInformerStore, ic.ingressInformerController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Extensions().Ingresses(api.NamespaceAll).List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return client.Extensions().Ingresses(api.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Extensions().Ingresses(api.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return client.Extensions().Ingresses(api.NamespaceAll).Watch(options)
},
},
&extensions_v1beta1.Ingress{},
@ -152,13 +150,11 @@ func NewIngressController(client federationclientset.Interface) *IngressControll
func(cluster *federation_api.Cluster, targetClient kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Extensions().Ingresses(api.NamespaceAll).List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return targetClient.Extensions().Ingresses(api.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Extensions().Ingresses(api.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return targetClient.Extensions().Ingresses(api.NamespaceAll).Watch(options)
},
},
&extensions_v1beta1.Ingress{},
@ -187,19 +183,17 @@ func NewIngressController(client federationclientset.Interface) *IngressControll
glog.V(4).Infof("Returning new informer for cluster %q", cluster.Name)
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
if targetClient == nil {
glog.Errorf("Internal error: targetClient is nil")
}
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().ConfigMaps(uidConfigMapNamespace).List(versionedOptions) // we only want to list one by name - unfortunately Kubernetes don't have a selector for that.
return targetClient.Core().ConfigMaps(uidConfigMapNamespace).List(options) // we only want to list one by name - unfortunately Kubernetes don't have a selector for that.
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if targetClient == nil {
glog.Errorf("Internal error: targetClient is nil")
}
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().ConfigMaps(uidConfigMapNamespace).Watch(versionedOptions) // as above
return targetClient.Core().ConfigMaps(uidConfigMapNamespace).Watch(options) // as above
},
},
&v1.ConfigMap{},

View File

@ -84,7 +84,7 @@ type NamespaceController struct {
func NewNamespaceController(client federationclientset.Interface) *NamespaceController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-namespace-controller"})
recorder := broadcaster.NewRecorder(api_v1.EventSource{Component: "federated-namespace-controller"})
nc := &NamespaceController{
federatedApiClient: client,
@ -103,13 +103,11 @@ func NewNamespaceController(client federationclientset.Interface) *NamespaceCont
// Start informer in federated API servers on namespaces that should be federated.
nc.namespaceInformerStore, nc.namespaceInformerController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().Namespaces().List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (runtime.Object, error) {
return client.Core().Namespaces().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().Namespaces().Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return client.Core().Namespaces().Watch(options)
},
},
&api_v1.Namespace{},
@ -122,13 +120,11 @@ func NewNamespaceController(client federationclientset.Interface) *NamespaceCont
func(cluster *federation_api.Cluster, targetClient kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().Namespaces().List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (runtime.Object, error) {
return targetClient.Core().Namespaces().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().Namespaces().Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return targetClient.Core().Namespaces().Watch(options)
},
},
&api_v1.Namespace{},

View File

@ -106,7 +106,7 @@ type ReplicaSetController struct {
func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSetController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(federationClient))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-replicaset-controller"})
recorder := broadcaster.NewRecorder(apiv1.EventSource{Component: "federated-replicaset-controller"})
frsc := &ReplicaSetController{
fedClient: federationClient,
@ -125,13 +125,11 @@ func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSe
replicaSetFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(options)
},
},
&extensionsv1.ReplicaSet{},
@ -154,13 +152,11 @@ func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSe
podFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Core().Pods(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return clientset.Core().Pods(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return clientset.Core().Pods(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return clientset.Core().Pods(apiv1.NamespaceAll).Watch(options)
},
},
&apiv1.Pod{},
@ -176,13 +172,11 @@ func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSe
frsc.replicaSetStore.Indexer, frsc.replicaSetController = cache.NewIndexerInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).List(versionedOptions)
ListFunc: func(options apiv1.ListOptions) (runtime.Object, error) {
return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := fedutil.VersionizeV1ListOptions(options)
return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options apiv1.ListOptions) (watch.Interface, error) {
return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(options)
},
},
&extensionsv1.ReplicaSet{},

View File

@ -85,7 +85,7 @@ type SecretController struct {
func NewSecretController(client federationclientset.Interface) *SecretController {
broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-secrets-controller"})
recorder := broadcaster.NewRecorder(api_v1.EventSource{Component: "federated-secrets-controller"})
secretcontroller := &SecretController{
federatedApiClient: client,
@ -104,13 +104,11 @@ func NewSecretController(client federationclientset.Interface) *SecretController
// Start informer in federated API servers on secrets that should be federated.
secretcontroller.secretInformerStore, secretcontroller.secretInformerController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().Secrets(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return client.Core().Secrets(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return client.Core().Secrets(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return client.Core().Secrets(api_v1.NamespaceAll).Watch(options)
},
},
&api_v1.Secret{},
@ -123,13 +121,11 @@ func NewSecretController(client federationclientset.Interface) *SecretController
func(cluster *federation_api.Cluster, targetClient kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().Secrets(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return targetClient.Core().Secrets(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return targetClient.Core().Secrets(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return targetClient.Core().Secrets(api_v1.NamespaceAll).Watch(options)
},
},
&api_v1.Secret{},

View File

@ -28,7 +28,6 @@ go_library(
"//federation/pkg/dnsprovider:go_default_library",
"//federation/pkg/dnsprovider/rrstype:go_default_library",
"//federation/pkg/federation-controller/util:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/errors:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/cache:go_default_library",

View File

@ -20,7 +20,6 @@ import (
"sync"
v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
"k8s.io/kubernetes/pkg/api"
v1 "k8s.io/kubernetes/pkg/api/v1"
cache "k8s.io/kubernetes/pkg/client/cache"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
@ -92,13 +91,11 @@ func (cc *clusterClientCache) startClusterLW(cluster *v1beta1.Cluster, clusterNa
}
cachedClusterClient.endpointStore.Store, cachedClusterClient.endpointController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return clientset.Core().Endpoints(v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return clientset.Core().Endpoints(v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return clientset.Core().Endpoints(v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return clientset.Core().Endpoints(v1.NamespaceAll).Watch(options)
},
},
&v1.Endpoints{},
@ -118,13 +115,11 @@ func (cc *clusterClientCache) startClusterLW(cluster *v1beta1.Cluster, clusterNa
cachedClusterClient.serviceStore.Indexer, cachedClusterClient.serviceController = cache.NewIndexerInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return clientset.Core().Services(v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return clientset.Core().Services(v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return clientset.Core().Services(v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return clientset.Core().Services(v1.NamespaceAll).Watch(options)
},
},
&v1.Service{},

View File

@ -22,9 +22,10 @@ import (
"github.com/golang/glog"
"strings"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
"k8s.io/kubernetes/federation/pkg/dnsprovider/rrstype"
"strings"
)
const (

View File

@ -21,12 +21,13 @@ import (
"testing"
"fmt"
"reflect"
"sort"
"k8s.io/kubernetes/federation/apis/federation/v1beta1"
"k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" // Only for unit testing purposes.
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/sets"
"reflect"
"sort"
)
func TestServiceController_ensureDnsRecords(t *testing.T) {

View File

@ -28,8 +28,6 @@ import (
federationcache "k8s.io/kubernetes/federation/client/cache"
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
v1 "k8s.io/kubernetes/pkg/api/v1"
cache "k8s.io/kubernetes/pkg/client/cache"
@ -145,7 +143,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(api.EventSource{Component: UserAgentName})
recorder := broadcaster.NewRecorder(v1.EventSource{Component: UserAgentName})
s := &ServiceController{
dns: dns,
@ -166,13 +164,11 @@ func New(federationClient fedclientset.Interface, dns dnsprovider.Interface,
}
s.serviceStore.Indexer, s.serviceController = cache.NewIndexerInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return s.federationClient.Core().Services(v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return s.federationClient.Core().Services(v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return s.federationClient.Core().Services(v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return s.federationClient.Core().Services(v1.NamespaceAll).Watch(options)
},
},
&v1.Service{},
@ -191,13 +187,11 @@ func New(federationClient fedclientset.Interface, dns dnsprovider.Interface,
)
s.clusterStore.Store, s.clusterController = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return s.federationClient.Federation().Clusters().List(versionedOptions)
ListFunc: func(options v1.ListOptions) (pkg_runtime.Object, error) {
return s.federationClient.Federation().Clusters().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := util.VersionizeV1ListOptions(options)
return s.federationClient.Federation().Clusters().Watch(versionedOptions)
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return s.federationClient.Federation().Clusters().Watch(options)
},
},
&v1beta1.Cluster{},

View File

@ -60,7 +60,6 @@ go_test(
deps = [
"//federation/apis/federation/v1beta1:go_default_library",
"//federation/client/clientset_generated/federation_release_1_5/fake:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",

View File

@ -30,7 +30,6 @@ go_test(
deps = [
"//federation/client/clientset_generated/federation_release_1_5/fake:go_default_library",
"//federation/pkg/federation-controller/util/test:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/testing/core:go_default_library",
"//pkg/runtime:go_default_library",

View File

@ -37,36 +37,14 @@ func NewFederatedEventSink(clientset fedclientset.Interface) *FederatedEventSink
}
}
func (fes *FederatedEventSink) Create(event *api.Event) (*api.Event, error) {
return fes.executeOperation(event, func(eventV1 *api_v1.Event) (*api_v1.Event, error) {
return fes.clientset.Core().Events(event.Namespace).Create(eventV1)
})
func (fes *FederatedEventSink) Create(event *api_v1.Event) (*api_v1.Event, error) {
return fes.clientset.Core().Events(event.Namespace).Create(event)
}
func (fes *FederatedEventSink) Update(event *api.Event) (*api.Event, error) {
return fes.executeOperation(event, func(eventV1 *api_v1.Event) (*api_v1.Event, error) {
return fes.clientset.Core().Events(event.Namespace).Update(eventV1)
})
func (fes *FederatedEventSink) Update(event *api_v1.Event) (*api_v1.Event, error) {
return fes.clientset.Core().Events(event.Namespace).Update(event)
}
func (fes *FederatedEventSink) Patch(event *api.Event, data []byte) (*api.Event, error) {
return fes.executeOperation(event, func(eventV1 *api_v1.Event) (*api_v1.Event, error) {
return fes.clientset.Core().Events(event.Namespace).Patch(event.Name, api.StrategicMergePatchType, data)
})
}
func (fes *FederatedEventSink) executeOperation(event *api.Event, operation func(*api_v1.Event) (*api_v1.Event, error)) (*api.Event, error) {
var versionedEvent api_v1.Event
if err := api.Scheme.Convert(event, &versionedEvent, nil); err != nil {
return nil, err
}
versionedEventPtr, err := operation(&versionedEvent)
if err != nil {
return nil, err
}
var unversionedEvent api.Event
if err := api.Scheme.Convert(versionedEventPtr, &unversionedEvent, nil); err != nil {
return nil, err
}
return &unversionedEvent, 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, api.StrategicMergePatchType, data)
}

View File

@ -21,7 +21,6 @@ import (
fake_fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5/fake"
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
api "k8s.io/kubernetes/pkg/api"
api_v1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/testing/core"
"k8s.io/kubernetes/pkg/runtime"
@ -46,8 +45,8 @@ func TestEventSink(t *testing.T) {
return true, obj, nil
})
event := api.Event{
ObjectMeta: api.ObjectMeta{
event := api_v1.Event{
ObjectMeta: api_v1.ObjectMeta{
Name: "bzium",
Namespace: "ns",
},

View File

@ -24,7 +24,6 @@ import (
federation_api "k8s.io/kubernetes/federation/apis/federation/v1beta1"
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
api "k8s.io/kubernetes/pkg/api"
api_v1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/cache"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
@ -161,13 +160,11 @@ func NewFederatedInformer(
federatedInformer.clusterInformer.store, federatedInformer.clusterInformer.controller = cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (pkg_runtime.Object, error) {
versionedOptions := VersionizeV1ListOptions(options)
return federationClient.Federation().Clusters().List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (pkg_runtime.Object, error) {
return federationClient.Federation().Clusters().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := VersionizeV1ListOptions(options)
return federationClient.Federation().Clusters().Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return federationClient.Federation().Clusters().Watch(options)
},
},
&federation_api.Cluster{},

View File

@ -22,7 +22,6 @@ import (
federation_api "k8s.io/kubernetes/federation/apis/federation/v1beta1"
fakefederationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5/fake"
api "k8s.io/kubernetes/pkg/api"
api_v1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/cache"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
@ -81,13 +80,11 @@ func TestFederatedInformer(t *testing.T) {
targetInformerFactory := func(cluster *federation_api.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) {
return cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
versionedOptions := VersionizeV1ListOptions(options)
return clientset.Core().Services(api_v1.NamespaceAll).List(versionedOptions)
ListFunc: func(options api_v1.ListOptions) (runtime.Object, error) {
return clientset.Core().Services(api_v1.NamespaceAll).List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
versionedOptions := VersionizeV1ListOptions(options)
return clientset.Core().Services(api_v1.NamespaceAll).Watch(versionedOptions)
WatchFunc: func(options api_v1.ListOptions) (watch.Interface, error) {
return clientset.Core().Services(api_v1.NamespaceAll).Watch(options)
},
},
&api_v1.Service{},

View File

@ -64,6 +64,7 @@ pkg/api/meta
pkg/api/resource
pkg/api/service
pkg/api/v1
pkg/api/v1/service
pkg/apimachinery
pkg/apis/abac/v0
pkg/apis/apps/install
@ -88,6 +89,7 @@ pkg/apiserver/audit
pkg/apiserver/openapi
pkg/auth/authenticator
pkg/auth/authorizer/union
pkg/client/conditions
pkg/client/listers/apps/internalversion
pkg/client/listers/apps/v1alpha1
pkg/client/listers/apps/v1beta1

View File

@ -2313,8 +2313,9 @@ __EOF__
kubectl-with-retry rollout resume deployment nginx "${kube_flags[@]}"
# The resumed deployment can now be rolled back
kubectl rollout undo deployment nginx "${kube_flags[@]}"
# Check that the new replica set (nginx-618515232) has all old revisions stored in an annotation
kubectl get rs nginx-618515232 -o yaml | grep "deployment.kubernetes.io/revision-history: 1,3"
# Check that the new replica set has all old revisions stored in an annotation
newrs="$(kubectl describe deployment nginx | grep NewReplicaSet | awk '{print $2}')"
kubectl get rs "${newrs}" -o yaml | grep "deployment.kubernetes.io/revision-history: 1,3"
# Check that trying to watch the status of a superseded revision returns an error
! kubectl rollout status deployment/nginx --revision=3
cat hack/testdata/deployment-revision1.yaml | $SED "s/name: nginx$/name: nginx2/" | kubectl create -f - "${kube_flags[@]}"

View File

@ -14,19 +14,4 @@ go_library(
name = "go_default_library",
srcs = ["util.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/util/intstr:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/util/intstr:go_default_library",
],
)

View File

@ -16,13 +16,6 @@ limitations under the License.
package pod
import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/util/intstr"
)
const (
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Hostname field.
// The annotation value is a string specifying the hostname to be used for the pod e.g 'my-webserver-1'
@ -36,26 +29,3 @@ const (
// <hostname>.my-web-service.<namespace>.svc.<cluster domain>" would be resolved by the cluster DNS Server.
PodSubdomainAnnotation = "pod.beta.kubernetes.io/subdomain"
)
// FindPort locates the container port for the given pod and portName. If the
// targetPort is a number, use that. If the targetPort is a string, look that
// string up in all named ports in all containers in the target pod. If no
// match is found, fail.
func FindPort(pod *api.Pod, svcPort *api.ServicePort) (int, error) {
portName := svcPort.TargetPort
switch portName.Type {
case intstr.String:
name := portName.StrVal
for _, container := range pod.Spec.Containers {
for _, port := range container.Ports {
if port.Name == name && port.Protocol == svcPort.Protocol {
return int(port.ContainerPort), nil
}
}
}
case intstr.Int:
return portName.IntValue(), nil
}
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}

View File

@ -97,15 +97,3 @@ func GetServiceHealthCheckNodePort(service *api.Service) int32 {
}
return 0
}
// GetServiceHealthCheckPathPort Return the path and nodePort programmed into the Cloud LB Health Check
func GetServiceHealthCheckPathPort(service *api.Service) (string, int32) {
if !NeedsHealthCheck(service) {
return "", 0
}
port := GetServiceHealthCheckNodePort(service)
if port == 0 {
return "", 0
}
return "/healthz", port
}

View File

@ -24,6 +24,7 @@ go_library(
"//pkg/api/resource:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/extensions:go_default_library",

View File

@ -18,6 +18,7 @@ package testing
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
// DeepEqualSafePodSpec returns a PodSpec which is ready to be used with api.Semantic.DeepEqual
@ -30,3 +31,14 @@ func DeepEqualSafePodSpec() api.PodSpec {
SecurityContext: &api.PodSecurityContext{},
}
}
// V1DeepEqualSafePodSpec returns a PodSpec which is ready to be used with api.Semantic.DeepEqual
func V1DeepEqualSafePodSpec() v1.PodSpec {
grace := int64(30)
return v1.PodSpec{
RestartPolicy: v1.RestartPolicyAlways,
DNSPolicy: v1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &v1.PodSecurityContext{},
}
}

View File

@ -16,10 +16,13 @@ go_library(
"conversion.go",
"defaults.go",
"doc.go",
"generate.go",
"generated.pb.go",
"helpers.go",
"meta.go",
"ref.go",
"register.go",
"resource_helpers.go",
"types.generated.go",
"types.go",
"types_swagger_doc_generated.go",
@ -36,11 +39,16 @@ go_library(
"//pkg/api/unversioned:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/conversion:go_default_library",
"//pkg/fields:go_default_library",
"//pkg/labels:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/selection:go_default_library",
"//pkg/types:go_default_library",
"//pkg/util:go_default_library",
"//pkg/util/intstr:go_default_library",
"//pkg/util/parsers:go_default_library",
"//pkg/util/rand:go_default_library",
"//pkg/util/sets:go_default_library",
"//pkg/util/validation/field:go_default_library",
"//pkg/watch/versioned:go_default_library",
"//vendor:github.com/gogo/protobuf/proto",
@ -70,3 +78,19 @@ go_test(
"//pkg/util/validation/field:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"helpers_test.go",
"resource_helpers_test.go",
],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/resource:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/labels:go_default_library",
],
)

View File

@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["util.go"],
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/types:go_default_library",
"//pkg/util/hash:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/types:go_default_library",
"//vendor:github.com/davecgh/go-spew/spew",
],
)

View File

@ -0,0 +1,238 @@
/*
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 endpoints
import (
"bytes"
"crypto/md5"
"encoding/hex"
"hash"
"sort"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/types"
hashutil "k8s.io/kubernetes/pkg/util/hash"
)
const (
// TODO: to be deleted after v1.3 is released
// Its value is the json representation of map[string(IP)][HostRecord]
// example: '{"10.245.1.6":{"HostName":"my-webserver"}}'
PodHostnamesAnnotation = "endpoints.beta.kubernetes.io/hostnames-map"
)
// TODO: to be deleted after v1.3 is released
type HostRecord struct {
HostName string
}
// RepackSubsets takes a slice of EndpointSubset objects, expands it to the full
// representation, and then repacks that into the canonical layout. This
// ensures that code which operates on these objects can rely on the common
// form for things like comparison. The result is a newly allocated slice.
func RepackSubsets(subsets []v1.EndpointSubset) []v1.EndpointSubset {
// First map each unique port definition to the sets of hosts that
// offer it.
allAddrs := map[addressKey]*v1.EndpointAddress{}
portToAddrReadyMap := map[v1.EndpointPort]addressSet{}
for i := range subsets {
for _, port := range subsets[i].Ports {
for k := range subsets[i].Addresses {
mapAddressByPort(&subsets[i].Addresses[k], port, true, allAddrs, portToAddrReadyMap)
}
for k := range subsets[i].NotReadyAddresses {
mapAddressByPort(&subsets[i].NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap)
}
}
}
// Next, map the sets of hosts to the sets of ports they offer.
// Go does not allow maps or slices as keys to maps, so we have
// to synthesize an artificial key and do a sort of 2-part
// associative entity.
type keyString string
keyToAddrReadyMap := map[keyString]addressSet{}
addrReadyMapKeyToPorts := map[keyString][]v1.EndpointPort{}
for port, addrs := range portToAddrReadyMap {
key := keyString(hashAddresses(addrs))
keyToAddrReadyMap[key] = addrs
addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port)
}
// Next, build the N-to-M association the API wants.
final := []v1.EndpointSubset{}
for key, ports := range addrReadyMapKeyToPorts {
var readyAddrs, notReadyAddrs []v1.EndpointAddress
for addr, ready := range keyToAddrReadyMap[key] {
if ready {
readyAddrs = append(readyAddrs, *addr)
} else {
notReadyAddrs = append(notReadyAddrs, *addr)
}
}
final = append(final, v1.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports})
}
// Finally, sort it.
return SortSubsets(final)
}
// The sets of hosts must be de-duped, using IP+UID as the key.
type addressKey struct {
ip string
uid types.UID
}
// mapAddressByPort adds an address into a map by its ports, registering the address with a unique pointer, and preserving
// any existing ready state.
func mapAddressByPort(addr *v1.EndpointAddress, port v1.EndpointPort, ready bool, allAddrs map[addressKey]*v1.EndpointAddress, portToAddrReadyMap map[v1.EndpointPort]addressSet) *v1.EndpointAddress {
// use addressKey to distinguish between two endpoints that are identical addresses
// but may have come from different hosts, for attribution. For instance, Mesos
// assigns pods the node IP, but the pods are distinct.
key := addressKey{ip: addr.IP}
if addr.TargetRef != nil {
key.uid = addr.TargetRef.UID
}
// Accumulate the address. The full EndpointAddress structure is preserved for use when
// we rebuild the subsets so that the final TargetRef has all of the necessary data.
existingAddress := allAddrs[key]
if existingAddress == nil {
// Make a copy so we don't write to the
// input args of this function.
existingAddress = &v1.EndpointAddress{}
*existingAddress = *addr
allAddrs[key] = existingAddress
}
// Remember that this port maps to this address.
if _, found := portToAddrReadyMap[port]; !found {
portToAddrReadyMap[port] = addressSet{}
}
// if we have not yet recorded this port for this address, or if the previous
// state was ready, write the current ready state. not ready always trumps
// ready.
if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady {
portToAddrReadyMap[port][existingAddress] = ready
}
return existingAddress
}
type addressSet map[*v1.EndpointAddress]bool
type addrReady struct {
addr *v1.EndpointAddress
ready bool
}
func hashAddresses(addrs addressSet) string {
// Flatten the list of addresses into a string so it can be used as a
// map key. Unfortunately, DeepHashObject is implemented in terms of
// spew, and spew does not handle non-primitive map keys well. So
// first we collapse it into a slice, sort the slice, then hash that.
slice := make([]addrReady, 0, len(addrs))
for k, ready := range addrs {
slice = append(slice, addrReady{k, ready})
}
sort.Sort(addrsReady(slice))
hasher := md5.New()
hashutil.DeepHashObject(hasher, slice)
return hex.EncodeToString(hasher.Sum(nil)[0:])
}
func lessAddrReady(a, b addrReady) bool {
// ready is not significant to hashing since we can't have duplicate addresses
return LessEndpointAddress(a.addr, b.addr)
}
type addrsReady []addrReady
func (sl addrsReady) Len() int { return len(sl) }
func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl addrsReady) Less(i, j int) bool {
return lessAddrReady(sl[i], sl[j])
}
func LessEndpointAddress(a, b *v1.EndpointAddress) bool {
ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP))
if ipComparison != 0 {
return ipComparison < 0
}
if b.TargetRef == nil {
return false
}
if a.TargetRef == nil {
return true
}
return a.TargetRef.UID < b.TargetRef.UID
}
type addrPtrsByIpAndUID []*v1.EndpointAddress
func (sl addrPtrsByIpAndUID) Len() int { return len(sl) }
func (sl addrPtrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl addrPtrsByIpAndUID) Less(i, j int) bool {
return LessEndpointAddress(sl[i], sl[j])
}
// SortSubsets sorts an array of EndpointSubset objects in place. For ease of
// use it returns the input slice.
func SortSubsets(subsets []v1.EndpointSubset) []v1.EndpointSubset {
for i := range subsets {
ss := &subsets[i]
sort.Sort(addrsByIpAndUID(ss.Addresses))
sort.Sort(addrsByIpAndUID(ss.NotReadyAddresses))
sort.Sort(portsByHash(ss.Ports))
}
sort.Sort(subsetsByHash(subsets))
return subsets
}
func hashObject(hasher hash.Hash, obj interface{}) []byte {
hashutil.DeepHashObject(hasher, obj)
return hasher.Sum(nil)
}
type subsetsByHash []v1.EndpointSubset
func (sl subsetsByHash) Len() int { return len(sl) }
func (sl subsetsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl subsetsByHash) Less(i, j int) bool {
hasher := md5.New()
h1 := hashObject(hasher, sl[i])
h2 := hashObject(hasher, sl[j])
return bytes.Compare(h1, h2) < 0
}
type addrsByIpAndUID []v1.EndpointAddress
func (sl addrsByIpAndUID) Len() int { return len(sl) }
func (sl addrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl addrsByIpAndUID) Less(i, j int) bool {
return LessEndpointAddress(&sl[i], &sl[j])
}
type portsByHash []v1.EndpointPort
func (sl portsByHash) Len() int { return len(sl) }
func (sl portsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl portsByHash) Less(i, j int) bool {
hasher := md5.New()
h1 := hashObject(hasher, sl[i])
h2 := hashObject(hasher, sl[j])
return bytes.Compare(h1, h2) < 0
}

View File

@ -0,0 +1,464 @@
/*
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 endpoints
import (
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/types"
)
func podRef(uid string) *v1.ObjectReference {
ref := v1.ObjectReference{UID: types.UID(uid)}
return &ref
}
func TestPackSubsets(t *testing.T) {
// The downside of table-driven tests is that some things have to live outside the table.
fooObjRef := v1.ObjectReference{Name: "foo"}
barObjRef := v1.ObjectReference{Name: "bar"}
testCases := []struct {
name string
given []v1.EndpointSubset
expect []v1.EndpointSubset
}{
{
name: "empty everything",
given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{}}},
expect: []v1.EndpointSubset{},
}, {
name: "empty addresses",
given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{{Port: 111}}}},
expect: []v1.EndpointSubset{},
}, {
name: "empty ports",
given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}},
expect: []v1.EndpointSubset{},
}, {
name: "empty ports",
given: []v1.EndpointSubset{{NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}},
expect: []v1.EndpointSubset{},
}, {
name: "one set, one ip, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one ip, one port (IPv6)",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one notReady ip, one port",
given: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one ip, one UID, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one notReady ip, one UID, one port",
given: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one ip, empty UID, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one notReady ip, empty UID, one port",
given: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, two ips, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, two mixed ips, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, two duplicate ips, one port, notReady is covered by ready",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one ip, two ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}},
}},
}, {
name: "one set, dup ips, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, dup ips, one port (IPv6)",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "beef::1"}, {IP: "beef::1"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "beef::1"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, dup ips with target-refs, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "1.2.3.4", TargetRef: &fooObjRef},
{IP: "1.2.3.4", TargetRef: &barObjRef},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, dup mixed ips with target-refs, one port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "1.2.3.4", TargetRef: &fooObjRef},
},
NotReadyAddresses: []v1.EndpointAddress{
{IP: "1.2.3.4", TargetRef: &barObjRef},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
// finding the same address twice is considered an error on input, only the first address+port
// reference is preserved
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "one set, one ip, dup ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}, {Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, dup ip, dup port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, dup mixed ip, dup port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, dup ip, two ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}},
}},
}, {
name: "two sets, dup ip, dup uids, two ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}},
}},
}, {
name: "two sets, dup mixed ip, dup uids, two ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
}, {
name: "two sets, two ips, dup port",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two set, dup ip, two uids, dup ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
{IP: "1.2.3.4", TargetRef: podRef("uid-2")},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two set, dup ip, with and without uid, dup ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "1.2.3.4"},
{IP: "1.2.3.4", TargetRef: podRef("uid-2")},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, two ips, two dup ip with uid, dup port, wrong order",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "1.2.3.4"},
{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
{IP: "5.6.7.8"},
{IP: "5.6.7.8", TargetRef: podRef("uid-1")},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, two mixed ips, two dup ip with uid, dup port, wrong order, ends up with split addresses",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{
{IP: "5.6.7.8"},
},
NotReadyAddresses: []v1.EndpointAddress{
{IP: "1.2.3.4"},
{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
{IP: "5.6.7.8", TargetRef: podRef("uid-1")},
},
Ports: []v1.EndpointPort{{Port: 111}},
}},
}, {
name: "two sets, two ips, two ports",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
Ports: []v1.EndpointPort{{Port: 222}},
}},
}, {
name: "four sets, three ips, three ports, jumbled",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 222}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 333}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 222}, {Port: 333}},
}},
}, {
name: "four sets, three mixed ips, three ports, jumbled",
given: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 222}},
}, {
Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 333}},
}},
expect: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}},
Ports: []v1.EndpointPort{{Port: 111}},
}, {
NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
Ports: []v1.EndpointPort{{Port: 222}, {Port: 333}},
}},
},
}
for _, tc := range testCases {
result := RepackSubsets(tc.given)
if !reflect.DeepEqual(result, SortSubsets(tc.expect)) {
t.Errorf("case %q: expected %s, got %s", tc.name, spew.Sprintf("%#v", SortSubsets(tc.expect)), spew.Sprintf("%#v", result))
}
}
}

64
pkg/api/v1/generate.go Normal file
View File

@ -0,0 +1,64 @@
/*
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 v1
import (
"fmt"
utilrand "k8s.io/kubernetes/pkg/util/rand"
)
// NameGenerator generates names for objects. Some backends may have more information
// available to guide selection of new names and this interface hides those details.
type NameGenerator interface {
// GenerateName generates a valid name from the base name, adding a random suffix to the
// the base. If base is valid, the returned name must also be valid. The generator is
// responsible for knowing the maximum valid name length.
GenerateName(base string) string
}
// GenerateName will resolve the object name of the provided ObjectMeta to a generated version if
// necessary. It expects that validation for ObjectMeta has already completed (that Base is a
// valid name) and that the NameGenerator generates a name that is also valid.
func GenerateName(u NameGenerator, meta *ObjectMeta) {
if len(meta.GenerateName) == 0 || len(meta.Name) != 0 {
return
}
meta.Name = u.GenerateName(meta.GenerateName)
}
// simpleNameGenerator generates random names.
type simpleNameGenerator struct{}
// SimpleNameGenerator is a generator that returns the name plus a random suffix of five alphanumerics
// when a name is requested. The string is guaranteed to not exceed the length of a standard Kubernetes
// name (63 characters)
var SimpleNameGenerator NameGenerator = simpleNameGenerator{}
const (
// TODO: make this flexible for non-core resources with alternate naming rules.
maxNameLength = 63
randomLength = 5
maxGeneratedNameLength = maxNameLength - randomLength
)
func (simpleNameGenerator) GenerateName(base string) string {
if len(base) > maxGeneratedNameLength {
base = base[:maxGeneratedNameLength]
}
return fmt.Sprintf("%s%s", base, utilrand.String(randomLength))
}

File diff suppressed because it is too large Load Diff

View File

@ -1465,6 +1465,13 @@ message NodeProxyOptions {
optional string path = 1;
}
// NodeResources is an object for conveying resource information about a node.
// see http://releases.k8s.io/HEAD/docs/design/resources.md for more details.
message NodeResources {
// Capacity represents the available resources of a node
map<string, k8s.io.kubernetes.pkg.api.resource.Quantity> capacity = 1;
}
// A node selector represents the union of the results of one or more label queries
// over a set of nodes; that is, it represents the OR of the selectors represented
// by the node selector terms.
@ -3360,6 +3367,12 @@ message ServiceStatus {
optional LoadBalancerStatus loadBalancer = 1;
}
message Sysctl {
optional string name = 1;
optional string value = 2;
}
// TCPSocketAction describes an action based on opening a socket
message TCPSocketAction {
// Number or name of the port to access on the container.

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
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.
@ -16,18 +16,441 @@ limitations under the License.
package v1
import "k8s.io/kubernetes/pkg/types"
import (
"encoding/json"
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/selection"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util/sets"
)
// IsOpaqueIntResourceName returns true if the resource name has the opaque
// integer resource prefix.
func IsOpaqueIntResourceName(name ResourceName) bool {
return strings.HasPrefix(string(name), ResourceOpaqueIntPrefix)
}
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
// integer prefix prepended. If the argument already has the prefix, it is
// returned unmodified.
func OpaqueIntResourceName(name string) ResourceName {
if IsOpaqueIntResourceName(ResourceName(name)) {
return ResourceName(name)
}
return ResourceName(fmt.Sprintf("%s%s", api.ResourceOpaqueIntPrefix, name))
}
// NewDeleteOptions returns a DeleteOptions indicating the resource should
// be deleted within the specified grace period. Use zero to indicate
// immediate deletion. If you would prefer to use the default grace period,
// use &v1.DeleteOptions{} directly.
// use &api.DeleteOptions{} directly.
func NewDeleteOptions(grace int64) *DeleteOptions {
return &DeleteOptions{GracePeriodSeconds: &grace}
}
// NewPreconditionDeleteOptions returns a DeleteOptions with a UID precondition set.
func NewPreconditionDeleteOptions(uid string) *DeleteOptions {
u := types.UID(uid)
p := Preconditions{UID: &u}
return &DeleteOptions{Preconditions: &p}
}
// NewUIDPreconditions returns a Preconditions with UID set.
func NewUIDPreconditions(uid string) *Preconditions {
u := types.UID(uid)
return &Preconditions{UID: &u}
}
// this function aims to check if the service's ClusterIP is set or not
// the objective is not to perform validation here
func IsServiceIPSet(service *Service) bool {
return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != ""
}
// this function aims to check if the service's cluster IP is requested or not
func IsServiceIPRequested(service *Service) bool {
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
if service.Spec.Type == ServiceTypeExternalName {
return false
}
return service.Spec.ClusterIP == ""
}
var standardFinalizers = sets.NewString(
string(FinalizerKubernetes),
FinalizerOrphan,
)
// HasAnnotation returns a bool if passed in annotation exists
func HasAnnotation(obj ObjectMeta, ann string) bool {
_, found := obj.Annotations[ann]
return found
}
// SetMetaDataAnnotation sets the annotation and value
func SetMetaDataAnnotation(obj *ObjectMeta, ann string, value string) {
if obj.Annotations == nil {
obj.Annotations = make(map[string]string)
}
obj.Annotations[ann] = value
}
func IsStandardFinalizerName(str string) bool {
return standardFinalizers.Has(str)
}
// SingleObject returns a ListOptions for watching a single object.
func SingleObject(meta ObjectMeta) ListOptions {
return ListOptions{
FieldSelector: fields.OneTermEqualSelector("metadata.name", meta.Name).String(),
ResourceVersion: meta.ResourceVersion,
}
}
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
// only if they do not already exist
func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
for _, add := range addAddresses {
exists := false
for _, existing := range *addresses {
if existing.Address == add.Address && existing.Type == add.Type {
exists = true
break
}
}
if !exists {
*addresses = append(*addresses, add)
}
}
}
// TODO: make method on LoadBalancerStatus?
func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool {
return ingressSliceEqual(l.Ingress, r.Ingress)
}
func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
if len(lhs) != len(rhs) {
return false
}
for i := range lhs {
if !ingressEqual(&lhs[i], &rhs[i]) {
return false
}
}
return true
}
func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
if lhs.IP != rhs.IP {
return false
}
if lhs.Hostname != rhs.Hostname {
return false
}
return true
}
// TODO: make method on LoadBalancerStatus?
func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
c := &LoadBalancerStatus{}
c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress))
for i := range lb.Ingress {
c.Ingress[i] = lb.Ingress[i]
}
return c
}
// GetAccessModesAsString returns a string representation of an array of access modes.
// modes, when present, are always in the same order: RWO,ROX,RWX.
func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string {
modes = removeDuplicateAccessModes(modes)
modesStr := []string{}
if containsAccessMode(modes, ReadWriteOnce) {
modesStr = append(modesStr, "RWO")
}
if containsAccessMode(modes, ReadOnlyMany) {
modesStr = append(modesStr, "ROX")
}
if containsAccessMode(modes, ReadWriteMany) {
modesStr = append(modesStr, "RWX")
}
return strings.Join(modesStr, ",")
}
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode {
strmodes := strings.Split(modes, ",")
accessModes := []PersistentVolumeAccessMode{}
for _, s := range strmodes {
s = strings.Trim(s, " ")
switch {
case s == "RWO":
accessModes = append(accessModes, ReadWriteOnce)
case s == "ROX":
accessModes = append(accessModes, ReadOnlyMany)
case s == "RWX":
accessModes = append(accessModes, ReadWriteMany)
}
}
return accessModes
}
// removeDuplicateAccessModes returns an array of access modes without any duplicates
func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode {
accessModes := []PersistentVolumeAccessMode{}
for _, m := range modes {
if !containsAccessMode(accessModes, m) {
accessModes = append(accessModes, m)
}
}
return accessModes
}
func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool {
for _, m := range modes {
if m == mode {
return true
}
}
return false
}
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
// labels.Selector.
func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) {
if len(nsm) == 0 {
return labels.Nothing(), nil
}
selector := labels.NewSelector()
for _, expr := range nsm {
var op selection.Operator
switch expr.Operator {
case NodeSelectorOpIn:
op = selection.In
case NodeSelectorOpNotIn:
op = selection.NotIn
case NodeSelectorOpExists:
op = selection.Exists
case NodeSelectorOpDoesNotExist:
op = selection.DoesNotExist
case NodeSelectorOpGt:
op = selection.GreaterThan
case NodeSelectorOpLt:
op = selection.LessThan
default:
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
}
r, err := labels.NewRequirement(expr.Key, op, expr.Values)
if err != nil {
return nil, err
}
selector = selector.Add(*r)
}
return selector, nil
}
const (
// AffinityAnnotationKey represents the key of affinity data (json serialized)
// in the Annotations of a Pod.
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
// TolerationsAnnotationKey represents the key of tolerations data (json serialized)
// in the Annotations of a Pod.
TolerationsAnnotationKey string = "scheduler.alpha.kubernetes.io/tolerations"
// TaintsAnnotationKey represents the key of taints data (json serialized)
// in the Annotations of a Node.
TaintsAnnotationKey string = "scheduler.alpha.kubernetes.io/taints"
// SeccompPodAnnotationKey represents the key of a seccomp profile applied
// to all containers of a pod.
SeccompPodAnnotationKey string = "seccomp.security.alpha.kubernetes.io/pod"
// SeccompContainerAnnotationKeyPrefix represents the key of a seccomp profile applied
// to one container of a pod.
SeccompContainerAnnotationKeyPrefix string = "container.seccomp.security.alpha.kubernetes.io/"
// CreatedByAnnotation represents the key used to store the spec(json)
// used to create the resource.
CreatedByAnnotation = "kubernetes.io/created-by"
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
// in the Annotations of a Node.
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
// SysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
// key-value pairs. Only a limited set of whitelisted and isolated sysctls is supported by
// the kubelet. Pods with other sysctls will fail to launch.
SysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
// UnsafeSysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
// key-value pairs. Unsafe sysctls must be explicitly enabled for a kubelet. They are properly
// namespaced to a pod or a container, but their isolation is usually unclear or weak. Their use
// is at-your-own-risk. Pods that attempt to set an unsafe sysctl that is not enabled for a kubelet
// will fail to launch.
UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
)
// GetAffinityFromPod gets the json serialized affinity data from Pod.Annotations
// and converts it to the Affinity type in api.
func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) {
if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" {
var affinity Affinity
err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity)
if err != nil {
return nil, err
}
return &affinity, nil
}
return nil, nil
}
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
// and converts it to the []Toleration type in api.
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) {
var tolerations []Toleration
if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" {
err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations)
if err != nil {
return tolerations, err
}
}
return tolerations, nil
}
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
// and converts it to the []Taint type in api.
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) {
var taints []Taint
if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" {
err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints)
if err != nil {
return []Taint{}, err
}
}
return taints, nil
}
// TolerationToleratesTaint checks if the toleration tolerates the taint.
func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
return false
}
if toleration.Key != taint.Key {
return false
}
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
if (len(toleration.Operator) == 0 || toleration.Operator == TolerationOpEqual) && toleration.Value == taint.Value {
return true
}
if toleration.Operator == TolerationOpExists {
return true
}
return false
}
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
tolerated := false
for i := range tolerations {
if TolerationToleratesTaint(&tolerations[i], taint) {
tolerated = true
break
}
}
return tolerated
}
// MatchTaint checks if the taint matches taintToMatch. Taints are unique by key:effect,
// if the two taints have same key:effect, regard as they match.
func (t *Taint) MatchTaint(taintToMatch Taint) bool {
return t.Key == taintToMatch.Key && t.Effect == taintToMatch.Effect
}
// taint.ToString() converts taint struct to string in format key=value:effect or key:effect.
func (t *Taint) ToString() string {
if len(t.Value) == 0 {
return fmt.Sprintf("%v:%v", t.Key, t.Effect)
}
return fmt.Sprintf("%v=%v:%v", t.Key, t.Value, t.Effect)
}
func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (AvoidPods, error) {
var avoidPods AvoidPods
if len(annotations) > 0 && annotations[PreferAvoidPodsAnnotationKey] != "" {
err := json.Unmarshal([]byte(annotations[PreferAvoidPodsAnnotationKey]), &avoidPods)
if err != nil {
return avoidPods, err
}
}
return avoidPods, nil
}
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
// SysctlsFromPodAnnotation.
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
if err != nil {
return nil, nil, err
}
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
if err != nil {
return nil, nil, err
}
return safe, unsafe, nil
}
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
if len(annotation) == 0 {
return nil, nil
}
kvs := strings.Split(annotation, ",")
sysctls := make([]Sysctl, len(kvs))
for i, kv := range kvs {
cs := strings.Split(kv, "=")
if len(cs) != 2 || len(cs[0]) == 0 {
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
}
sysctls[i].Name = cs[0]
sysctls[i].Value = cs[1]
}
return sysctls, nil
}
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
if len(sysctls) == 0 {
return ""
}
kvs := make([]string, len(sysctls))
for i := range sysctls {
kvs[i] = fmt.Sprintf("%s=%s", sysctls[i].Name, sysctls[i].Value)
}
return strings.Join(kvs, ",")
}
type Sysctl struct {
Name string
Value string
}
// NodeResources is an object for conveying resource information about a node.
// see http://releases.k8s.io/HEAD/docs/design/resources.md for more details.
type NodeResources struct {
// Capacity represents the available resources of a node
Capacity ResourceList
}

479
pkg/api/v1/helpers_test.go Normal file
View File

@ -0,0 +1,479 @@
/*
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 v1
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/labels"
)
func TestAddToNodeAddresses(t *testing.T) {
testCases := []struct {
existing []NodeAddress
toAdd []NodeAddress
expected []NodeAddress
}{
{
existing: []NodeAddress{},
toAdd: []NodeAddress{},
expected: []NodeAddress{},
},
{
existing: []NodeAddress{},
toAdd: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeHostName, Address: "localhost"},
},
expected: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeHostName, Address: "localhost"},
},
},
{
existing: []NodeAddress{},
toAdd: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeExternalIP, Address: "1.1.1.1"},
},
expected: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
},
},
{
existing: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeInternalIP, Address: "10.1.1.1"},
},
toAdd: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeHostName, Address: "localhost"},
},
expected: []NodeAddress{
{Type: NodeExternalIP, Address: "1.1.1.1"},
{Type: NodeInternalIP, Address: "10.1.1.1"},
{Type: NodeHostName, Address: "localhost"},
},
},
}
for i, tc := range testCases {
AddToNodeAddresses(&tc.existing, tc.toAdd...)
if !api.Semantic.DeepEqual(tc.expected, tc.existing) {
t.Errorf("case[%d], expected: %v, got: %v", i, tc.expected, tc.existing)
}
}
}
func TestGetAccessModesFromString(t *testing.T) {
modes := GetAccessModesFromString("ROX")
if !containsAccessMode(modes, ReadOnlyMany) {
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
}
modes = GetAccessModesFromString("ROX,RWX")
if !containsAccessMode(modes, ReadOnlyMany) {
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
}
if !containsAccessMode(modes, ReadWriteMany) {
t.Errorf("Expected mode %s, but got %+v", ReadWriteMany, modes)
}
modes = GetAccessModesFromString("RWO,ROX,RWX")
if !containsAccessMode(modes, ReadOnlyMany) {
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
}
if !containsAccessMode(modes, ReadWriteMany) {
t.Errorf("Expected mode %s, but got %+v", ReadWriteMany, modes)
}
}
func TestRemoveDuplicateAccessModes(t *testing.T) {
modes := []PersistentVolumeAccessMode{
ReadWriteOnce, ReadOnlyMany, ReadOnlyMany, ReadOnlyMany,
}
modes = removeDuplicateAccessModes(modes)
if len(modes) != 2 {
t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
}
}
func TestNodeSelectorRequirementsAsSelector(t *testing.T) {
matchExpressions := []NodeSelectorRequirement{{
Key: "foo",
Operator: NodeSelectorOpIn,
Values: []string{"bar", "baz"},
}}
mustParse := func(s string) labels.Selector {
out, e := labels.Parse(s)
if e != nil {
panic(e)
}
return out
}
tc := []struct {
in []NodeSelectorRequirement
out labels.Selector
expectErr bool
}{
{in: nil, out: labels.Nothing()},
{in: []NodeSelectorRequirement{}, out: labels.Nothing()},
{
in: matchExpressions,
out: mustParse("foo in (baz,bar)"),
},
{
in: []NodeSelectorRequirement{{
Key: "foo",
Operator: NodeSelectorOpExists,
Values: []string{"bar", "baz"},
}},
expectErr: true,
},
{
in: []NodeSelectorRequirement{{
Key: "foo",
Operator: NodeSelectorOpGt,
Values: []string{"1"},
}},
out: mustParse("foo>1"),
},
{
in: []NodeSelectorRequirement{{
Key: "bar",
Operator: NodeSelectorOpLt,
Values: []string{"7"},
}},
out: mustParse("bar<7"),
},
}
for i, tc := range tc {
out, err := NodeSelectorRequirementsAsSelector(tc.in)
if err == nil && tc.expectErr {
t.Errorf("[%v]expected error but got none.", i)
}
if err != nil && !tc.expectErr {
t.Errorf("[%v]did not expect error but got: %v", i, err)
}
if !reflect.DeepEqual(out, tc.out) {
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
}
}
}
func TestGetAffinityFromPod(t *testing.T) {
testCases := []struct {
pod *Pod
expectErr bool
}{
{
pod: &Pod{},
expectErr: false,
},
{
pod: &Pod{
ObjectMeta: ObjectMeta{
Annotations: map[string]string{
AffinityAnnotationKey: `
{"nodeAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [{
"matchExpressions": [{
"key": "foo",
"operator": "In",
"values": ["value1", "value2"]
}]
}]
}}}`,
},
},
},
expectErr: false,
},
{
pod: &Pod{
ObjectMeta: ObjectMeta{
Annotations: map[string]string{
AffinityAnnotationKey: `
{"nodeAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [{
"matchExpressions": [{
"key": "foo",
`,
},
},
},
expectErr: true,
},
}
for i, tc := range testCases {
_, err := GetAffinityFromPodAnnotations(tc.pod.Annotations)
if err == nil && tc.expectErr {
t.Errorf("[%v]expected error but got none.", i)
}
if err != nil && !tc.expectErr {
t.Errorf("[%v]did not expect error but got: %v", i, err)
}
}
}
func TestTaintToString(t *testing.T) {
testCases := []struct {
taint *Taint
expectedString string
}{
{
taint: &Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
expectedString: "foo=bar:NoSchedule",
},
{
taint: &Taint{
Key: "foo",
Effect: TaintEffectNoSchedule,
},
expectedString: "foo:NoSchedule",
},
}
for i, tc := range testCases {
if tc.expectedString != tc.taint.ToString() {
t.Errorf("[%v] expected taint %v converted to %s, got %s", i, tc.taint, tc.expectedString, tc.taint.ToString())
}
}
}
func TestMatchTaint(t *testing.T) {
testCases := []struct {
description string
taint *Taint
taintToMatch Taint
expectMatch bool
}{
{
description: "two taints with the same key,value,effect should match",
taint: &Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
taintToMatch: Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
expectMatch: true,
},
{
description: "two taints with the same key,effect but different value should match",
taint: &Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
taintToMatch: Taint{
Key: "foo",
Value: "different-value",
Effect: TaintEffectNoSchedule,
},
expectMatch: true,
},
{
description: "two taints with the different key cannot match",
taint: &Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
taintToMatch: Taint{
Key: "different-key",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
expectMatch: false,
},
{
description: "two taints with the different effect cannot match",
taint: &Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectNoSchedule,
},
taintToMatch: Taint{
Key: "foo",
Value: "bar",
Effect: TaintEffectPreferNoSchedule,
},
expectMatch: false,
},
}
for _, tc := range testCases {
if tc.expectMatch != tc.taint.MatchTaint(tc.taintToMatch) {
t.Errorf("[%s] expect taint %s match taint %s", tc.description, tc.taint.ToString(), tc.taintToMatch.ToString())
}
}
}
func TestGetAvoidPodsFromNode(t *testing.T) {
controllerFlag := true
testCases := []struct {
node *Node
expectValue AvoidPods
expectErr bool
}{
{
node: &Node{},
expectValue: AvoidPods{},
expectErr: false,
},
{
node: &Node{
ObjectMeta: ObjectMeta{
Annotations: map[string]string{
PreferAvoidPodsAnnotationKey: `
{
"preferAvoidPods": [
{
"podSignature": {
"podController": {
"apiVersion": "v1",
"kind": "ReplicationController",
"name": "foo",
"uid": "abcdef123456",
"controller": true
}
},
"reason": "some reason",
"message": "some message"
}
]
}`,
},
},
},
expectValue: AvoidPods{
PreferAvoidPods: []PreferAvoidPodsEntry{
{
PodSignature: PodSignature{
PodController: &OwnerReference{
APIVersion: "v1",
Kind: "ReplicationController",
Name: "foo",
UID: "abcdef123456",
Controller: &controllerFlag,
},
},
Reason: "some reason",
Message: "some message",
},
},
},
expectErr: false,
},
{
node: &Node{
// Missing end symbol of "podController" and "podSignature"
ObjectMeta: ObjectMeta{
Annotations: map[string]string{
PreferAvoidPodsAnnotationKey: `
{
"preferAvoidPods": [
{
"podSignature": {
"podController": {
"kind": "ReplicationController",
"apiVersion": "v1"
"reason": "some reason",
"message": "some message"
}
]
}`,
},
},
},
expectValue: AvoidPods{},
expectErr: true,
},
}
for i, tc := range testCases {
v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations)
if err == nil && tc.expectErr {
t.Errorf("[%v]expected error but got none.", i)
}
if err != nil && !tc.expectErr {
t.Errorf("[%v]did not expect error but got: %v", i, err)
}
if !reflect.DeepEqual(tc.expectValue, v) {
t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller)
}
}
}
func TestSysctlsFromPodAnnotation(t *testing.T) {
type Test struct {
annotation string
expectValue []Sysctl
expectErr bool
}
for i, test := range []Test{
{
annotation: "",
expectValue: nil,
},
{
annotation: "foo.bar",
expectErr: true,
},
{
annotation: "=123",
expectErr: true,
},
{
annotation: "foo.bar=",
expectValue: []Sysctl{{Name: "foo.bar", Value: ""}},
},
{
annotation: "foo.bar=42",
expectValue: []Sysctl{{Name: "foo.bar", Value: "42"}},
},
{
annotation: "foo.bar=42,",
expectErr: true,
},
{
annotation: "foo.bar=42,abc.def=1",
expectValue: []Sysctl{{Name: "foo.bar", Value: "42"}, {Name: "abc.def", Value: "1"}},
},
} {
sysctls, err := SysctlsFromPodAnnotation(test.annotation)
if test.expectErr && err == nil {
t.Errorf("[%v]expected error but got none", i)
} else if !test.expectErr && err != nil {
t.Errorf("[%v]did not expect error but got: %v", i, err)
} else if !reflect.DeepEqual(sysctls, test.expectValue) {
t.Errorf("[%v]expect value %v but got %v", i, test.expectValue, sysctls)
}
}
}

32
pkg/api/v1/pod/BUILD Normal file
View File

@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["util.go"],
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/util/intstr:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/util/intstr:go_default_library",
],
)

120
pkg/api/v1/pod/util.go Normal file
View File

@ -0,0 +1,120 @@
/*
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 pod
import (
"encoding/json"
"fmt"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr"
)
const (
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Hostname field.
// The annotation value is a string specifying the hostname to be used for the pod e.g 'my-webserver-1'
PodHostnameAnnotation = "pod.beta.kubernetes.io/hostname"
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Subdomain field.
// The annotation value is a string specifying the subdomain e.g. "my-web-service"
// If specified, on the pod itself, "<hostname>.my-web-service.<namespace>.svc.<cluster domain>" would resolve to
// the pod's IP.
// If there is a headless service named "my-web-service" in the same namespace as the pod, then,
// <hostname>.my-web-service.<namespace>.svc.<cluster domain>" would be resolved by the cluster DNS Server.
PodSubdomainAnnotation = "pod.beta.kubernetes.io/subdomain"
)
// FindPort locates the container port for the given pod and portName. If the
// targetPort is a number, use that. If the targetPort is a string, look that
// string up in all named ports in all containers in the target pod. If no
// match is found, fail.
func FindPort(pod *v1.Pod, svcPort *v1.ServicePort) (int, error) {
portName := svcPort.TargetPort
switch portName.Type {
case intstr.String:
name := portName.StrVal
for _, container := range pod.Spec.Containers {
for _, port := range container.Ports {
if port.Name == name && port.Protocol == svcPort.Protocol {
return int(port.ContainerPort), nil
}
}
}
case intstr.Int:
return portName.IntValue(), nil
}
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersAndStatuses(pod *v1.Pod) error {
var initContainersAnnotation string
initContainersAnnotation = pod.Annotations[v1.PodInitContainersAnnotationKey]
initContainersAnnotation = pod.Annotations[v1.PodInitContainersBetaAnnotationKey]
if len(initContainersAnnotation) > 0 {
var values []v1.Container
if err := json.Unmarshal([]byte(initContainersAnnotation), &values); err != nil {
return err
}
pod.Spec.InitContainers = values
}
var initContainerStatusesAnnotation string
initContainerStatusesAnnotation = pod.Annotations[v1.PodInitContainerStatusesAnnotationKey]
initContainerStatusesAnnotation = pod.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey]
if len(initContainerStatusesAnnotation) > 0 {
var values []v1.ContainerStatus
if err := json.Unmarshal([]byte(initContainerStatusesAnnotation), &values); err != nil {
return err
}
pod.Status.InitContainerStatuses = values
}
return nil
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersAnnotations(pod *v1.Pod) error {
if len(pod.Spec.InitContainers) > 0 {
value, err := json.Marshal(pod.Spec.InitContainers)
if err != nil {
return err
}
if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
pod.Annotations[v1.PodInitContainersAnnotationKey] = string(value)
pod.Annotations[v1.PodInitContainersBetaAnnotationKey] = string(value)
}
return nil
}
// TODO: remove this function when init containers becomes a stable feature
func SetInitContainersStatusesAnnotations(pod *v1.Pod) error {
if len(pod.Status.InitContainerStatuses) > 0 {
value, err := json.Marshal(pod.Status.InitContainerStatuses)
if err != nil {
return err
}
if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
pod.Annotations[v1.PodInitContainerStatusesAnnotationKey] = string(value)
pod.Annotations[v1.PodInitContainerStatusesBetaAnnotationKey] = string(value)
}
return nil
}

View File

@ -19,26 +19,26 @@ package pod
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr"
)
func TestFindPort(t *testing.T) {
testCases := []struct {
name string
containers []api.Container
containers []v1.Container
port intstr.IntOrString
expected int
pass bool
}{{
name: "valid int, no ports",
containers: []api.Container{{}},
containers: []v1.Container{{}},
port: intstr.FromInt(93),
expected: 93,
pass: true,
}, {
name: "valid int, with ports",
containers: []api.Container{{Ports: []api.ContainerPort{{
containers: []v1.Container{{Ports: []v1.ContainerPort{{
Name: "",
ContainerPort: 11,
Protocol: "TCP",
@ -52,13 +52,13 @@ func TestFindPort(t *testing.T) {
pass: true,
}, {
name: "valid str, no ports",
containers: []api.Container{{}},
containers: []v1.Container{{}},
port: intstr.FromString("p"),
expected: 0,
pass: false,
}, {
name: "valid str, one ctr with ports",
containers: []api.Container{{Ports: []api.ContainerPort{{
containers: []v1.Container{{Ports: []v1.ContainerPort{{
Name: "",
ContainerPort: 11,
Protocol: "UDP",
@ -76,7 +76,7 @@ func TestFindPort(t *testing.T) {
pass: true,
}, {
name: "valid str, two ctr with ports",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "",
ContainerPort: 11,
Protocol: "UDP",
@ -94,7 +94,7 @@ func TestFindPort(t *testing.T) {
pass: true,
}, {
name: "valid str, two ctr with same port",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "",
ContainerPort: 11,
Protocol: "UDP",
@ -112,7 +112,7 @@ func TestFindPort(t *testing.T) {
pass: true,
}, {
name: "valid str, invalid protocol",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "a",
ContainerPort: 11,
Protocol: "snmp",
@ -123,7 +123,7 @@ func TestFindPort(t *testing.T) {
pass: false,
}, {
name: "valid hostPort",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "a",
ContainerPort: 11,
HostPort: 81,
@ -136,7 +136,7 @@ func TestFindPort(t *testing.T) {
},
{
name: "invalid hostPort",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "a",
ContainerPort: 11,
HostPort: -1,
@ -150,7 +150,7 @@ func TestFindPort(t *testing.T) {
},
{
name: "invalid ContainerPort",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "a",
ContainerPort: -1,
Protocol: "TCP",
@ -163,7 +163,7 @@ func TestFindPort(t *testing.T) {
},
{
name: "HostIP Address",
containers: []api.Container{{}, {Ports: []api.ContainerPort{{
containers: []v1.Container{{}, {Ports: []v1.ContainerPort{{
Name: "a",
ContainerPort: 11,
HostIP: "192.168.1.1",
@ -177,8 +177,8 @@ func TestFindPort(t *testing.T) {
}
for _, tc := range testCases {
port, err := FindPort(&api.Pod{Spec: api.PodSpec{Containers: tc.containers}},
&api.ServicePort{Protocol: "TCP", TargetPort: tc.port})
port, err := FindPort(&v1.Pod{Spec: v1.PodSpec{Containers: tc.containers}},
&v1.ServicePort{Protocol: "TCP", TargetPort: tc.port})
if err != nil && tc.pass {
t.Errorf("unexpected error for %s: %v", tc.name, err)
}

133
pkg/api/v1/ref.go Normal file
View File

@ -0,0 +1,133 @@
/*
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 v1
import (
"errors"
"fmt"
"k8s.io/kubernetes/pkg/api"
"net/url"
"strings"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)
var (
// Errors that could be returned by GetReference.
ErrNilObject = errors.New("can't reference a nil object")
ErrNoSelfLink = errors.New("selfLink was empty, can't make reference")
)
// GetReference returns an ObjectReference which refers to the given
// 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) {
if obj == nil {
return nil, ErrNilObject
}
if ref, ok := obj.(*ObjectReference); ok {
// Don't make a reference to a reference.
return ref, nil
}
gvk := obj.GetObjectKind().GroupVersionKind()
// if the object referenced is actually persisted, we can just get kind from meta
// if we are building an object reference to something not yet persisted, we should fallback to scheme
kind := gvk.Kind
if len(kind) == 0 {
// TODO: this is wrong
gvks, _, err := api.Scheme.ObjectKinds(obj)
if err != nil {
return nil, err
}
kind = gvks[0].Kind
}
// An object that implements only List has enough metadata to build a reference
var listMeta meta.List
objectMeta, err := meta.Accessor(obj)
if err != nil {
listMeta, err = meta.ListAccessor(obj)
if err != nil {
return nil, err
}
} else {
listMeta = objectMeta
}
// if the object referenced is actually persisted, we can also get version from meta
version := gvk.GroupVersion().String()
if len(version) == 0 {
selfLink := listMeta.GetSelfLink()
if len(selfLink) == 0 {
return nil, ErrNoSelfLink
}
selfLinkUrl, err := url.Parse(selfLink)
if err != nil {
return nil, err
}
// example paths: /<prefix>/<version>/*
parts := strings.Split(selfLinkUrl.Path, "/")
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
}
version = parts[2]
}
// only has list metadata
if objectMeta == nil {
return &ObjectReference{
Kind: kind,
APIVersion: version,
ResourceVersion: listMeta.GetResourceVersion(),
}, nil
}
return &ObjectReference{
Kind: kind,
APIVersion: version,
Name: objectMeta.GetName(),
Namespace: objectMeta.GetNamespace(),
UID: objectMeta.GetUID(),
ResourceVersion: objectMeta.GetResourceVersion(),
}, nil
}
// 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)
if err != nil {
return nil, err
}
ref.FieldPath = fieldPath
return ref, nil
}
// IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that
// intend only to get a reference to that object. This simplifies the event recording interface.
func (obj *ObjectReference) SetGroupVersionKind(gvk unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ObjectReference) GroupVersionKind() unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ObjectReference) GetObjectKind() unversioned.ObjectKind { return obj }

View File

@ -0,0 +1,229 @@
/*
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 v1
import (
"time"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
)
// Returns string version of ResourceName.
func (self ResourceName) String() string {
return string(self)
}
// Returns the CPU limit if specified.
func (self *ResourceList) Cpu() *resource.Quantity {
if val, ok := (*self)[ResourceCPU]; ok {
return &val
}
return &resource.Quantity{Format: resource.DecimalSI}
}
// Returns the Memory limit if specified.
func (self *ResourceList) Memory() *resource.Quantity {
if val, ok := (*self)[ResourceMemory]; ok {
return &val
}
return &resource.Quantity{Format: resource.BinarySI}
}
func (self *ResourceList) Pods() *resource.Quantity {
if val, ok := (*self)[ResourcePods]; ok {
return &val
}
return &resource.Quantity{}
}
func (self *ResourceList) NvidiaGPU() *resource.Quantity {
if val, ok := (*self)[ResourceNvidiaGPU]; ok {
return &val
}
return &resource.Quantity{}
}
func GetContainerStatus(statuses []ContainerStatus, name string) (ContainerStatus, bool) {
for i := range statuses {
if statuses[i].Name == name {
return statuses[i], true
}
}
return ContainerStatus{}, false
}
func GetExistingContainerStatus(statuses []ContainerStatus, name string) ContainerStatus {
for i := range statuses {
if statuses[i].Name == name {
return statuses[i]
}
}
return ContainerStatus{}
}
// IsPodAvailable returns true if a pod is available; false otherwise.
// Precondition for an available pod is that it must be ready. On top
// of that, there are two cases when a pod can be considered available:
// 1. minReadySeconds == 0, or
// 2. LastTransitionTime (is set) + minReadySeconds < current time
func IsPodAvailable(pod *Pod, minReadySeconds int32, now unversioned.Time) bool {
if !IsPodReady(pod) {
return false
}
c := GetPodReadyCondition(pod.Status)
minReadySecondsDuration := time.Duration(minReadySeconds) * time.Second
if minReadySeconds == 0 || !c.LastTransitionTime.IsZero() && c.LastTransitionTime.Add(minReadySecondsDuration).Before(now.Time) {
return true
}
return false
}
// IsPodReady returns true if a pod is ready; false otherwise.
func IsPodReady(pod *Pod) bool {
return IsPodReadyConditionTrue(pod.Status)
}
// IsPodReady retruns true if a pod is ready; false otherwise.
func IsPodReadyConditionTrue(status PodStatus) bool {
condition := GetPodReadyCondition(status)
return condition != nil && condition.Status == ConditionTrue
}
// Extracts the pod ready condition from the given status and returns that.
// Returns nil if the condition is not present.
func GetPodReadyCondition(status PodStatus) *PodCondition {
_, condition := GetPodCondition(&status, PodReady)
return condition
}
// GetPodCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func GetPodCondition(status *PodStatus, conditionType PodConditionType) (int, *PodCondition) {
if status == nil {
return -1, nil
}
for i := range status.Conditions {
if status.Conditions[i].Type == conditionType {
return i, &status.Conditions[i]
}
}
return -1, nil
}
// GetNodeCondition extracts the provided condition from the given status and returns that.
// Returns nil and -1 if the condition is not present, and the index of the located condition.
func GetNodeCondition(status *NodeStatus, conditionType NodeConditionType) (int, *NodeCondition) {
if status == nil {
return -1, nil
}
for i := range status.Conditions {
if status.Conditions[i].Type == conditionType {
return i, &status.Conditions[i]
}
}
return -1, nil
}
// Updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the
// status has changed.
// Returns true if pod condition has changed or has been added.
func UpdatePodCondition(status *PodStatus, condition *PodCondition) bool {
condition.LastTransitionTime = unversioned.Now()
// Try to find this pod condition.
conditionIndex, oldCondition := GetPodCondition(status, condition.Type)
if oldCondition == nil {
// We are adding new pod condition.
status.Conditions = append(status.Conditions, *condition)
return true
} else {
// We are updating an existing condition, so we need to check if it has changed.
if condition.Status == oldCondition.Status {
condition.LastTransitionTime = oldCondition.LastTransitionTime
}
isEqual := condition.Status == oldCondition.Status &&
condition.Reason == oldCondition.Reason &&
condition.Message == oldCondition.Message &&
condition.LastProbeTime.Equal(oldCondition.LastProbeTime) &&
condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime)
status.Conditions[conditionIndex] = *condition
// Return true if one of the fields have changed.
return !isEqual
}
}
// IsNodeReady returns true if a node is ready; false otherwise.
func IsNodeReady(node *Node) bool {
for _, c := range node.Status.Conditions {
if c.Type == NodeReady {
return c.Status == ConditionTrue
}
}
return false
}
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
// containers of the pod.
func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, limits map[ResourceName]resource.Quantity, err error) {
reqs, limits = map[ResourceName]resource.Quantity{}, map[ResourceName]resource.Quantity{}
for _, container := range pod.Spec.Containers {
for name, quantity := range container.Resources.Requests {
if value, ok := reqs[name]; !ok {
reqs[name] = *quantity.Copy()
} else {
value.Add(quantity)
reqs[name] = value
}
}
for name, quantity := range container.Resources.Limits {
if value, ok := limits[name]; !ok {
limits[name] = *quantity.Copy()
} else {
value.Add(quantity)
limits[name] = value
}
}
}
// init containers define the minimum of any resource
for _, container := range pod.Spec.InitContainers {
for name, quantity := range container.Resources.Requests {
value, ok := reqs[name]
if !ok {
reqs[name] = *quantity.Copy()
continue
}
if quantity.Cmp(value) > 0 {
reqs[name] = *quantity.Copy()
}
}
for name, quantity := range container.Resources.Limits {
value, ok := limits[name]
if !ok {
limits[name] = *quantity.Copy()
continue
}
if quantity.Cmp(value) > 0 {
limits[name] = *quantity.Copy()
}
}
}
return
}

View File

@ -0,0 +1,120 @@
/*
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 v1
import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
)
func TestResourceHelpers(t *testing.T) {
cpuLimit := resource.MustParse("10")
memoryLimit := resource.MustParse("10G")
resourceSpec := ResourceRequirements{
Limits: ResourceList{
"cpu": cpuLimit,
"memory": memoryLimit,
"kube.io/storage": memoryLimit,
},
}
if res := resourceSpec.Limits.Cpu(); res.Cmp(cpuLimit) != 0 {
t.Errorf("expected cpulimit %v, got %v", cpuLimit, res)
}
if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
}
resourceSpec = ResourceRequirements{
Limits: ResourceList{
"memory": memoryLimit,
"kube.io/storage": memoryLimit,
},
}
if res := resourceSpec.Limits.Cpu(); res.Value() != 0 {
t.Errorf("expected cpulimit %v, got %v", 0, res)
}
if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
}
}
func TestDefaultResourceHelpers(t *testing.T) {
resourceList := ResourceList{}
if resourceList.Cpu().Format != resource.DecimalSI {
t.Errorf("expected %v, actual %v", resource.DecimalSI, resourceList.Cpu().Format)
}
if resourceList.Memory().Format != resource.BinarySI {
t.Errorf("expected %v, actual %v", resource.BinarySI, resourceList.Memory().Format)
}
}
func newPod(now unversioned.Time, ready bool, beforeSec int) *Pod {
conditionStatus := ConditionFalse
if ready {
conditionStatus = ConditionTrue
}
return &Pod{
Status: PodStatus{
Conditions: []PodCondition{
{
Type: PodReady,
LastTransitionTime: unversioned.NewTime(now.Time.Add(-1 * time.Duration(beforeSec) * time.Second)),
Status: conditionStatus,
},
},
},
}
}
func TestIsPodAvailable(t *testing.T) {
now := unversioned.Now()
tests := []struct {
pod *Pod
minReadySeconds int32
expected bool
}{
{
pod: newPod(now, false, 0),
minReadySeconds: 0,
expected: false,
},
{
pod: newPod(now, true, 0),
minReadySeconds: 1,
expected: false,
},
{
pod: newPod(now, true, 0),
minReadySeconds: 0,
expected: true,
},
{
pod: newPod(now, true, 51),
minReadySeconds: 50,
expected: true,
},
}
for i, test := range tests {
isAvailable := IsPodAvailable(test.pod, test.minReadySeconds, now)
if isAvailable != test.expected {
t.Errorf("[tc #%d] expected available pod: %t, got: %t", i, test.expected, isAvailable)
}
}
}

36
pkg/api/v1/service/BUILD Normal file
View File

@ -0,0 +1,36 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"annotations.go",
"util.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/util/net/sets:go_default_library",
"//vendor:github.com/golang/glog",
],
)
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/util/net/sets:go_default_library",
],
)

View File

@ -0,0 +1,111 @@
/*
Copyright 2016 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 service
import (
"strconv"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api/v1"
)
const (
// AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers
//
// It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to
// allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow
// access only from the CIDRs currently allocated to MIT & the USPS.
//
// Not all cloud providers support this annotation, though AWS & GCE do.
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
// AnnotationValueExternalTrafficLocal Value of annotation to specify local endpoints behaviour
AnnotationValueExternalTrafficLocal = "OnlyLocal"
// AnnotationValueExternalTrafficGlobal Value of annotation to specify global (legacy) behaviour
AnnotationValueExternalTrafficGlobal = "Global"
// TODO: The alpha annotations have been deprecated, remove them when we move this feature to GA.
// AlphaAnnotationHealthCheckNodePort Annotation specifying the healthcheck nodePort for the service
// If not specified, annotation is created by the service api backend with the allocated nodePort
// Will use user-specified nodePort value if specified by the client
AlphaAnnotationHealthCheckNodePort = "service.alpha.kubernetes.io/healthcheck-nodeport"
// AlphaAnnotationExternalTraffic An annotation that denotes if this Service desires to route external traffic to local
// endpoints only. This preserves Source IP and avoids a second hop.
AlphaAnnotationExternalTraffic = "service.alpha.kubernetes.io/external-traffic"
// BetaAnnotationHealthCheckNodePort is the beta version of AlphaAnnotationHealthCheckNodePort.
BetaAnnotationHealthCheckNodePort = "service.beta.kubernetes.io/healthcheck-nodeport"
// BetaAnnotationExternalTraffic is the beta version of AlphaAnnotationExternalTraffic.
BetaAnnotationExternalTraffic = "service.beta.kubernetes.io/external-traffic"
)
// NeedsHealthCheck Check service for health check annotations
func NeedsHealthCheck(service *v1.Service) bool {
// First check the alpha annotation and then the beta. This is so existing
// Services continue to work till the user decides to transition to beta.
// If they transition to beta, there's no way to go back to alpha without
// rolling back the cluster.
for _, annotation := range []string{AlphaAnnotationExternalTraffic, BetaAnnotationExternalTraffic} {
if l, ok := service.Annotations[annotation]; ok {
if l == AnnotationValueExternalTrafficLocal {
return true
} else if l == AnnotationValueExternalTrafficGlobal {
return false
} else {
glog.Errorf("Invalid value for annotation %v: %v", annotation, l)
}
}
}
return false
}
// GetServiceHealthCheckNodePort Return health check node port annotation for service, if one exists
func GetServiceHealthCheckNodePort(service *v1.Service) int32 {
if !NeedsHealthCheck(service) {
return 0
}
// First check the alpha annotation and then the beta. This is so existing
// Services continue to work till the user decides to transition to beta.
// If they transition to beta, there's no way to go back to alpha without
// rolling back the cluster.
for _, annotation := range []string{AlphaAnnotationHealthCheckNodePort, BetaAnnotationHealthCheckNodePort} {
if l, ok := service.Annotations[annotation]; ok {
p, err := strconv.Atoi(l)
if err != nil {
glog.Errorf("Failed to parse annotation %v: %v", annotation, err)
continue
}
return int32(p)
}
}
return 0
}
// GetServiceHealthCheckPathPort Return the path and nodePort programmed into the Cloud LB Health Check
func GetServiceHealthCheckPathPort(service *v1.Service) (string, int32) {
if !NeedsHealthCheck(service) {
return "", 0
}
port := GetServiceHealthCheckNodePort(service)
if port == 0 {
return "", 0
}
return "/healthz", port
}

View File

@ -0,0 +1,68 @@
/*
Copyright 2016 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 service
import (
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api/v1"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
)
const (
defaultLoadBalancerSourceRanges = "0.0.0.0/0"
)
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0
func IsAllowAll(ipnets netsets.IPNet) bool {
for _, s := range ipnets.StringSlice() {
if s == "0.0.0.0/0" {
return true
}
}
return false
}
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service.
// If the field is not specified, turn to parse and verify the AnnotationLoadBalancerSourceRangesKey annotation from a service,
// extracting the source ranges to allow, and if not present returns a default (allow-all) value.
func GetLoadBalancerSourceRanges(service *v1.Service) (netsets.IPNet, error) {
var ipnets netsets.IPNet
var err error
// if SourceRange field is specified, ignore sourceRange annotation
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
specs := service.Spec.LoadBalancerSourceRanges
ipnets, err = netsets.ParseIPNets(specs...)
if err != nil {
return nil, fmt.Errorf("service.Spec.LoadBalancerSourceRanges: %v is not valid. Expecting a list of IP ranges. For example, 10.0.0.0/24. Error msg: %v", specs, err)
}
} else {
val := service.Annotations[AnnotationLoadBalancerSourceRangesKey]
val = strings.TrimSpace(val)
if val == "" {
val = defaultLoadBalancerSourceRanges
}
specs := strings.Split(val, ",")
ipnets, err = netsets.ParseIPNets(specs...)
if err != nil {
return nil, fmt.Errorf("%s: %s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", AnnotationLoadBalancerSourceRangesKey, val)
}
}
return ipnets, nil
}

View File

@ -0,0 +1,131 @@
/*
Copyright 2016 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 service
import (
"testing"
"strings"
"k8s.io/kubernetes/pkg/api/v1"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
)
func TestGetLoadBalancerSourceRanges(t *testing.T) {
checkError := func(v string) {
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = v
svc := v1.Service{}
svc.Annotations = annotations
_, err := GetLoadBalancerSourceRanges(&svc)
if err == nil {
t.Errorf("Expected error parsing: %q", v)
}
svc = v1.Service{}
svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",")
_, err = GetLoadBalancerSourceRanges(&svc)
if err == nil {
t.Errorf("Expected error parsing: %q", v)
}
}
checkError("10.0.0.1/33")
checkError("foo.bar")
checkError("10.0.0.1/32,*")
checkError("10.0.0.1/32,")
checkError("10.0.0.1/32, ")
checkError("10.0.0.1")
checkOK := func(v string) netsets.IPNet {
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = v
svc := v1.Service{}
svc.Annotations = annotations
cidrs, err := GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error parsing: %q", v)
}
svc = v1.Service{}
svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",")
cidrs, err = GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error parsing: %q", v)
}
return cidrs
}
cidrs := checkOK("192.168.0.1/32")
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice())
}
cidrs = checkOK("192.168.0.1/32,192.168.0.1/32")
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR (after de-dup): %v", cidrs.StringSlice())
}
cidrs = checkOK("192.168.0.1/32,192.168.0.2/32")
if len(cidrs) != 2 {
t.Errorf("Expected two CIDRs: %v", cidrs.StringSlice())
}
cidrs = checkOK(" 192.168.0.1/32 , 192.168.0.2/32 ")
if len(cidrs) != 2 {
t.Errorf("Expected two CIDRs: %v", cidrs.StringSlice())
}
// check LoadBalancerSourceRanges not specified
svc := v1.Service{}
cidrs, err := GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice())
}
if !IsAllowAll(cidrs) {
t.Errorf("Expected default to be allow-all: %v", cidrs.StringSlice())
}
// check SourceRanges annotation is empty
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = ""
svc = v1.Service{}
svc.Annotations = annotations
cidrs, err = GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice())
}
if !IsAllowAll(cidrs) {
t.Errorf("Expected default to be allow-all: %v", cidrs.StringSlice())
}
}
func TestAllowAll(t *testing.T) {
checkAllowAll := func(allowAll bool, cidrs ...string) {
ipnets, err := netsets.ParseIPNets(cidrs...)
if err != nil {
t.Errorf("Unexpected error parsing cidrs: %v", cidrs)
}
if allowAll != IsAllowAll(ipnets) {
t.Errorf("IsAllowAll did not return expected value for %v", cidrs)
}
}
checkAllowAll(false, "10.0.0.1/32")
checkAllowAll(false, "10.0.0.1/32", "10.0.0.2/32")
checkAllowAll(false, "10.0.0.1/32", "10.0.0.1/32")
checkAllowAll(true, "0.0.0.0/0")
checkAllowAll(true, "192.168.0.0/0")
checkAllowAll(true, "192.168.0.1/32", "0.0.0.0/0")
}

View File

@ -2995,6 +2995,8 @@ const (
NodeDiskPressure NodeConditionType = "DiskPressure"
// NodeNetworkUnavailable means that network for the node is not correctly configured.
NodeNetworkUnavailable NodeConditionType = "NetworkUnavailable"
// NodeInodePressure means the kublet is under pressure due to insufficient available inodes.
NodeInodePressure NodeConditionType = "InodePressure"
)
// NodeCondition contains condition information for a node.
@ -3056,6 +3058,11 @@ const (
// Number of Pods that may be running on this Node: see ResourcePods
)
const (
// Namespace prefix for opaque counted resources (alpha).
ResourceOpaqueIntPrefix = "pod.alpha.kubernetes.io/opaque-int-resource-"
)
// ResourceList is a set of (resource name, quantity) pairs.
type ResourceList map[ResourceName]resource.Quantity
@ -3790,6 +3797,35 @@ const (
// DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets
DockerConfigKey = ".dockercfg"
// SecretTypeDockerConfigJson contains a dockercfg file that follows the same format rules as ~/.docker/config.json
//
// Required fields:
// - Secret.Data[".dockerconfigjson"] - a serialized ~/.docker/config.json file
SecretTypeDockerConfigJson SecretType = "kubernetes.io/dockerconfigjson"
// DockerConfigJsonKey is the key of the required data for SecretTypeDockerConfigJson secrets
DockerConfigJsonKey = ".dockerconfigjson"
// SecretTypeBasicAuth contains data needed for basic authentication.
//
// Required at least one of fields:
// - Secret.Data["username"] - username used for authentication
// - Secret.Data["password"] - password or token needed for authentication
SecretTypeBasicAuth SecretType = "kubernetes.io/basic-auth"
// BasicAuthUsernameKey is the key of the username for SecretTypeBasicAuth secrets
BasicAuthUsernameKey = "username"
// BasicAuthPasswordKey is the key of the password or token for SecretTypeBasicAuth secrets
BasicAuthPasswordKey = "password"
// SecretTypeSSHAuth contains data needed for SSH authetication.
//
// Required field:
// - Secret.Data["ssh-privatekey"] - private SSH key needed for authentication
SecretTypeSSHAuth SecretType = "kubernetes.io/ssh-auth"
// SSHAuthPrivateKey is the key of the required SSH private key for SecretTypeSSHAuth secrets
SSHAuthPrivateKey = "ssh-privatekey"
// SecretTypeTLS contains information about a TLS client or server secret. It
// is primarily used with TLS termination of the Ingress resource, but may be
// used in other types.
@ -4011,4 +4047,14 @@ type RangeAllocation struct {
const (
// "default-scheduler" is the name of default scheduler.
DefaultSchedulerName = "default-scheduler"
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
// corresponding to every RequiredDuringScheduling affinity rule.
// When the --hard-pod-affinity-weight scheduler flag is not specified,
// DefaultHardPodAffinityWeight defines the weight of the implicit PreferredDuringScheduling affinity rule.
DefaultHardPodAffinitySymmetricWeight int = 1
// When the --failure-domains scheduler flag is not specified,
// DefaultFailureDomains defines the set of label keys used when TopologyKey is empty in PreferredDuringScheduling anti-affinity.
DefaultFailureDomains string = unversioned.LabelHostname + "," + unversioned.LabelZoneFailureDomain + "," + unversioned.LabelZoneRegion
)

View File

@ -0,0 +1,25 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["validation.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/resource:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/util/sets:go_default_library",
"//pkg/util/validation:go_default_library",
"//pkg/util/validation/field:go_default_library",
],
)

View File

@ -0,0 +1,159 @@
/*
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 validation
import (
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/validation"
"k8s.io/kubernetes/pkg/util/validation/field"
)
const isNegativeErrorMsg string = `must be greater than or equal to 0`
const isNotIntegerErrorMsg string = `must be an integer`
func ValidateResourceRequirements(requirements *v1.ResourceRequirements, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
limPath := fldPath.Child("limits")
reqPath := fldPath.Child("requests")
for resourceName, quantity := range requirements.Limits {
fldPath := limPath.Key(string(resourceName))
// Validate resource name.
allErrs = append(allErrs, validateContainerResourceName(string(resourceName), fldPath)...)
// Validate resource quantity.
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
// Check that request <= limit.
requestQuantity, exists := requirements.Requests[resourceName]
if exists {
// For GPUs, not only requests can't exceed limits, they also can't be lower, i.e. must be equal.
if resourceName == v1.ResourceNvidiaGPU && quantity.Cmp(requestQuantity) != 0 {
allErrs = append(allErrs, field.Invalid(reqPath, requestQuantity.String(), fmt.Sprintf("must be equal to %s limit", v1.ResourceNvidiaGPU)))
} else if quantity.Cmp(requestQuantity) < 0 {
allErrs = append(allErrs, field.Invalid(limPath, quantity.String(), fmt.Sprintf("must be greater than or equal to %s request", resourceName)))
}
}
}
for resourceName, quantity := range requirements.Requests {
fldPath := reqPath.Key(string(resourceName))
// Validate resource name.
allErrs = append(allErrs, validateContainerResourceName(string(resourceName), fldPath)...)
// Validate resource quantity.
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
}
return allErrs
}
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
allErrs := validateResourceName(value, fldPath)
if len(strings.Split(value, "/")) == 1 {
if !api.IsStandardContainerResourceName(value) {
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
}
}
return field.ErrorList{}
}
// ValidateResourceQuantityValue enforces that specified quantity is valid for specified resource
func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...)
if api.IsIntegerResourceName(resource) {
if value.MilliValue()%int64(1000) != int64(0) {
allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg))
}
}
return allErrs
}
// Validates that a Quantity is not negative
func ValidateNonnegativeQuantity(value resource.Quantity, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if value.Cmp(resource.Quantity{}) < 0 {
allErrs = append(allErrs, field.Invalid(fldPath, value.String(), isNegativeErrorMsg))
}
return allErrs
}
// Validate compute resource typename.
// Refer to docs/design/resources.md for more details.
func validateResourceName(value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, msg := range validation.IsQualifiedName(value) {
allErrs = append(allErrs, field.Invalid(fldPath, value, msg))
}
if len(allErrs) != 0 {
return allErrs
}
if len(strings.Split(value, "/")) == 1 {
if !api.IsStandardResourceName(value) {
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified"))
}
}
return field.ErrorList{}
}
func ValidatePodLogOptions(opts *v1.PodLogOptions) field.ErrorList {
allErrs := field.ErrorList{}
if opts.TailLines != nil && *opts.TailLines < 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("tailLines"), *opts.TailLines, isNegativeErrorMsg))
}
if opts.LimitBytes != nil && *opts.LimitBytes < 1 {
allErrs = append(allErrs, field.Invalid(field.NewPath("limitBytes"), *opts.LimitBytes, "must be greater than 0"))
}
switch {
case opts.SinceSeconds != nil && opts.SinceTime != nil:
allErrs = append(allErrs, field.Forbidden(field.NewPath(""), "at most one of `sinceTime` or `sinceSeconds` may be specified"))
case opts.SinceSeconds != nil:
if *opts.SinceSeconds < 1 {
allErrs = append(allErrs, field.Invalid(field.NewPath("sinceSeconds"), *opts.SinceSeconds, "must be greater than 0"))
}
}
return allErrs
}
func AccumulateUniqueHostPorts(containers []v1.Container, accumulator *sets.String, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for ci, ctr := range containers {
idxPath := fldPath.Index(ci)
portsPath := idxPath.Child("ports")
for pi := range ctr.Ports {
idxPath := portsPath.Index(pi)
port := ctr.Ports[pi].HostPort
if port == 0 {
continue
}
str := fmt.Sprintf("%d/%s", port, ctr.Ports[pi].Protocol)
if accumulator.Has(str) {
allErrs = append(allErrs, field.Duplicate(idxPath.Child("hostPort"), str))
} else {
accumulator.Insert(str)
}
}
}
return allErrs
}

View File

@ -189,6 +189,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_NodeList_To_v1_NodeList,
Convert_v1_NodeProxyOptions_To_api_NodeProxyOptions,
Convert_api_NodeProxyOptions_To_v1_NodeProxyOptions,
Convert_v1_NodeResources_To_api_NodeResources,
Convert_api_NodeResources_To_v1_NodeResources,
Convert_v1_NodeSelector_To_api_NodeSelector,
Convert_api_NodeSelector_To_v1_NodeSelector,
Convert_v1_NodeSelectorRequirement_To_api_NodeSelectorRequirement,
@ -333,6 +335,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_ServiceSpec_To_v1_ServiceSpec,
Convert_v1_ServiceStatus_To_api_ServiceStatus,
Convert_api_ServiceStatus_To_v1_ServiceStatus,
Convert_v1_Sysctl_To_api_Sysctl,
Convert_api_Sysctl_To_v1_Sysctl,
Convert_v1_TCPSocketAction_To_api_TCPSocketAction,
Convert_api_TCPSocketAction_To_v1_TCPSocketAction,
Convert_v1_Taint_To_api_Taint,
@ -2152,6 +2156,24 @@ func Convert_api_NodeProxyOptions_To_v1_NodeProxyOptions(in *api.NodeProxyOption
return autoConvert_api_NodeProxyOptions_To_v1_NodeProxyOptions(in, out, s)
}
func autoConvert_v1_NodeResources_To_api_NodeResources(in *NodeResources, out *api.NodeResources, s conversion.Scope) error {
out.Capacity = *(*api.ResourceList)(unsafe.Pointer(&in.Capacity))
return nil
}
func Convert_v1_NodeResources_To_api_NodeResources(in *NodeResources, out *api.NodeResources, s conversion.Scope) error {
return autoConvert_v1_NodeResources_To_api_NodeResources(in, out, s)
}
func autoConvert_api_NodeResources_To_v1_NodeResources(in *api.NodeResources, out *NodeResources, s conversion.Scope) error {
out.Capacity = *(*ResourceList)(unsafe.Pointer(&in.Capacity))
return nil
}
func Convert_api_NodeResources_To_v1_NodeResources(in *api.NodeResources, out *NodeResources, s conversion.Scope) error {
return autoConvert_api_NodeResources_To_v1_NodeResources(in, out, s)
}
func autoConvert_v1_NodeSelector_To_api_NodeSelector(in *NodeSelector, out *api.NodeSelector, s conversion.Scope) error {
out.NodeSelectorTerms = *(*[]api.NodeSelectorTerm)(unsafe.Pointer(&in.NodeSelectorTerms))
return nil
@ -4155,6 +4177,26 @@ func Convert_api_ServiceStatus_To_v1_ServiceStatus(in *api.ServiceStatus, out *S
return autoConvert_api_ServiceStatus_To_v1_ServiceStatus(in, out, s)
}
func autoConvert_v1_Sysctl_To_api_Sysctl(in *Sysctl, out *api.Sysctl, s conversion.Scope) error {
out.Name = in.Name
out.Value = in.Value
return nil
}
func Convert_v1_Sysctl_To_api_Sysctl(in *Sysctl, out *api.Sysctl, s conversion.Scope) error {
return autoConvert_v1_Sysctl_To_api_Sysctl(in, out, s)
}
func autoConvert_api_Sysctl_To_v1_Sysctl(in *api.Sysctl, out *Sysctl, s conversion.Scope) error {
out.Name = in.Name
out.Value = in.Value
return nil
}
func Convert_api_Sysctl_To_v1_Sysctl(in *api.Sysctl, out *Sysctl, s conversion.Scope) error {
return autoConvert_api_Sysctl_To_v1_Sysctl(in, out, s)
}
func autoConvert_v1_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error {
out.Port = in.Port
return nil

View File

@ -112,6 +112,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeDaemonEndpoints, InType: reflect.TypeOf(&NodeDaemonEndpoints{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeList, InType: reflect.TypeOf(&NodeList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeProxyOptions, InType: reflect.TypeOf(&NodeProxyOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeResources, InType: reflect.TypeOf(&NodeResources{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeSelector, InType: reflect.TypeOf(&NodeSelector{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeSelectorRequirement, InType: reflect.TypeOf(&NodeSelectorRequirement{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_NodeSelectorTerm, InType: reflect.TypeOf(&NodeSelectorTerm{})},
@ -184,6 +185,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_ServiceProxyOptions, InType: reflect.TypeOf(&ServiceProxyOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_ServiceSpec, InType: reflect.TypeOf(&ServiceSpec{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_ServiceStatus, InType: reflect.TypeOf(&ServiceStatus{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Sysctl, InType: reflect.TypeOf(&Sysctl{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_TCPSocketAction, InType: reflect.TypeOf(&TCPSocketAction{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Taint, InType: reflect.TypeOf(&Taint{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_Toleration, InType: reflect.TypeOf(&Toleration{})},
@ -1689,6 +1691,23 @@ func DeepCopy_v1_NodeProxyOptions(in interface{}, out interface{}, c *conversion
}
}
func DeepCopy_v1_NodeResources(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*NodeResources)
out := out.(*NodeResources)
if in.Capacity != nil {
in, out := &in.Capacity, &out.Capacity
*out = make(ResourceList)
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
} else {
out.Capacity = nil
}
return nil
}
}
func DeepCopy_v1_NodeSelector(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*NodeSelector)
@ -3494,6 +3513,16 @@ func DeepCopy_v1_ServiceStatus(in interface{}, out interface{}, c *conversion.Cl
}
}
func DeepCopy_v1_Sysctl(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Sysctl)
out := out.(*Sysctl)
out.Name = in.Name
out.Value = in.Value
return nil
}
}
func DeepCopy_v1_TCPSocketAction(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TCPSocketAction)

View File

@ -16,6 +16,7 @@ go_library(
"defaults.go",
"doc.go",
"generated.pb.go",
"helpers.go",
"register.go",
"types.generated.go",
"types.go",

View File

@ -27,9 +27,11 @@ limitations under the License.
It has these top-level messages:
ClusterRole
ClusterRoleBinding
ClusterRoleBindingBuilder
ClusterRoleBindingList
ClusterRoleList
PolicyRule
PolicyRuleBuilder
Role
RoleBinding
RoleBindingList
@ -65,48 +67,60 @@ func (m *ClusterRoleBinding) Reset() { *m = ClusterRoleBindin
func (*ClusterRoleBinding) ProtoMessage() {}
func (*ClusterRoleBinding) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} }
func (m *ClusterRoleBindingBuilder) Reset() { *m = ClusterRoleBindingBuilder{} }
func (*ClusterRoleBindingBuilder) ProtoMessage() {}
func (*ClusterRoleBindingBuilder) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{2}
}
func (m *ClusterRoleBindingList) Reset() { *m = ClusterRoleBindingList{} }
func (*ClusterRoleBindingList) ProtoMessage() {}
func (*ClusterRoleBindingList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
func (*ClusterRoleBindingList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{3} }
func (m *ClusterRoleList) Reset() { *m = ClusterRoleList{} }
func (*ClusterRoleList) ProtoMessage() {}
func (*ClusterRoleList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{3} }
func (*ClusterRoleList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} }
func (m *PolicyRule) Reset() { *m = PolicyRule{} }
func (*PolicyRule) ProtoMessage() {}
func (*PolicyRule) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{4} }
func (*PolicyRule) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} }
func (m *PolicyRuleBuilder) Reset() { *m = PolicyRuleBuilder{} }
func (*PolicyRuleBuilder) ProtoMessage() {}
func (*PolicyRuleBuilder) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{6} }
func (m *Role) Reset() { *m = Role{} }
func (*Role) ProtoMessage() {}
func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} }
func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{7} }
func (m *RoleBinding) Reset() { *m = RoleBinding{} }
func (*RoleBinding) ProtoMessage() {}
func (*RoleBinding) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{6} }
func (*RoleBinding) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} }
func (m *RoleBindingList) Reset() { *m = RoleBindingList{} }
func (*RoleBindingList) ProtoMessage() {}
func (*RoleBindingList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{7} }
func (*RoleBindingList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} }
func (m *RoleList) Reset() { *m = RoleList{} }
func (*RoleList) ProtoMessage() {}
func (*RoleList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} }
func (*RoleList) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} }
func (m *RoleRef) Reset() { *m = RoleRef{} }
func (*RoleRef) ProtoMessage() {}
func (*RoleRef) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} }
func (*RoleRef) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} }
func (m *Subject) Reset() { *m = Subject{} }
func (*Subject) ProtoMessage() {}
func (*Subject) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} }
func (*Subject) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} }
func init() {
proto.RegisterType((*ClusterRole)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRole")
proto.RegisterType((*ClusterRoleBinding)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleBinding")
proto.RegisterType((*ClusterRoleBindingBuilder)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleBindingBuilder")
proto.RegisterType((*ClusterRoleBindingList)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleBindingList")
proto.RegisterType((*ClusterRoleList)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleList")
proto.RegisterType((*PolicyRule)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.PolicyRule")
proto.RegisterType((*PolicyRuleBuilder)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.PolicyRuleBuilder")
proto.RegisterType((*Role)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.Role")
proto.RegisterType((*RoleBinding)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.RoleBinding")
proto.RegisterType((*RoleBindingList)(nil), "k8s.io.kubernetes.pkg.apis.rbac.v1alpha1.RoleBindingList")
@ -198,6 +212,32 @@ func (m *ClusterRoleBinding) MarshalTo(data []byte) (int, error) {
return i, nil
}
func (m *ClusterRoleBindingBuilder) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
n, err := m.MarshalTo(data)
if err != nil {
return nil, err
}
return data[:n], nil
}
func (m *ClusterRoleBindingBuilder) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ClusterRoleBinding.Size()))
n4, err := m.ClusterRoleBinding.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n4
return i, nil
}
func (m *ClusterRoleBindingList) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
@ -216,11 +256,11 @@ func (m *ClusterRoleBindingList) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size()))
n4, err := m.ListMeta.MarshalTo(data[i:])
n5, err := m.ListMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n4
i += n5
if len(m.Items) > 0 {
for _, msg := range m.Items {
data[i] = 0x12
@ -254,11 +294,11 @@ func (m *ClusterRoleList) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size()))
n5, err := m.ListMeta.MarshalTo(data[i:])
n6, err := m.ListMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n5
i += n6
if len(m.Items) > 0 {
for _, msg := range m.Items {
data[i] = 0x12
@ -307,11 +347,11 @@ func (m *PolicyRule) MarshalTo(data []byte) (int, error) {
data[i] = 0x12
i++
i = encodeVarintGenerated(data, i, uint64(m.AttributeRestrictions.Size()))
n6, err := m.AttributeRestrictions.MarshalTo(data[i:])
n7, err := m.AttributeRestrictions.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n6
i += n7
if len(m.APIGroups) > 0 {
for _, s := range m.APIGroups {
data[i] = 0x1a
@ -375,6 +415,32 @@ func (m *PolicyRule) MarshalTo(data []byte) (int, error) {
return i, nil
}
func (m *PolicyRuleBuilder) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
n, err := m.MarshalTo(data)
if err != nil {
return nil, err
}
return data[:n], nil
}
func (m *PolicyRuleBuilder) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.PolicyRule.Size()))
n8, err := m.PolicyRule.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n8
return i, nil
}
func (m *Role) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
@ -393,11 +459,11 @@ func (m *Role) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size()))
n7, err := m.ObjectMeta.MarshalTo(data[i:])
n9, err := m.ObjectMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n7
i += n9
if len(m.Rules) > 0 {
for _, msg := range m.Rules {
data[i] = 0x12
@ -431,11 +497,11 @@ func (m *RoleBinding) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size()))
n8, err := m.ObjectMeta.MarshalTo(data[i:])
n10, err := m.ObjectMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n8
i += n10
if len(m.Subjects) > 0 {
for _, msg := range m.Subjects {
data[i] = 0x12
@ -451,11 +517,11 @@ func (m *RoleBinding) MarshalTo(data []byte) (int, error) {
data[i] = 0x1a
i++
i = encodeVarintGenerated(data, i, uint64(m.RoleRef.Size()))
n9, err := m.RoleRef.MarshalTo(data[i:])
n11, err := m.RoleRef.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n9
i += n11
return i, nil
}
@ -477,11 +543,11 @@ func (m *RoleBindingList) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size()))
n10, err := m.ListMeta.MarshalTo(data[i:])
n12, err := m.ListMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n10
i += n12
if len(m.Items) > 0 {
for _, msg := range m.Items {
data[i] = 0x12
@ -515,11 +581,11 @@ func (m *RoleList) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size()))
n11, err := m.ListMeta.MarshalTo(data[i:])
n13, err := m.ListMeta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n11
i += n13
if len(m.Items) > 0 {
for _, msg := range m.Items {
data[i] = 0x12
@ -656,6 +722,14 @@ func (m *ClusterRoleBinding) Size() (n int) {
return n
}
func (m *ClusterRoleBindingBuilder) Size() (n int) {
var l int
_ = l
l = m.ClusterRoleBinding.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
func (m *ClusterRoleBindingList) Size() (n int) {
var l int
_ = l
@ -722,6 +796,14 @@ func (m *PolicyRule) Size() (n int) {
return n
}
func (m *PolicyRuleBuilder) Size() (n int) {
var l int
_ = l
l = m.PolicyRule.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
func (m *Role) Size() (n int) {
var l int
_ = l
@ -842,6 +924,16 @@ func (this *ClusterRoleBinding) String() string {
}, "")
return s
}
func (this *ClusterRoleBindingBuilder) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ClusterRoleBindingBuilder{`,
`ClusterRoleBinding:` + strings.Replace(strings.Replace(this.ClusterRoleBinding.String(), "ClusterRoleBinding", "ClusterRoleBinding", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func (this *ClusterRoleBindingList) String() string {
if this == nil {
return "nil"
@ -879,6 +971,16 @@ func (this *PolicyRule) String() string {
}, "")
return s
}
func (this *PolicyRuleBuilder) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&PolicyRuleBuilder{`,
`PolicyRule:` + strings.Replace(strings.Replace(this.PolicyRule.String(), "PolicyRule", "PolicyRule", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func (this *Role) String() string {
if this == nil {
return "nil"
@ -1209,6 +1311,86 @@ func (m *ClusterRoleBinding) Unmarshal(data []byte) error {
}
return nil
}
func (m *ClusterRoleBindingBuilder) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ClusterRoleBindingBuilder: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ClusterRoleBindingBuilder: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClusterRoleBinding", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.ClusterRoleBinding.Unmarshal(data[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ClusterRoleBindingList) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
@ -1656,6 +1838,86 @@ func (m *PolicyRule) Unmarshal(data []byte) error {
}
return nil
}
func (m *PolicyRuleBuilder) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PolicyRuleBuilder: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PolicyRuleBuilder: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PolicyRule", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.PolicyRule.Unmarshal(data[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Role) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
@ -2539,56 +2801,60 @@ var (
)
var fileDescriptorGenerated = []byte{
// 815 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x54, 0x41, 0x6b, 0xe3, 0x46,
0x18, 0xb5, 0x62, 0xbb, 0xb1, 0xc6, 0x35, 0x6e, 0x54, 0x52, 0x84, 0xa1, 0xb2, 0xf1, 0xc9, 0x34,
0xc9, 0x08, 0x9b, 0x86, 0xe6, 0xd0, 0x1e, 0xa2, 0x52, 0x4a, 0x68, 0x9a, 0x86, 0x09, 0x0d, 0x6d,
0x68, 0x29, 0x63, 0x7b, 0xe2, 0x4c, 0x2d, 0x4b, 0x62, 0x66, 0xe4, 0xb6, 0xf4, 0x12, 0xf6, 0x17,
0xec, 0xaf, 0xd8, 0xdb, 0x5e, 0xf6, 0xba, 0xb0, 0x87, 0x3d, 0xe5, 0xb0, 0x87, 0x1c, 0x97, 0x3d,
0x98, 0x8d, 0xf6, 0x8f, 0x2c, 0x1a, 0x49, 0x96, 0x1d, 0xdb, 0x1b, 0x27, 0xb0, 0x81, 0x85, 0x3d,
0x25, 0xf3, 0x7d, 0xef, 0xbd, 0xf9, 0xde, 0xe7, 0xd1, 0x03, 0x3b, 0xfd, 0x1d, 0x0e, 0xa9, 0x6b,
0xf6, 0xfd, 0x36, 0x61, 0x0e, 0x11, 0x84, 0x9b, 0x5e, 0xbf, 0x67, 0x62, 0x8f, 0x72, 0x93, 0xb5,
0x71, 0xc7, 0x1c, 0x36, 0xb1, 0xed, 0x9d, 0xe1, 0xa6, 0xd9, 0x23, 0x0e, 0x61, 0x58, 0x90, 0x2e,
0xf4, 0x98, 0x2b, 0x5c, 0xad, 0x11, 0x31, 0x61, 0xca, 0x84, 0x5e, 0xbf, 0x07, 0x43, 0x26, 0x0c,
0x99, 0x30, 0x61, 0x56, 0xb6, 0x7a, 0x54, 0x9c, 0xf9, 0x6d, 0xd8, 0x71, 0x07, 0x66, 0xcf, 0xed,
0xb9, 0xa6, 0x14, 0x68, 0xfb, 0xa7, 0xf2, 0x24, 0x0f, 0xf2, 0xbf, 0x48, 0xb8, 0xd2, 0x5a, 0x38,
0x92, 0xc9, 0x08, 0x77, 0x7d, 0xd6, 0x21, 0xd7, 0x87, 0xa9, 0x6c, 0x2f, 0xe6, 0xf8, 0xce, 0x90,
0x30, 0x4e, 0x5d, 0x87, 0x74, 0x67, 0x68, 0x9b, 0x8b, 0x69, 0xc3, 0x19, 0xc7, 0x95, 0xad, 0xf9,
0x68, 0xe6, 0x3b, 0x82, 0x0e, 0x66, 0x67, 0x6a, 0xce, 0x87, 0xfb, 0x82, 0xda, 0x26, 0x75, 0x04,
0x17, 0xec, 0x3a, 0xa5, 0xfe, 0x5c, 0x01, 0xc5, 0xef, 0x6d, 0x9f, 0x0b, 0xc2, 0x90, 0x6b, 0x13,
0xed, 0x37, 0x50, 0x18, 0x10, 0x81, 0xbb, 0x58, 0x60, 0x5d, 0xa9, 0x29, 0x8d, 0x62, 0xab, 0x01,
0x17, 0xae, 0x1d, 0x0e, 0x9b, 0xf0, 0x97, 0xf6, 0xdf, 0xa4, 0x23, 0x7e, 0x26, 0x02, 0x5b, 0xda,
0xc5, 0xa8, 0x9a, 0x09, 0x46, 0x55, 0x90, 0xd6, 0xd0, 0x58, 0x4d, 0xfb, 0x1d, 0xe4, 0x99, 0x6f,
0x13, 0xae, 0xaf, 0xd4, 0xb2, 0x8d, 0x62, 0xeb, 0x6b, 0xb8, 0xec, 0xaf, 0x09, 0x0f, 0x5d, 0x9b,
0x76, 0xfe, 0x43, 0xbe, 0x4d, 0xac, 0x52, 0x7c, 0x45, 0x3e, 0x3c, 0x71, 0x14, 0x29, 0xd6, 0x1f,
0xaf, 0x00, 0x6d, 0xc2, 0x84, 0x45, 0x9d, 0x2e, 0x75, 0x7a, 0xef, 0xd1, 0xcb, 0x5f, 0xa0, 0xc0,
0x7d, 0xd9, 0x48, 0xec, 0x34, 0x97, 0xb7, 0x73, 0x14, 0x31, 0xad, 0xcf, 0xe2, 0x2b, 0x0a, 0x71,
0x81, 0xa3, 0xb1, 0xa8, 0xf6, 0x07, 0x58, 0x65, 0xae, 0x4d, 0x10, 0x39, 0xd5, 0xb3, 0x72, 0xf2,
0x5b, 0xe8, 0xa3, 0x88, 0x68, 0x95, 0x63, 0xfd, 0xd5, 0xb8, 0x80, 0x12, 0xc9, 0xfa, 0x2b, 0x05,
0x7c, 0x31, 0xbb, 0xaf, 0x7d, 0xca, 0x85, 0xf6, 0xe7, 0xcc, 0xce, 0xcc, 0x77, 0xec, 0x6c, 0xe2,
0xa5, 0xc3, 0x90, 0x2e, 0x57, 0x37, 0xf6, 0x95, 0x54, 0x26, 0x16, 0x87, 0x41, 0x9e, 0x0a, 0x32,
0x48, 0xb6, 0xf6, 0xed, 0xf2, 0xae, 0x66, 0xe7, 0x4d, 0x1f, 0xc3, 0x5e, 0x28, 0x89, 0x22, 0xe5,
0xfa, 0x0b, 0x05, 0x94, 0x27, 0xc0, 0xf7, 0xe1, 0xea, 0x64, 0xda, 0xd5, 0xf6, 0xdd, 0x5c, 0xcd,
0xb7, 0xf3, 0x20, 0x0b, 0x40, 0xfa, 0x01, 0x68, 0x55, 0x90, 0x1f, 0x12, 0xd6, 0xe6, 0xba, 0x52,
0xcb, 0x36, 0x54, 0x4b, 0x0d, 0xf1, 0xc7, 0x61, 0x01, 0x45, 0x75, 0xed, 0x5c, 0x01, 0xeb, 0x58,
0x08, 0x46, 0xdb, 0xbe, 0x20, 0x88, 0x70, 0xc1, 0x68, 0x47, 0x50, 0xd7, 0x09, 0x87, 0x0b, 0x8d,
0x6f, 0x2c, 0x18, 0x2e, 0xce, 0x14, 0x88, 0xf0, 0x3f, 0x3f, 0xfc, 0x2b, 0x88, 0x13, 0xfa, 0xb7,
0xbe, 0x8c, 0x47, 0x5a, 0xdf, 0x9d, 0xa7, 0x88, 0xe6, 0x5f, 0xa4, 0x6d, 0x00, 0x15, 0x7b, 0xf4,
0x47, 0xe6, 0xfa, 0x1e, 0xd7, 0xb3, 0x72, 0xce, 0x52, 0x30, 0xaa, 0xaa, 0xbb, 0x87, 0x7b, 0x51,
0x11, 0xa5, 0xfd, 0x10, 0x9c, 0x64, 0x2c, 0xd7, 0x73, 0x29, 0x18, 0x25, 0x45, 0x94, 0xf6, 0xb5,
0x6f, 0x40, 0x29, 0x39, 0x1c, 0xe0, 0x01, 0xe1, 0x7a, 0x5e, 0x12, 0xd6, 0x82, 0x51, 0xb5, 0x84,
0x26, 0x1b, 0x68, 0x1a, 0xa7, 0x7d, 0x07, 0xca, 0x8e, 0xeb, 0x24, 0x90, 0x5f, 0xd1, 0x3e, 0xd7,
0x3f, 0x91, 0xd4, 0xcf, 0x83, 0x51, 0xb5, 0x7c, 0x30, 0xdd, 0x42, 0xd7, 0xb1, 0xf5, 0xa7, 0x0a,
0xc8, 0x7d, 0xb8, 0xf1, 0xf8, 0x68, 0x05, 0x14, 0x3f, 0xe6, 0xe2, 0x12, 0xb9, 0x18, 0x46, 0xc7,
0x3d, 0x07, 0xe2, 0xdd, 0xa3, 0xe3, 0xe6, 0x24, 0x7c, 0xa6, 0x80, 0xc2, 0x7d, 0x45, 0xe0, 0xd1,
0xb4, 0x0f, 0x78, 0x4b, 0x1f, 0xf3, 0x0d, 0xfc, 0x0f, 0x92, 0xdf, 0x48, 0xdb, 0x04, 0x85, 0x24,
0x33, 0xe4, 0xf8, 0x6a, 0x3a, 0x4d, 0x12, 0x2b, 0x68, 0x8c, 0xd0, 0x6a, 0x20, 0xd7, 0xa7, 0x4e,
0x57, 0x46, 0x9e, 0x6a, 0x7d, 0x1a, 0x23, 0x73, 0x3f, 0x51, 0xa7, 0x8b, 0x64, 0x27, 0x44, 0x38,
0x78, 0x40, 0xe4, 0x2b, 0x9a, 0x40, 0x84, 0x69, 0x81, 0x64, 0xa7, 0xfe, 0x44, 0x01, 0xab, 0xf1,
0x0b, 0x1c, 0xeb, 0x29, 0x0b, 0xf5, 0x5a, 0x00, 0x60, 0x8f, 0x1e, 0x47, 0x4b, 0x8b, 0xef, 0x1d,
0x7f, 0x2b, 0xbb, 0x87, 0x7b, 0x71, 0x07, 0x4d, 0xa0, 0x6e, 0x9e, 0x41, 0x33, 0x81, 0x1a, 0xfe,
0xe5, 0x1e, 0xee, 0x10, 0x3d, 0x27, 0x61, 0x6b, 0x31, 0x4c, 0x3d, 0x48, 0x1a, 0x28, 0xc5, 0x58,
0x5f, 0x5d, 0x5c, 0x19, 0x99, 0xcb, 0x2b, 0x23, 0xf3, 0xf2, 0xca, 0xc8, 0x9c, 0x07, 0x86, 0x72,
0x11, 0x18, 0xca, 0x65, 0x60, 0x28, 0xaf, 0x03, 0x43, 0x79, 0xf8, 0xc6, 0xc8, 0x9c, 0x14, 0x92,
0xc5, 0xbf, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x62, 0x32, 0x8a, 0x1f, 0x89, 0x0b, 0x00, 0x00,
// 875 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x55, 0xcf, 0x8b, 0x23, 0x45,
0x14, 0x4e, 0x4d, 0x12, 0x27, 0x79, 0xe3, 0x30, 0x4e, 0xc9, 0x4a, 0x1b, 0x30, 0x19, 0x72, 0x0a,
0xee, 0x6e, 0x37, 0x19, 0x5c, 0xdc, 0x83, 0x1e, 0xa6, 0x45, 0x64, 0x70, 0x1d, 0x87, 0x5a, 0x5c,
0x74, 0x51, 0xa4, 0x92, 0xd4, 0x66, 0xca, 0x74, 0xba, 0x9b, 0xaa, 0xea, 0xa8, 0x88, 0xb0, 0x78,
0xf2, 0xe8, 0x5f, 0xb1, 0x37, 0x2f, 0x5e, 0x05, 0x0f, 0x9e, 0xe6, 0xe0, 0x61, 0x8f, 0xe2, 0x21,
0x38, 0xf1, 0x1f, 0x91, 0xae, 0xae, 0xfe, 0x31, 0x93, 0x8e, 0x9b, 0x19, 0x71, 0x40, 0xd8, 0x53,
0xd2, 0xef, 0x7d, 0xdf, 0x57, 0xef, 0xab, 0x57, 0xf5, 0x0a, 0xee, 0x4e, 0xee, 0x4a, 0x9b, 0x07,
0xce, 0x24, 0x1a, 0x30, 0xe1, 0x33, 0xc5, 0xa4, 0x13, 0x4e, 0xc6, 0x0e, 0x0d, 0xb9, 0x74, 0xc4,
0x80, 0x0e, 0x9d, 0x59, 0x9f, 0x7a, 0xe1, 0x09, 0xed, 0x3b, 0x63, 0xe6, 0x33, 0x41, 0x15, 0x1b,
0xd9, 0xa1, 0x08, 0x54, 0x80, 0x7b, 0x09, 0xd3, 0xce, 0x99, 0x76, 0x38, 0x19, 0xdb, 0x31, 0xd3,
0x8e, 0x99, 0x76, 0xca, 0x6c, 0xdd, 0x1e, 0x73, 0x75, 0x12, 0x0d, 0xec, 0x61, 0x30, 0x75, 0xc6,
0xc1, 0x38, 0x70, 0xb4, 0xc0, 0x20, 0x7a, 0xa4, 0xbf, 0xf4, 0x87, 0xfe, 0x97, 0x08, 0xb7, 0xf6,
0x57, 0x96, 0xe4, 0x08, 0x26, 0x83, 0x48, 0x0c, 0xd9, 0xc5, 0x62, 0x5a, 0x77, 0x56, 0x73, 0x22,
0x7f, 0xc6, 0x84, 0xe4, 0x81, 0xcf, 0x46, 0x4b, 0xb4, 0x5b, 0xab, 0x69, 0xb3, 0x25, 0xc7, 0xad,
0xdb, 0xe5, 0x68, 0x11, 0xf9, 0x8a, 0x4f, 0x97, 0x6b, 0xea, 0x97, 0xc3, 0x23, 0xc5, 0x3d, 0x87,
0xfb, 0x4a, 0x2a, 0x71, 0x91, 0xd2, 0xfd, 0x15, 0xc1, 0xd6, 0x3b, 0x5e, 0x24, 0x15, 0x13, 0x24,
0xf0, 0x18, 0xfe, 0x18, 0x1a, 0x53, 0xa6, 0xe8, 0x88, 0x2a, 0x6a, 0xa1, 0x3d, 0xd4, 0xdb, 0xda,
0xef, 0xd9, 0x2b, 0xb7, 0xdd, 0x9e, 0xf5, 0xed, 0x0f, 0x07, 0x5f, 0xb0, 0xa1, 0xfa, 0x80, 0x29,
0xea, 0xe2, 0xd3, 0x79, 0xa7, 0xb2, 0x98, 0x77, 0x20, 0x8f, 0x91, 0x4c, 0x0d, 0x7f, 0x02, 0x75,
0x11, 0x79, 0x4c, 0x5a, 0x1b, 0x7b, 0xd5, 0xde, 0xd6, 0xfe, 0x1b, 0xf6, 0xba, 0xdd, 0xb4, 0x8f,
0x03, 0x8f, 0x0f, 0xbf, 0x26, 0x91, 0xc7, 0xdc, 0x6d, 0xb3, 0x44, 0x3d, 0xfe, 0x92, 0x24, 0x51,
0xec, 0xfe, 0xb8, 0x01, 0xb8, 0x60, 0xc2, 0xe5, 0xfe, 0x88, 0xfb, 0xe3, 0xff, 0xd0, 0xcb, 0xe7,
0xd0, 0x90, 0x91, 0x4e, 0xa4, 0x76, 0xfa, 0xeb, 0xdb, 0xb9, 0x9f, 0x30, 0xdd, 0x97, 0xcc, 0x12,
0x0d, 0x13, 0x90, 0x24, 0x13, 0xc5, 0x9f, 0xc2, 0xa6, 0x08, 0x3c, 0x46, 0xd8, 0x23, 0xab, 0xaa,
0x2b, 0xbf, 0x84, 0x3e, 0x49, 0x88, 0xee, 0x8e, 0xd1, 0xdf, 0x34, 0x01, 0x92, 0x4a, 0x76, 0x9f,
0x20, 0x78, 0x75, 0x79, 0xbf, 0xdc, 0x88, 0x7b, 0x23, 0x26, 0xf0, 0xf7, 0x08, 0xf0, 0x70, 0x29,
0x6b, 0x76, 0xf0, 0xad, 0xf5, 0xeb, 0x28, 0x59, 0xa1, 0x65, 0x4a, 0x2a, 0xe9, 0x16, 0x29, 0x59,
0xb3, 0xfb, 0x07, 0x82, 0x57, 0x96, 0xa1, 0xf7, 0xb8, 0x54, 0xf8, 0xb3, 0xa5, 0xe6, 0x3a, 0xff,
0xd0, 0xdc, 0xc2, 0x95, 0xb4, 0x63, 0xba, 0xee, 0x71, 0xd6, 0x80, 0x34, 0x52, 0xe8, 0x30, 0x85,
0x3a, 0x57, 0x6c, 0x9a, 0xb6, 0xf7, 0xdf, 0xd9, 0xce, 0x4e, 0xed, 0x61, 0x2c, 0x49, 0x12, 0xe5,
0xee, 0x6f, 0x08, 0x76, 0x0a, 0xe0, 0xeb, 0x70, 0xf5, 0xf0, 0xbc, 0xab, 0x3b, 0x57, 0x73, 0x55,
0x6e, 0xe7, 0xbb, 0x2a, 0x40, 0x7e, 0x53, 0x71, 0x07, 0xea, 0x33, 0x26, 0x06, 0xd2, 0x42, 0x7b,
0xd5, 0x5e, 0xd3, 0x6d, 0xc6, 0xf8, 0x07, 0x71, 0x80, 0x24, 0x71, 0xfc, 0x18, 0xc1, 0x0d, 0xaa,
0x94, 0xe0, 0x83, 0x48, 0x31, 0xc2, 0xa4, 0x12, 0x7c, 0xa8, 0x78, 0xe0, 0xc7, 0xc5, 0xc5, 0xc6,
0x6f, 0xae, 0x28, 0xce, 0x0c, 0x3f, 0x9b, 0xd0, 0x2f, 0xdf, 0xfd, 0x4a, 0x31, 0x3f, 0xf6, 0xef,
0xbe, 0x66, 0x4a, 0xba, 0x71, 0x50, 0xa6, 0x48, 0xca, 0x17, 0xc2, 0x37, 0xa1, 0x49, 0x43, 0xfe,
0x9e, 0x08, 0xa2, 0x50, 0x5a, 0x55, 0x5d, 0xe7, 0xf6, 0x62, 0xde, 0x69, 0x1e, 0x1c, 0x1f, 0x26,
0x41, 0x92, 0xe7, 0x63, 0x70, 0xfa, 0x18, 0x48, 0xab, 0x96, 0x83, 0x49, 0x1a, 0x24, 0x79, 0x1e,
0xbf, 0x09, 0xdb, 0xe9, 0xc7, 0x11, 0x9d, 0x32, 0x69, 0xd5, 0x35, 0x61, 0x77, 0x31, 0xef, 0x6c,
0x93, 0x62, 0x82, 0x9c, 0xc7, 0xe1, 0xb7, 0x61, 0xc7, 0x0f, 0xfc, 0x14, 0xf2, 0x11, 0xb9, 0x27,
0xad, 0x17, 0x34, 0xf5, 0xe5, 0xc5, 0xbc, 0xb3, 0x73, 0x74, 0x3e, 0x45, 0x2e, 0x62, 0xbb, 0xdf,
0xc2, 0x6e, 0x61, 0x5a, 0x9a, 0x0b, 0x7d, 0x02, 0x10, 0x66, 0x41, 0x73, 0xac, 0xae, 0x36, 0x7e,
0xb3, 0xa9, 0x98, 0xc7, 0x48, 0x41, 0xbb, 0xfb, 0x33, 0x82, 0xda, 0xff, 0xf7, 0x19, 0x79, 0xb2,
0x01, 0x5b, 0xcf, 0xdf, 0x8f, 0x35, 0xde, 0x8f, 0x78, 0x72, 0x5d, 0xf3, 0x3c, 0xbe, 0xfa, 0xe4,
0x7a, 0xf6, 0x20, 0xfe, 0x05, 0x41, 0xe3, 0xba, 0x26, 0xf0, 0xfd, 0xf3, 0x3e, 0xec, 0x4b, 0xfa,
0x28, 0x37, 0xf0, 0x0d, 0xa4, 0x3d, 0xc2, 0xb7, 0xa0, 0x91, 0x8e, 0x2c, 0x5d, 0x7e, 0x33, 0xaf,
0x26, 0x9d, 0x6a, 0x24, 0x43, 0xe0, 0x3d, 0xa8, 0x4d, 0xb8, 0x3f, 0xd2, 0x13, 0xb7, 0xe9, 0xbe,
0x68, 0x90, 0xb5, 0xf7, 0xb9, 0x3f, 0x22, 0x3a, 0x13, 0x23, 0x7c, 0x3a, 0x65, 0xfa, 0x14, 0x15,
0x10, 0xf1, 0xb0, 0x22, 0x3a, 0xd3, 0xfd, 0x09, 0xc1, 0xa6, 0x39, 0x81, 0x99, 0x1e, 0x5a, 0xa9,
0xb7, 0x0f, 0x40, 0x43, 0xfe, 0x20, 0xd9, 0x34, 0xb3, 0x6e, 0x76, 0x57, 0x0e, 0x8e, 0x0f, 0x4d,
0x86, 0x14, 0x50, 0xcf, 0xae, 0x01, 0x3b, 0xd0, 0x8c, 0x7f, 0x65, 0x48, 0x87, 0xcc, 0xaa, 0x69,
0xd8, 0xae, 0x81, 0x35, 0x8f, 0xd2, 0x04, 0xc9, 0x31, 0xee, 0xeb, 0xa7, 0x67, 0xed, 0xca, 0xd3,
0xb3, 0x76, 0xe5, 0xf7, 0xb3, 0x76, 0xe5, 0xf1, 0xa2, 0x8d, 0x4e, 0x17, 0x6d, 0xf4, 0x74, 0xd1,
0x46, 0x7f, 0x2e, 0xda, 0xe8, 0x87, 0xbf, 0xda, 0x95, 0x87, 0x8d, 0x74, 0xe3, 0xff, 0x0e, 0x00,
0x00, 0xff, 0xff, 0x90, 0x88, 0x4e, 0x35, 0xb1, 0x0c, 0x00, 0x00,
}

View File

@ -55,6 +55,14 @@ message ClusterRoleBinding {
optional RoleRef roleRef = 3;
}
// +k8s:deepcopy-gen=false
// ClusterRoleBindingBuilder let's us attach methods. A no-no for API types.
// We use it to construct bindings in code. It's more compact than trying to write them
// out in a literal.
message ClusterRoleBindingBuilder {
optional ClusterRoleBinding clusterRoleBinding = 1;
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings
message ClusterRoleBindingList {
// Standard object's metadata.
@ -107,6 +115,14 @@ message PolicyRule {
repeated string nonResourceURLs = 6;
}
// +k8s:deepcopy-gen=false
// PolicyRuleBuilder let's us attach methods. A no-no for API types.
// We use it to construct rules in code. It's more compact than trying to write them
// out in a literal and allows us to perform some basic checking during construction
message PolicyRuleBuilder {
optional PolicyRule policyRule = 1;
}
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
message Role {
// Standard object's metadata.

View File

@ -0,0 +1,148 @@
/*
Copyright 2016 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 v1alpha1
import (
"fmt"
"k8s.io/kubernetes/pkg/api/v1"
)
// +k8s:deepcopy-gen=false
// PolicyRuleBuilder let's us attach methods. A no-no for API types.
// We use it to construct rules in code. It's more compact than trying to write them
// out in a literal and allows us to perform some basic checking during construction
type PolicyRuleBuilder struct {
PolicyRule PolicyRule
}
func NewRule(verbs ...string) *PolicyRuleBuilder {
return &PolicyRuleBuilder{
PolicyRule: PolicyRule{Verbs: verbs},
}
}
func (r *PolicyRuleBuilder) Groups(groups ...string) *PolicyRuleBuilder {
r.PolicyRule.APIGroups = append(r.PolicyRule.APIGroups, groups...)
return r
}
func (r *PolicyRuleBuilder) Resources(resources ...string) *PolicyRuleBuilder {
r.PolicyRule.Resources = append(r.PolicyRule.Resources, resources...)
return r
}
func (r *PolicyRuleBuilder) Names(names ...string) *PolicyRuleBuilder {
r.PolicyRule.ResourceNames = append(r.PolicyRule.ResourceNames, names...)
return r
}
func (r *PolicyRuleBuilder) URLs(urls ...string) *PolicyRuleBuilder {
r.PolicyRule.NonResourceURLs = append(r.PolicyRule.NonResourceURLs, urls...)
return r
}
func (r *PolicyRuleBuilder) RuleOrDie() PolicyRule {
ret, err := r.Rule()
if err != nil {
panic(err)
}
return ret
}
func (r *PolicyRuleBuilder) Rule() (PolicyRule, error) {
if len(r.PolicyRule.Verbs) == 0 {
return PolicyRule{}, fmt.Errorf("verbs are required: %#v", r.PolicyRule)
}
switch {
case len(r.PolicyRule.NonResourceURLs) > 0:
if len(r.PolicyRule.APIGroups) != 0 || len(r.PolicyRule.Resources) != 0 || len(r.PolicyRule.ResourceNames) != 0 {
return PolicyRule{}, fmt.Errorf("non-resource rule may not have apiGroups, resources, or resourceNames: %#v", r.PolicyRule)
}
case len(r.PolicyRule.Resources) > 0:
if len(r.PolicyRule.NonResourceURLs) != 0 {
return PolicyRule{}, fmt.Errorf("resource rule may not have nonResourceURLs: %#v", r.PolicyRule)
}
if len(r.PolicyRule.APIGroups) == 0 {
// this a common bug
return PolicyRule{}, fmt.Errorf("resource rule must have apiGroups: %#v", r.PolicyRule)
}
default:
return PolicyRule{}, fmt.Errorf("a rule must have either nonResourceURLs or resources: %#v", r.PolicyRule)
}
return r.PolicyRule, nil
}
// +k8s:deepcopy-gen=false
// ClusterRoleBindingBuilder let's us attach methods. A no-no for API types.
// We use it to construct bindings in code. It's more compact than trying to write them
// out in a literal.
type ClusterRoleBindingBuilder struct {
ClusterRoleBinding ClusterRoleBinding
}
func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {
return &ClusterRoleBindingBuilder{
ClusterRoleBinding: ClusterRoleBinding{
ObjectMeta: v1.ObjectMeta{Name: clusterRoleName},
RoleRef: RoleRef{
APIGroup: GroupName,
Kind: "ClusterRole",
Name: clusterRoleName,
},
},
}
}
func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, Name: group})
}
return r
}
func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, Name: user})
}
return r
}
func (r *ClusterRoleBindingBuilder) SAs(namespace string, serviceAccountNames ...string) *ClusterRoleBindingBuilder {
for _, saName := range serviceAccountNames {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: ServiceAccountKind, Namespace: namespace, Name: saName})
}
return r
}
func (r *ClusterRoleBindingBuilder) BindingOrDie() ClusterRoleBinding {
ret, err := r.Binding()
if err != nil {
panic(err)
}
return ret
}
func (r *ClusterRoleBindingBuilder) Binding() (ClusterRoleBinding, error) {
if len(r.ClusterRoleBinding.Subjects) == 0 {
return ClusterRoleBinding{}, fmt.Errorf("subjects are required: %#v", r.ClusterRoleBinding)
}
return r.ClusterRoleBinding, nil
}

View File

@ -27,6 +27,24 @@ import (
// 2. evaluation of RoleBindings in the namespace requested - short circuit on match
// 3. deny by default
const (
APIGroupAll = "*"
ResourceAll = "*"
VerbAll = "*"
NonResourceAll = "*"
GroupKind = "Group"
ServiceAccountKind = "ServiceAccount"
UserKind = "User"
UserAll = "*"
)
// Authorization is calculated against
// 1. evaluation of ClusterRoleBindings - short circuit on match
// 2. evaluation of RoleBindings in the namespace requested - short circuit on match
// 3. deny by default
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
type PolicyRule struct {

View File

@ -39,12 +39,16 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_rbac_ClusterRole_To_v1alpha1_ClusterRole,
Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding,
Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding,
Convert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder,
Convert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder,
Convert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList,
Convert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList,
Convert_v1alpha1_ClusterRoleList_To_rbac_ClusterRoleList,
Convert_rbac_ClusterRoleList_To_v1alpha1_ClusterRoleList,
Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule,
Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule,
Convert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder,
Convert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder,
Convert_v1alpha1_Role_To_rbac_Role,
Convert_rbac_Role_To_v1alpha1_Role,
Convert_v1alpha1_RoleBinding_To_rbac_RoleBinding,
@ -138,6 +142,28 @@ func Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in *rbac.Clu
return autoConvert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in *ClusterRoleBindingBuilder, out *rbac.ClusterRoleBindingBuilder, s conversion.Scope) error {
if err := Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(&in.ClusterRoleBinding, &out.ClusterRoleBinding, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in *ClusterRoleBindingBuilder, out *rbac.ClusterRoleBindingBuilder, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in, out, s)
}
func autoConvert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in *rbac.ClusterRoleBindingBuilder, out *ClusterRoleBindingBuilder, s conversion.Scope) error {
if err := Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(&in.ClusterRoleBinding, &out.ClusterRoleBinding, s); err != nil {
return err
}
return nil
}
func Convert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in *rbac.ClusterRoleBindingBuilder, out *ClusterRoleBindingBuilder, s conversion.Scope) error {
return autoConvert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in *ClusterRoleBindingList, out *rbac.ClusterRoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]rbac.ClusterRoleBinding)(unsafe.Pointer(&in.Items))
@ -230,6 +256,28 @@ func Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(in *rbac.PolicyRule, out *Po
return autoConvert_rbac_PolicyRule_To_v1alpha1_PolicyRule(in, out, s)
}
func autoConvert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in *PolicyRuleBuilder, out *rbac.PolicyRuleBuilder, s conversion.Scope) error {
if err := Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule(&in.PolicyRule, &out.PolicyRule, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in *PolicyRuleBuilder, out *rbac.PolicyRuleBuilder, s conversion.Scope) error {
return autoConvert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in, out, s)
}
func autoConvert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in *rbac.PolicyRuleBuilder, out *PolicyRuleBuilder, s conversion.Scope) error {
if err := Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(&in.PolicyRule, &out.PolicyRule, s); err != nil {
return err
}
return nil
}
func Convert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in *rbac.PolicyRuleBuilder, out *PolicyRuleBuilder, s conversion.Scope) error {
return autoConvert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in, out, s)
}
func autoConvert_v1alpha1_Role_To_rbac_Role(in *Role, out *rbac.Role, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {

View File

@ -0,0 +1,18 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["helpers.go"],
tags = ["automanaged"],
deps = ["//pkg/api/v1:go_default_library"],
)

View File

@ -0,0 +1,134 @@
/*
Copyright 2016 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 util
import "k8s.io/kubernetes/pkg/api/v1"
// IsDefaultStorageClassAnnotation represents a StorageClass annotation that
// marks a class as the default StorageClass
//TODO: Update IsDefaultStorageClassannotation and remove Beta when no longer used
const IsDefaultStorageClassAnnotation = "storageclass.beta.kubernetes.io/is-default-class"
const BetaIsDefaultStorageClassAnnotation = "storageclass.beta.kubernetes.io/is-default-class"
// AlphaStorageClassAnnotation represents the previous alpha storage class
// annotation. it's no longer used and held here for posterity.
const AlphaStorageClassAnnotation = "volume.alpha.kubernetes.io/storage-class"
// BetaStorageClassAnnotation represents the beta/previous StorageClass annotation.
// It's currently still used and will be held for backwards compatibility
const BetaStorageClassAnnotation = "volume.beta.kubernetes.io/storage-class"
// StorageClassAnnotation represents the storage class associated with a resource.
// It currently matches the Beta value and can change when official is set.
// - in PersistentVolumeClaim it represents required class to match.
// Only PersistentVolumes with the same class (i.e. annotation with the same
// value) can be bound to the claim. In case no such volume exists, the
// controller will provision a new one using StorageClass instance with
// the same name as the annotation value.
// - in PersistentVolume it represents storage class to which the persistent
// volume belongs.
//TODO: Update this to final annotation value as it matches BetaStorageClassAnnotation for now
const StorageClassAnnotation = "volume.beta.kubernetes.io/storage-class"
// GetVolumeStorageClass returns value of StorageClassAnnotation or empty string in case
// the annotation does not exist.
// TODO: change to PersistentVolume.Spec.Class value when this attribute is
// introduced.
func GetVolumeStorageClass(volume *v1.PersistentVolume) string {
if class, found := volume.Annotations[StorageClassAnnotation]; found {
return class
}
// 'nil' is interpreted as "", i.e. the volume does not belong to any class.
return ""
}
// GetClaimStorageClass returns name of class that is requested by given claim.
// Request for `nil` class is interpreted as request for class "",
// i.e. for a classless PV.
// TODO: change to PersistentVolumeClaim.Spec.Class value when this
// attribute is introduced.
func GetClaimStorageClass(claim *v1.PersistentVolumeClaim) string {
if class, found := claim.Annotations[StorageClassAnnotation]; found {
return class
}
return ""
}
// GetStorageClassAnnotation returns the StorageClass value
// if the annotation is set, empty string if not
// TODO: remove Alpha and Beta when no longer used or needed
func GetStorageClassAnnotation(obj v1.ObjectMeta) string {
if class, ok := obj.Annotations[StorageClassAnnotation]; ok {
return class
}
if class, ok := obj.Annotations[BetaStorageClassAnnotation]; ok {
return class
}
if class, ok := obj.Annotations[AlphaStorageClassAnnotation]; ok {
return class
}
return ""
}
// HasStorageClassAnnotation returns a boolean
// if the annotation is set
// TODO: remove Alpha and Beta when no longer used or needed
func HasStorageClassAnnotation(obj v1.ObjectMeta) bool {
if _, found := obj.Annotations[StorageClassAnnotation]; found {
return found
}
if _, found := obj.Annotations[BetaStorageClassAnnotation]; found {
return found
}
if _, found := obj.Annotations[AlphaStorageClassAnnotation]; found {
return found
}
return false
}
// IsDefaultAnnotationText returns a pretty Yes/No String if
// the annotation is set
// TODO: remove Beta when no longer needed
func IsDefaultAnnotationText(obj v1.ObjectMeta) string {
if obj.Annotations[IsDefaultStorageClassAnnotation] == "true" {
return "Yes"
}
if obj.Annotations[BetaIsDefaultStorageClassAnnotation] == "true" {
return "Yes"
}
return "No"
}
// IsDefaultAnnotation returns a boolean if
// the annotation is set
// TODO: remove Beta when no longer needed
func IsDefaultAnnotation(obj v1.ObjectMeta) bool {
if obj.Annotations[IsDefaultStorageClassAnnotation] == "true" {
return true
}
if obj.Annotations[BetaIsDefaultStorageClassAnnotation] == "true" {
return true
}
return false
}

View File

@ -39,12 +39,15 @@ go_library(
"//pkg/api/errors:go_default_library",
"//pkg/api/meta:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/certificates:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/apis/certificates/v1alpha1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/policy/v1beta1:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/v1beta1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/fields:go_default_library",
"//pkg/labels:go_default_library",
@ -82,8 +85,9 @@ go_test(
"//pkg/api/errors:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apimachinery/registered:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/testing/cache:go_default_library",

View File

@ -23,7 +23,7 @@ import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
fcache "k8s.io/kubernetes/pkg/client/testing/cache"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
@ -51,7 +51,7 @@ func Example() {
cfg := &Config{
Queue: fifo,
ListerWatcher: source,
ObjectType: &api.Pod{},
ObjectType: &v1.Pod{},
FullResyncPeriod: time.Millisecond * 100,
RetryOnError: false,
@ -101,7 +101,7 @@ func Example() {
for _, name := range testIDs {
// Note that these pods are not valid-- the fake source doesn't
// call validation or anything.
source.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: name}})
source.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: name}})
}
// Let's wait for the controller to process the things we just added.
@ -130,7 +130,7 @@ func ExampleNewInformer() {
// logs anything deleted.
_, controller := NewInformer(
source,
&api.Pod{},
&v1.Pod{},
time.Millisecond*100,
ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
@ -158,7 +158,7 @@ func ExampleNewInformer() {
for _, name := range testIDs {
// Note that these pods are not valid-- the fake source doesn't
// call validation or anything.
source.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: name}})
source.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: name}})
}
// Let's wait for the controller to process the things we just added.
@ -206,7 +206,7 @@ func TestHammerController(t *testing.T) {
// Make a controller which just logs all the changes it gets.
_, controller := NewInformer(
source,
&api.Pod{},
&v1.Pod{},
time.Millisecond*100,
ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { recordFunc("add", obj) },
@ -253,7 +253,7 @@ func TestHammerController(t *testing.T) {
name = l[r.Intn(len(l))]
}
pod := &api.Pod{}
pod := &v1.Pod{}
f.Fuzz(pod)
pod.ObjectMeta.Name = name
pod.ObjectMeta.Namespace = "default"
@ -315,9 +315,9 @@ func TestUpdate(t *testing.T) {
pair{FROM, FROM}: true,
}
pod := func(name, check string, final bool) *api.Pod {
p := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := func(name, check string, final bool) *v1.Pod {
p := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: name,
Labels: map[string]string{"check": check},
},
@ -327,7 +327,7 @@ func TestUpdate(t *testing.T) {
}
return p
}
deletePod := func(p *api.Pod) bool {
deletePod := func(p *v1.Pod) bool {
return p.Labels["final"] == "true"
}
@ -350,20 +350,20 @@ func TestUpdate(t *testing.T) {
watchCh := make(chan struct{})
_, controller := NewInformer(
&testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
watch, err := source.Watch(options)
close(watchCh)
return watch, err
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return source.List(options)
},
},
&api.Pod{},
&v1.Pod{},
0,
ResourceEventHandlerFuncs{
UpdateFunc: func(oldObj, newObj interface{}) {
o, n := oldObj.(*api.Pod), newObj.(*api.Pod)
o, n := oldObj.(*v1.Pod), newObj.(*v1.Pod)
from, to := o.Labels["check"], n.Labels["check"]
if !allowedTransitions[pair{from, to}] {
t.Errorf("observed transition %q -> %q for %v", from, to, n.Name)

View File

@ -21,19 +21,20 @@ import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
func testIndexFunc(obj interface{}) ([]string, error) {
pod := obj.(*api.Pod)
pod := obj.(*v1.Pod)
return []string{pod.Labels["foo"]}, nil
}
func TestGetIndexFuncValues(t *testing.T) {
index := NewIndexer(MetaNamespaceKeyFunc, Indexers{"testmodes": testIndexFunc})
pod1 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "one", Labels: map[string]string{"foo": "bar"}}}
pod2 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "two", Labels: map[string]string{"foo": "bar"}}}
pod3 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "tre", Labels: map[string]string{"foo": "biz"}}}
pod1 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "one", Labels: map[string]string{"foo": "bar"}}}
pod2 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "two", Labels: map[string]string{"foo": "bar"}}}
pod3 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "tre", Labels: map[string]string{"foo": "biz"}}}
index.Add(pod1)
index.Add(pod2)
@ -52,7 +53,7 @@ func TestGetIndexFuncValues(t *testing.T) {
}
func testUsersIndexFunc(obj interface{}) ([]string, error) {
pod := obj.(*api.Pod)
pod := obj.(*v1.Pod)
usersString := pod.Annotations["users"]
return strings.Split(usersString, ","), nil
@ -61,9 +62,9 @@ func testUsersIndexFunc(obj interface{}) ([]string, error) {
func TestMultiIndexKeys(t *testing.T) {
index := NewIndexer(MetaNamespaceKeyFunc, Indexers{"byUser": testUsersIndexFunc})
pod1 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "one", Annotations: map[string]string{"users": "ernie,bert"}}}
pod2 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "two", Annotations: map[string]string{"users": "bert,oscar"}}}
pod3 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "tre", Annotations: map[string]string{"users": "ernie,elmo"}}}
pod1 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "one", Annotations: map[string]string{"users": "ernie,bert"}}}
pod2 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "two", Annotations: map[string]string{"users": "bert,oscar"}}}
pod3 := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "tre", Annotations: map[string]string{"users": "ernie,elmo"}}}
index.Add(pod1)
index.Add(pod2)
@ -121,7 +122,7 @@ func TestMultiIndexKeys(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
copyOfPod2 := obj.(*api.Pod)
copyOfPod2 := obj.(*v1.Pod)
copyOfPod2.Annotations["users"] = "oscar"
index.Update(copyOfPod2)
bertPods, err = index.ByIndex("byUser", "bert")

View File

@ -20,15 +20,16 @@ import (
"fmt"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/apis/storage"
"k8s.io/kubernetes/pkg/api/v1"
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
certificates "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
policy "k8s.io/kubernetes/pkg/apis/policy/v1beta1"
storageinternal "k8s.io/kubernetes/pkg/apis/storage"
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
)
@ -50,7 +51,7 @@ func ListAll(store Store, selector labels.Selector, appendFn AppendFunc) error {
}
func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selector, appendFn AppendFunc) error {
if namespace == api.NamespaceAll {
if namespace == v1.NamespaceAll {
for _, m := range indexer.List() {
metadata, err := meta.Accessor(m)
if err != nil {
@ -63,7 +64,7 @@ func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selec
return nil
}
items, err := indexer.Index(NamespaceIndex, &api.ObjectMeta{Namespace: namespace})
items, err := indexer.Index(NamespaceIndex, &v1.ObjectMeta{Namespace: namespace})
if err != nil {
// Ignore error; do slow search without index.
glog.Warningf("can not retrieve list of objects using index : %v", err)
@ -170,7 +171,7 @@ func (s *genericNamespaceLister) Get(name string) (runtime.Object, error) {
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
// some set of criteria defined by the function.
type NodeConditionPredicate func(node *api.Node) bool
type NodeConditionPredicate func(node *v1.Node) bool
// StoreToNodeLister makes a Store have the List method of the client.NodeInterface
// The Store must contain (only) Nodes.
@ -178,9 +179,9 @@ type StoreToNodeLister struct {
Store
}
func (s *StoreToNodeLister) List() (machines api.NodeList, err error) {
func (s *StoreToNodeLister) List() (machines v1.NodeList, err error) {
for _, m := range s.Store.List() {
machines.Items = append(machines.Items, *(m.(*api.Node)))
machines.Items = append(machines.Items, *(m.(*v1.Node)))
}
return machines, nil
}
@ -199,9 +200,9 @@ type storeToNodeConditionLister struct {
}
// List returns a list of nodes that match the conditions defined by the predicate functions in the storeToNodeConditionLister.
func (s storeToNodeConditionLister) List() (nodes []*api.Node, err error) {
func (s storeToNodeConditionLister) List() (nodes []*v1.Node, err error) {
for _, m := range s.store.List() {
node := m.(*api.Node)
node := m.(*v1.Node)
if s.predicate(node) {
nodes = append(nodes, node)
} else {
@ -236,7 +237,7 @@ func (s *StoreToDaemonSetLister) List() (dss extensions.DaemonSetList, err error
// GetPodDaemonSets returns a list of daemon sets managing a pod.
// Returns an error if and only if no matching daemon sets are found.
func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []extensions.DaemonSet, err error) {
func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *v1.Pod) (daemonSets []extensions.DaemonSet, err error) {
var selector labels.Selector
var daemonSet extensions.DaemonSet
@ -274,17 +275,17 @@ type StoreToEndpointsLister struct {
}
// List lists all endpoints in the store.
func (s *StoreToEndpointsLister) List() (services api.EndpointsList, err error) {
func (s *StoreToEndpointsLister) List() (services v1.EndpointsList, err error) {
for _, m := range s.Store.List() {
services.Items = append(services.Items, *(m.(*api.Endpoints)))
services.Items = append(services.Items, *(m.(*v1.Endpoints)))
}
return services, nil
}
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) {
func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *v1.Service) (ep v1.Endpoints, err error) {
for _, m := range s.Store.List() {
ep = *m.(*api.Endpoints)
ep = *m.(*v1.Endpoints)
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
return ep, nil
}
@ -299,8 +300,8 @@ type StoreToPVFetcher struct {
}
// GetPersistentVolumeInfo returns cached data for the PersistentVolume 'id'.
func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*api.PersistentVolume, error) {
o, exists, err := s.Get(&api.PersistentVolume{ObjectMeta: api.ObjectMeta{Name: id}})
func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*v1.PersistentVolume, error) {
o, exists, err := s.Get(&v1.PersistentVolume{ObjectMeta: v1.ObjectMeta{Name: id}})
if err != nil {
return nil, fmt.Errorf("error retrieving PersistentVolume '%v' from cache: %v", id, err)
@ -310,7 +311,7 @@ func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*api.PersistentVo
return nil, fmt.Errorf("PersistentVolume '%v' not found", id)
}
return o.(*api.PersistentVolume), nil
return o.(*v1.PersistentVolume), nil
}
// StoreToStatefulSetLister gives a store List and Exists methods. The store must contain only StatefulSets.
@ -345,7 +346,7 @@ func (s *StoreToStatefulSetLister) StatefulSets(namespace string) storeStatefulS
}
// GetPodStatefulSets returns a list of StatefulSets managing a pod. Returns an error only if no matching StatefulSets are found.
func (s *StoreToStatefulSetLister) GetPodStatefulSets(pod *api.Pod) (psList []apps.StatefulSet, err error) {
func (s *StoreToStatefulSetLister) GetPodStatefulSets(pod *v1.Pod) (psList []apps.StatefulSet, err error) {
var selector labels.Selector
var ps apps.StatefulSet
@ -404,7 +405,7 @@ type StoreToPodDisruptionBudgetLister struct {
}
// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found.
func (s *StoreToPodDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *api.Pod) (pdbList []policy.PodDisruptionBudget, err error) {
func (s *StoreToPodDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *v1.Pod) (pdbList []policy.PodDisruptionBudget, err error) {
var selector labels.Selector
if len(pod.Labels) == 0 {
@ -466,13 +467,13 @@ func (s *storageClassLister) List(selector labels.Selector) (ret []*storage.Stor
// List returns a list of storage classes
func (s *storageClassLister) Get(name string) (*storage.StorageClass, error) {
key := &storage.StorageClass{ObjectMeta: api.ObjectMeta{Name: name}}
key := &storage.StorageClass{ObjectMeta: v1.ObjectMeta{Name: name}}
obj, exists, err := s.indexer.Get(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(storage.Resource("storageclass"), name)
return nil, errors.NewNotFound(storageinternal.Resource("storageclass"), name)
}
return obj.(*storage.StorageClass), nil
}

View File

@ -21,6 +21,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/labels"
)
@ -40,9 +41,9 @@ type StoreToPodLister struct {
Indexer Indexer
}
func (s *StoreToPodLister) List(selector labels.Selector) (ret []*api.Pod, err error) {
func (s *StoreToPodLister) List(selector labels.Selector) (ret []*v1.Pod, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.Pod))
ret = append(ret, m.(*v1.Pod))
})
return ret, err
}
@ -56,14 +57,14 @@ type storePodsNamespacer struct {
namespace string
}
func (s storePodsNamespacer) List(selector labels.Selector) (ret []*api.Pod, err error) {
func (s storePodsNamespacer) List(selector labels.Selector) (ret []*v1.Pod, err error) {
err = ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.Pod))
ret = append(ret, m.(*v1.Pod))
})
return ret, err
}
func (s storePodsNamespacer) Get(name string) (*api.Pod, error) {
func (s storePodsNamespacer) Get(name string) (*v1.Pod, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -71,7 +72,7 @@ func (s storePodsNamespacer) Get(name string) (*api.Pod, error) {
if !exists {
return nil, errors.NewNotFound(api.Resource("pod"), name)
}
return obj.(*api.Pod), nil
return obj.(*v1.Pod), nil
}
// StoreToServiceLister helps list services
@ -79,9 +80,9 @@ type StoreToServiceLister struct {
Indexer Indexer
}
func (s *StoreToServiceLister) List(selector labels.Selector) (ret []*api.Service, err error) {
func (s *StoreToServiceLister) List(selector labels.Selector) (ret []*v1.Service, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.Service))
ret = append(ret, m.(*v1.Service))
})
return ret, err
}
@ -95,14 +96,14 @@ type storeServicesNamespacer struct {
namespace string
}
func (s storeServicesNamespacer) List(selector labels.Selector) (ret []*api.Service, err error) {
func (s storeServicesNamespacer) List(selector labels.Selector) (ret []*v1.Service, err error) {
err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.Service))
ret = append(ret, m.(*v1.Service))
})
return ret, err
}
func (s storeServicesNamespacer) Get(name string) (*api.Service, error) {
func (s storeServicesNamespacer) Get(name string) (*v1.Service, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -110,12 +111,12 @@ func (s storeServicesNamespacer) Get(name string) (*api.Service, error) {
if !exists {
return nil, errors.NewNotFound(api.Resource("service"), name)
}
return obj.(*api.Service), nil
return obj.(*v1.Service), nil
}
// TODO: Move this back to scheduler as a helper function that takes a Store,
// rather than a method of StoreToServiceLister.
func (s *StoreToServiceLister) GetPodServices(pod *api.Pod) (services []*api.Service, err error) {
func (s *StoreToServiceLister) GetPodServices(pod *v1.Pod) (services []*v1.Service, err error) {
allServices, err := s.Services(pod.Namespace).List(labels.Everything())
if err != nil {
return nil, err
@ -141,9 +142,9 @@ type StoreToReplicationControllerLister struct {
Indexer Indexer
}
func (s *StoreToReplicationControllerLister) List(selector labels.Selector) (ret []*api.ReplicationController, err error) {
func (s *StoreToReplicationControllerLister) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.ReplicationController))
ret = append(ret, m.(*v1.ReplicationController))
})
return ret, err
}
@ -157,14 +158,14 @@ type storeReplicationControllersNamespacer struct {
namespace string
}
func (s storeReplicationControllersNamespacer) List(selector labels.Selector) (ret []*api.ReplicationController, err error) {
func (s storeReplicationControllersNamespacer) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) {
err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.ReplicationController))
ret = append(ret, m.(*v1.ReplicationController))
})
return ret, err
}
func (s storeReplicationControllersNamespacer) Get(name string) (*api.ReplicationController, error) {
func (s storeReplicationControllersNamespacer) Get(name string) (*v1.ReplicationController, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -172,24 +173,24 @@ func (s storeReplicationControllersNamespacer) Get(name string) (*api.Replicatio
if !exists {
return nil, errors.NewNotFound(api.Resource("replicationcontroller"), name)
}
return obj.(*api.ReplicationController), nil
return obj.(*v1.ReplicationController), nil
}
// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found.
func (s *StoreToReplicationControllerLister) GetPodControllers(pod *api.Pod) (controllers []*api.ReplicationController, err error) {
func (s *StoreToReplicationControllerLister) GetPodControllers(pod *v1.Pod) (controllers []*v1.ReplicationController, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name)
return
}
key := &api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: pod.Namespace}}
key := &v1.ReplicationController{ObjectMeta: v1.ObjectMeta{Namespace: pod.Namespace}}
items, err := s.Indexer.Index(NamespaceIndex, key)
if err != nil {
return
}
for _, m := range items {
rc := m.(*api.ReplicationController)
rc := m.(*v1.ReplicationController)
selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated()
// If an rc with a nil or empty selector creeps in, it should match nothing, not everything.
@ -209,9 +210,9 @@ type StoreToServiceAccountLister struct {
Indexer Indexer
}
func (s *StoreToServiceAccountLister) List(selector labels.Selector) (ret []*api.ServiceAccount, err error) {
func (s *StoreToServiceAccountLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.ServiceAccount))
ret = append(ret, m.(*v1.ServiceAccount))
})
return ret, err
}
@ -225,14 +226,14 @@ type storeServiceAccountsNamespacer struct {
namespace string
}
func (s storeServiceAccountsNamespacer) List(selector labels.Selector) (ret []*api.ServiceAccount, err error) {
func (s storeServiceAccountsNamespacer) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) {
err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.ServiceAccount))
ret = append(ret, m.(*v1.ServiceAccount))
})
return ret, err
}
func (s storeServiceAccountsNamespacer) Get(name string) (*api.ServiceAccount, error) {
func (s storeServiceAccountsNamespacer) Get(name string) (*v1.ServiceAccount, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -240,7 +241,7 @@ func (s storeServiceAccountsNamespacer) Get(name string) (*api.ServiceAccount, e
if !exists {
return nil, errors.NewNotFound(api.Resource("serviceaccount"), name)
}
return obj.(*api.ServiceAccount), nil
return obj.(*v1.ServiceAccount), nil
}
// StoreToLimitRangeLister helps list limit ranges
@ -248,9 +249,9 @@ type StoreToLimitRangeLister struct {
Indexer Indexer
}
func (s *StoreToLimitRangeLister) List(selector labels.Selector) (ret []*api.LimitRange, err error) {
func (s *StoreToLimitRangeLister) List(selector labels.Selector) (ret []*v1.LimitRange, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.LimitRange))
ret = append(ret, m.(*v1.LimitRange))
})
return ret, err
}
@ -261,9 +262,9 @@ type StoreToPersistentVolumeClaimLister struct {
}
// List returns all persistentvolumeclaims that match the specified selector
func (s *StoreToPersistentVolumeClaimLister) List(selector labels.Selector) (ret []*api.PersistentVolumeClaim, err error) {
func (s *StoreToPersistentVolumeClaimLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.PersistentVolumeClaim))
ret = append(ret, m.(*v1.PersistentVolumeClaim))
})
return ret, err
}
@ -277,14 +278,14 @@ type storeLimitRangesNamespacer struct {
namespace string
}
func (s storeLimitRangesNamespacer) List(selector labels.Selector) (ret []*api.LimitRange, err error) {
func (s storeLimitRangesNamespacer) List(selector labels.Selector) (ret []*v1.LimitRange, err error) {
err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.LimitRange))
ret = append(ret, m.(*v1.LimitRange))
})
return ret, err
}
func (s storeLimitRangesNamespacer) Get(name string) (*api.LimitRange, error) {
func (s storeLimitRangesNamespacer) Get(name string) (*v1.LimitRange, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -292,7 +293,7 @@ func (s storeLimitRangesNamespacer) Get(name string) (*api.LimitRange, error) {
if !exists {
return nil, errors.NewNotFound(api.Resource("limitrange"), name)
}
return obj.(*api.LimitRange), nil
return obj.(*v1.LimitRange), nil
}
// PersistentVolumeClaims returns all claims in a specified namespace.
@ -305,14 +306,14 @@ type storePersistentVolumeClaimsNamespacer struct {
namespace string
}
func (s storePersistentVolumeClaimsNamespacer) List(selector labels.Selector) (ret []*api.PersistentVolumeClaim, err error) {
func (s storePersistentVolumeClaimsNamespacer) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
err = ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*api.PersistentVolumeClaim))
ret = append(ret, m.(*v1.PersistentVolumeClaim))
})
return ret, err
}
func (s storePersistentVolumeClaimsNamespacer) Get(name string) (*api.PersistentVolumeClaim, error) {
func (s storePersistentVolumeClaimsNamespacer) Get(name string) (*v1.PersistentVolumeClaim, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
@ -320,7 +321,7 @@ func (s storePersistentVolumeClaimsNamespacer) Get(name string) (*api.Persistent
if !exists {
return nil, errors.NewNotFound(api.Resource("persistentvolumeclaims"), name)
}
return obj.(*api.PersistentVolumeClaim), nil
return obj.(*v1.PersistentVolumeClaim), nil
}
// IndexerToNamespaceLister gives an Indexer List method
@ -329,14 +330,14 @@ type IndexerToNamespaceLister struct {
}
// List returns a list of namespaces
func (i *IndexerToNamespaceLister) List(selector labels.Selector) (ret []*api.Namespace, err error) {
func (i *IndexerToNamespaceLister) List(selector labels.Selector) (ret []*v1.Namespace, err error) {
err = ListAll(i.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.Namespace))
ret = append(ret, m.(*v1.Namespace))
})
return ret, err
}
func (i *IndexerToNamespaceLister) Get(name string) (*api.Namespace, error) {
func (i *IndexerToNamespaceLister) Get(name string) (*v1.Namespace, error) {
obj, exists, err := i.Indexer.GetByKey(name)
if err != nil {
return nil, err
@ -344,5 +345,5 @@ func (i *IndexerToNamespaceLister) Get(name string) (*api.Namespace, error) {
if !exists {
return nil, errors.NewNotFound(api.Resource("namespace"), name)
}
return obj.(*api.Namespace), nil
return obj.(*v1.Namespace), nil
}

View File

@ -19,10 +19,11 @@ package cache
import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/api/v1"
extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/labels"
)
@ -71,7 +72,7 @@ func (s storeDeploymentsNamespacer) Get(name string) (*extensions.Deployment, er
return nil, err
}
if !exists {
return nil, errors.NewNotFound(extensions.Resource("deployment"), name)
return nil, errors.NewNotFound(extensionsinternal.Resource("deployment"), name)
}
return obj.(*extensions.Deployment), nil
}
@ -107,7 +108,7 @@ func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.Rep
// GetDeploymentsForDeployments returns a list of deployments managing a pod. Returns an error only if no matching deployments are found.
// TODO eliminate shallow copies
func (s *StoreToDeploymentLister) GetDeploymentsForPod(pod *api.Pod) (deployments []*extensions.Deployment, err error) {
func (s *StoreToDeploymentLister) GetDeploymentsForPod(pod *v1.Pod) (deployments []*extensions.Deployment, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no deployments found for Pod %v because it has no labels", pod.Name)
return
@ -172,13 +173,13 @@ func (s storeReplicaSetsNamespacer) Get(name string) (*extensions.ReplicaSet, er
return nil, err
}
if !exists {
return nil, errors.NewNotFound(extensions.Resource("replicaset"), name)
return nil, errors.NewNotFound(extensionsinternal.Resource("replicaset"), name)
}
return obj.(*extensions.ReplicaSet), nil
}
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found.
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *api.Pod) (rss []*extensions.ReplicaSet, err error) {
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *v1.Pod) (rss []*extensions.ReplicaSet, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name)
return

View File

@ -18,7 +18,7 @@ package cache
import (
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/apis/rbac"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/labels"
)

View File

@ -19,10 +19,10 @@ package cache
import (
"testing"
"k8s.io/kubernetes/pkg/api"
apierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/api/v1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util/sets"
)
@ -31,7 +31,7 @@ func TestStoreToNodeLister(t *testing.T) {
store := NewStore(MetaNamespaceKeyFunc)
ids := sets.NewString("foo", "bar", "baz")
for id := range ids {
store.Add(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}})
store.Add(&v1.Node{ObjectMeta: v1.ObjectMeta{Name: id}})
}
sml := StoreToNodeLister{store}
@ -50,44 +50,44 @@ func TestStoreToNodeLister(t *testing.T) {
func TestStoreToNodeConditionLister(t *testing.T) {
store := NewStore(MetaNamespaceKeyFunc)
nodes := []*api.Node{
nodes := []*v1.Node{
{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Status: api.NodeStatus{
Conditions: []api.NodeCondition{
ObjectMeta: v1.ObjectMeta{Name: "foo"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: api.NodeReady,
Status: api.ConditionTrue,
Type: v1.NodeReady,
Status: v1.ConditionTrue,
},
{
Type: api.NodeOutOfDisk,
Status: api.ConditionFalse,
Type: v1.NodeOutOfDisk,
Status: v1.ConditionFalse,
},
},
},
},
{
ObjectMeta: api.ObjectMeta{Name: "bar"},
Status: api.NodeStatus{
Conditions: []api.NodeCondition{
ObjectMeta: v1.ObjectMeta{Name: "bar"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: api.NodeOutOfDisk,
Status: api.ConditionTrue,
Type: v1.NodeOutOfDisk,
Status: v1.ConditionTrue,
},
},
},
},
{
ObjectMeta: api.ObjectMeta{Name: "baz"},
Status: api.NodeStatus{
Conditions: []api.NodeCondition{
ObjectMeta: v1.ObjectMeta{Name: "baz"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: api.NodeReady,
Status: api.ConditionFalse,
Type: v1.NodeReady,
Status: v1.ConditionFalse,
},
{
Type: api.NodeOutOfDisk,
Status: api.ConditionUnknown,
Type: v1.NodeOutOfDisk,
Status: v1.ConditionUnknown,
},
},
},
@ -97,9 +97,9 @@ func TestStoreToNodeConditionLister(t *testing.T) {
store.Add(n)
}
predicate := func(node *api.Node) bool {
predicate := func(node *v1.Node) bool {
for _, cond := range node.Status.Conditions {
if cond.Type == api.NodeOutOfDisk && cond.Status == api.ConditionTrue {
if cond.Type == v1.NodeOutOfDisk && cond.Status == v1.ConditionTrue {
return false
}
}
@ -126,65 +126,65 @@ func TestStoreToNodeConditionLister(t *testing.T) {
func TestStoreToReplicationControllerLister(t *testing.T) {
testCases := []struct {
description string
inRCs []*api.ReplicationController
list func(StoreToReplicationControllerLister) ([]*api.ReplicationController, error)
inRCs []*v1.ReplicationController
list func(StoreToReplicationControllerLister) ([]*v1.ReplicationController, error)
outRCNames sets.String
expectErr bool
onlyIfIndexedByNamespace bool
}{
{
description: "Verify we can search all namespaces",
inRCs: []*api.ReplicationController{
inRCs: []*v1.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"},
ObjectMeta: v1.ObjectMeta{Name: "foo", Namespace: "bar"},
},
{
ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"},
ObjectMeta: v1.ObjectMeta{Name: "hmm", Namespace: "hmm"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
return lister.ReplicationControllers(api.NamespaceAll).List(labels.Set{}.AsSelectorPreValidated())
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.ReplicationControllers(v1.NamespaceAll).List(labels.Set{}.AsSelectorPreValidated())
},
outRCNames: sets.NewString("hmm", "foo"),
},
{
description: "Verify we can search a specific namespace",
inRCs: []*api.ReplicationController{
inRCs: []*v1.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"},
ObjectMeta: v1.ObjectMeta{Name: "foo", Namespace: "bar"},
},
{
ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"},
ObjectMeta: v1.ObjectMeta{Name: "hmm", Namespace: "hmm"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.ReplicationControllers("hmm").List(labels.Set{}.AsSelectorPreValidated())
},
outRCNames: sets.NewString("hmm"),
},
{
description: "Basic listing with all labels and no selectors",
inRCs: []*api.ReplicationController{
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
inRCs: []*v1.ReplicationController{
{ObjectMeta: v1.ObjectMeta{Name: "basic"}},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.List(labels.Everything())
},
outRCNames: sets.NewString("basic"),
},
{
description: "No pod labels",
inRCs: []*api.ReplicationController{
inRCs: []*v1.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: api.ReplicationControllerSpec{
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "baz"},
},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodControllers(pod)
},
@ -193,14 +193,14 @@ func TestStoreToReplicationControllerLister(t *testing.T) {
},
{
description: "No RC selectors",
inRCs: []*api.ReplicationController{
inRCs: []*v1.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
@ -213,23 +213,23 @@ func TestStoreToReplicationControllerLister(t *testing.T) {
},
{
description: "Matching labels to selectors and namespace",
inRCs: []*api.ReplicationController{
inRCs: []*v1.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.ReplicationControllerSpec{
ObjectMeta: v1.ObjectMeta{Name: "foo"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "bar"},
},
},
{
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: api.ReplicationControllerSpec{
ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "bar"},
},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*api.ReplicationController, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
@ -290,7 +290,7 @@ func TestStoreToReplicaSetLister(t *testing.T) {
// Basic listing with all labels and no selectors
{
inRSs: []*extensions.ReplicaSet{
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
{ObjectMeta: v1.ObjectMeta{Name: "basic"}},
},
list: func() ([]*extensions.ReplicaSet, error) {
return lister.List(labels.Everything())
@ -301,15 +301,15 @@ func TestStoreToReplicaSetLister(t *testing.T) {
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: extensions.ReplicaSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodReplicaSets(pod)
},
@ -320,12 +320,12 @@ func TestStoreToReplicaSetLister(t *testing.T) {
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
@ -340,21 +340,21 @@ func TestStoreToReplicaSetLister(t *testing.T) {
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: api.ObjectMeta{Name: "foo"},
ObjectMeta: v1.ObjectMeta{Name: "foo"},
Spec: extensions.ReplicaSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
{
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: extensions.ReplicaSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
@ -402,7 +402,7 @@ func TestStoreToDaemonSetLister(t *testing.T) {
// Basic listing
{
inDSs: []*extensions.DaemonSet{
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
{ObjectMeta: v1.ObjectMeta{Name: "basic"}},
},
list: func() ([]extensions.DaemonSet, error) {
list, err := lister.List()
@ -413,9 +413,9 @@ func TestStoreToDaemonSetLister(t *testing.T) {
// Listing multiple daemon sets
{
inDSs: []*extensions.DaemonSet{
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
{ObjectMeta: api.ObjectMeta{Name: "complex"}},
{ObjectMeta: api.ObjectMeta{Name: "complex2"}},
{ObjectMeta: v1.ObjectMeta{Name: "basic"}},
{ObjectMeta: v1.ObjectMeta{Name: "complex"}},
{ObjectMeta: v1.ObjectMeta{Name: "complex2"}},
},
list: func() ([]extensions.DaemonSet, error) {
list, err := lister.List()
@ -427,15 +427,15 @@ func TestStoreToDaemonSetLister(t *testing.T) {
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: extensions.DaemonSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodDaemonSets(pod)
},
@ -446,12 +446,12 @@ func TestStoreToDaemonSetLister(t *testing.T) {
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
@ -466,21 +466,21 @@ func TestStoreToDaemonSetLister(t *testing.T) {
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: api.ObjectMeta{Name: "foo"},
ObjectMeta: v1.ObjectMeta{Name: "foo"},
Spec: extensions.DaemonSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
{
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
ObjectMeta: v1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: extensions.DaemonSetSpec{
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
@ -527,25 +527,25 @@ func TestStoreToPodLister(t *testing.T) {
for _, store := range stores {
ids := []string{"foo", "bar", "baz"}
for _, id := range ids {
store.Add(&api.Pod{
ObjectMeta: api.ObjectMeta{
store.Add(&v1.Pod{
ObjectMeta: v1.ObjectMeta{
Namespace: "other",
Name: id,
Labels: map[string]string{"name": id},
},
})
}
store.Add(&api.Pod{
ObjectMeta: api.ObjectMeta{
store.Add(&v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "quux",
Namespace: api.NamespaceDefault,
Namespace: v1.NamespaceDefault,
Labels: map[string]string{"name": "quux"},
},
})
spl := StoreToPodLister{store}
// Verify that we can always look up by Namespace.
defaultPods, err := spl.Pods(api.NamespaceDefault).List(labels.Set{}.AsSelectorPreValidated())
defaultPods, err := spl.Pods(v1.NamespaceDefault).List(labels.Set{}.AsSelectorPreValidated())
if err != nil {
t.Errorf("Unexpected error: %v", err)
} else if e, a := 1, len(defaultPods); e != a {
@ -583,17 +583,17 @@ func TestStoreToPodLister(t *testing.T) {
func TestStoreToServiceLister(t *testing.T) {
store := NewIndexer(MetaNamespaceKeyFunc, Indexers{NamespaceIndex: MetaNamespaceIndexFunc})
store.Add(&api.Service{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.ServiceSpec{
store.Add(&v1.Service{
ObjectMeta: v1.ObjectMeta{Name: "foo"},
Spec: v1.ServiceSpec{
Selector: map[string]string{},
},
})
store.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}})
store.Add(&v1.Service{ObjectMeta: v1.ObjectMeta{Name: "bar"}})
ssl := StoreToServiceLister{store}
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "foopod",
Labels: map[string]string{"role": "foo"},
},

View File

@ -21,6 +21,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/runtime"
@ -31,16 +32,16 @@ import (
type ListerWatcher interface {
// List should return a list type object; the Items field will be extracted, and the
// ResourceVersion field will be used to start the watch in the right place.
List(options api.ListOptions) (runtime.Object, error)
List(options v1.ListOptions) (runtime.Object, error)
// Watch should begin a watch at the specified version.
Watch(options api.ListOptions) (watch.Interface, error)
Watch(options v1.ListOptions) (watch.Interface, error)
}
// ListFunc knows how to list resources
type ListFunc func(options api.ListOptions) (runtime.Object, error)
type ListFunc func(options v1.ListOptions) (runtime.Object, error)
// WatchFunc knows how to watch resources
type WatchFunc func(options api.ListOptions) (watch.Interface, error)
type WatchFunc func(options v1.ListOptions) (watch.Interface, error)
// ListWatch knows how to list and watch a set of apiserver resources. It satisfies the ListerWatcher interface.
// It is a convenience function for users of NewReflector, etc.
@ -57,7 +58,7 @@ type Getter interface {
// NewListWatchFromClient creates a new ListWatch from the specified client, resource, namespace and field selector.
func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSelector fields.Selector) *ListWatch {
listFunc := func(options api.ListOptions) (runtime.Object, error) {
listFunc := func(options v1.ListOptions) (runtime.Object, error) {
return c.Get().
Namespace(namespace).
Resource(resource).
@ -66,7 +67,7 @@ func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSe
Do().
Get()
}
watchFunc := func(options api.ListOptions) (watch.Interface, error) {
watchFunc := func(options v1.ListOptions) (watch.Interface, error) {
return c.Get().
Prefix("watch").
Namespace(namespace).
@ -78,7 +79,7 @@ func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSe
return &ListWatch{ListFunc: listFunc, WatchFunc: watchFunc}
}
func timeoutFromListOptions(options api.ListOptions) time.Duration {
func timeoutFromListOptions(options v1.ListOptions) time.Duration {
if options.TimeoutSeconds != nil {
return time.Duration(*options.TimeoutSeconds) * time.Second
}
@ -86,12 +87,12 @@ func timeoutFromListOptions(options api.ListOptions) time.Duration {
}
// List a set of apiserver resources
func (lw *ListWatch) List(options api.ListOptions) (runtime.Object, error) {
func (lw *ListWatch) List(options v1.ListOptions) (runtime.Object, error) {
return lw.ListFunc(options)
}
// Watch a set of apiserver resources
func (lw *ListWatch) Watch(options api.ListOptions) (watch.Interface, error) {
func (lw *ListWatch) Watch(options v1.ListOptions) (watch.Interface, error) {
return lw.WatchFunc(options)
}
@ -101,7 +102,7 @@ func ListWatchUntil(timeout time.Duration, lw ListerWatcher, conditions ...watch
return nil, nil
}
list, err := lw.List(api.ListOptions{})
list, err := lw.List(v1.ListOptions{})
if err != nil {
return nil, err
}
@ -153,7 +154,7 @@ func ListWatchUntil(timeout time.Duration, lw ListerWatcher, conditions ...watch
}
currResourceVersion := metaObj.GetResourceVersion()
watchInterface, err := lw.Watch(api.ListOptions{ResourceVersion: currResourceVersion})
watchInterface, err := lw.Watch(v1.ListOptions{ResourceVersion: currResourceVersion})
if err != nil {
return nil, err
}

View File

@ -22,9 +22,9 @@ import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apimachinery/registered"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
@ -60,7 +60,7 @@ func buildLocation(resourcePath string, query url.Values) string {
}
func TestListWatchesCanList(t *testing.T) {
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(registered.GroupOrDie(api.GroupName).GroupVersion.String())
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(registered.GroupOrDie(v1.GroupName).GroupVersion.String())
table := []struct {
location string
resource string
@ -69,18 +69,18 @@ func TestListWatchesCanList(t *testing.T) {
}{
// Node
{
location: testapi.Default.ResourcePath("nodes", api.NamespaceAll, ""),
location: testapi.Default.ResourcePath("nodes", v1.NamespaceAll, ""),
resource: "nodes",
namespace: api.NamespaceAll,
namespace: v1.NamespaceAll,
fieldSelector: parseSelectorOrDie(""),
},
// pod with "assigned" field selector.
{
location: buildLocation(
testapi.Default.ResourcePath("pods", api.NamespaceAll, ""),
testapi.Default.ResourcePath("pods", v1.NamespaceAll, ""),
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}})),
resource: "pods",
namespace: api.NamespaceAll,
namespace: v1.NamespaceAll,
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
},
// pod in namespace "foo"
@ -101,16 +101,16 @@ func TestListWatchesCanList(t *testing.T) {
}
server := httptest.NewServer(&handler)
defer server.Close()
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}})
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(v1.GroupName).GroupVersion}})
lw := NewListWatchFromClient(client.Core().RESTClient(), item.resource, item.namespace, item.fieldSelector)
// This test merely tests that the correct request is made.
lw.List(api.ListOptions{})
lw.List(v1.ListOptions{})
handler.ValidateRequest(t, item.location, "GET", nil)
}
}
func TestListWatchesCanWatch(t *testing.T) {
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(registered.GroupOrDie(api.GroupName).GroupVersion.String())
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(registered.GroupOrDie(v1.GroupName).GroupVersion.String())
table := []struct {
rv string
location string
@ -121,30 +121,30 @@ func TestListWatchesCanWatch(t *testing.T) {
// Node
{
location: buildLocation(
testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""),
testapi.Default.ResourcePathWithPrefix("watch", "nodes", v1.NamespaceAll, ""),
buildQueryValues(url.Values{})),
rv: "",
resource: "nodes",
namespace: api.NamespaceAll,
namespace: v1.NamespaceAll,
fieldSelector: parseSelectorOrDie(""),
},
{
location: buildLocation(
testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""),
testapi.Default.ResourcePathWithPrefix("watch", "nodes", v1.NamespaceAll, ""),
buildQueryValues(url.Values{"resourceVersion": []string{"42"}})),
rv: "42",
resource: "nodes",
namespace: api.NamespaceAll,
namespace: v1.NamespaceAll,
fieldSelector: parseSelectorOrDie(""),
},
// pod with "assigned" field selector.
{
location: buildLocation(
testapi.Default.ResourcePathWithPrefix("watch", "pods", api.NamespaceAll, ""),
testapi.Default.ResourcePathWithPrefix("watch", "pods", v1.NamespaceAll, ""),
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}, "resourceVersion": []string{"0"}})),
rv: "0",
resource: "pods",
namespace: api.NamespaceAll,
namespace: v1.NamespaceAll,
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
},
// pod with namespace foo and assigned field selector
@ -167,10 +167,10 @@ func TestListWatchesCanWatch(t *testing.T) {
}
server := httptest.NewServer(&handler)
defer server.Close()
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}})
client := clientset.NewForConfigOrDie(&restclient.Config{Host: server.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(v1.GroupName).GroupVersion}})
lw := NewListWatchFromClient(client.Core().RESTClient(), item.resource, item.namespace, item.fieldSelector)
// This test merely tests that the correct request is made.
lw.Watch(api.ListOptions{ResourceVersion: item.rv})
lw.Watch(v1.ListOptions{ResourceVersion: item.rv})
handler.ValidateRequest(t, item.location, "GET", nil)
}
}
@ -180,22 +180,22 @@ type lw struct {
watch watch.Interface
}
func (w lw) List(options api.ListOptions) (runtime.Object, error) {
func (w lw) List(options v1.ListOptions) (runtime.Object, error) {
return w.list, nil
}
func (w lw) Watch(options api.ListOptions) (watch.Interface, error) {
func (w lw) Watch(options v1.ListOptions) (watch.Interface, error) {
return w.watch, nil
}
func TestListWatchUntil(t *testing.T) {
fw := watch.NewFake()
go func() {
var obj *api.Pod
var obj *v1.Pod
fw.Modify(obj)
}()
listwatch := lw{
list: &api.PodList{Items: []api.Pod{{}}},
list: &v1.PodList{Items: []v1.Pod{{}}},
watch: fw,
}
@ -221,7 +221,7 @@ func TestListWatchUntil(t *testing.T) {
if lastEvent.Type != watch.Modified {
t.Fatalf("expected MODIFIED event type, got %v", lastEvent.Type)
}
if got, isPod := lastEvent.Object.(*api.Pod); !isPod {
if got, isPod := lastEvent.Object.(*v1.Pod); !isPod {
t.Fatalf("expected a pod event, got %#v", got)
}
}

View File

@ -22,7 +22,7 @@ import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/watch"
)
@ -30,15 +30,15 @@ import (
func TestMutationDetector(t *testing.T) {
fakeWatch := watch.NewFake()
lw := &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return fakeWatch, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
return &api.PodList{}, nil
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return &v1.PodList{}, nil
},
}
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "anything",
Labels: map[string]string{"check": "foo"},
},
@ -48,7 +48,7 @@ func TestMutationDetector(t *testing.T) {
addReceived := make(chan bool)
mutationFound := make(chan bool)
informer := NewSharedInformer(lw, &api.Pod{}, 1*time.Second).(*sharedIndexInformer)
informer := NewSharedInformer(lw, &v1.Pod{}, 1*time.Second).(*sharedIndexInformer)
informer.cacheMutationDetector = &defaultCacheMutationDetector{
name: "name",
period: 1 * time.Second,

View File

@ -34,9 +34,9 @@ import (
"time"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
apierrs "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/util/wait"
@ -239,7 +239,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
// Explicitly set "0" as resource version - it's fine for the List()
// to be served from cache and potentially be delayed relative to
// etcd contents. Reflector framework will catch up via Watch() eventually.
options := api.ListOptions{ResourceVersion: "0"}
options := v1.ListOptions{ResourceVersion: "0"}
list, err := r.listerWatcher.List(options)
if err != nil {
return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err)
@ -278,7 +278,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
for {
timemoutseconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0))
options = api.ListOptions{
options = v1.ListOptions{
ResourceVersion: resourceVersion,
// We want to avoid situations of hanging watchers. Stop any wachers that do not
// receive any events within the timeout window.

View File

@ -24,8 +24,8 @@ import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/watch"
@ -34,27 +34,27 @@ import (
var nevererrc chan error
type testLW struct {
ListFunc func(options api.ListOptions) (runtime.Object, error)
WatchFunc func(options api.ListOptions) (watch.Interface, error)
ListFunc func(options v1.ListOptions) (runtime.Object, error)
WatchFunc func(options v1.ListOptions) (watch.Interface, error)
}
func (t *testLW) List(options api.ListOptions) (runtime.Object, error) {
func (t *testLW) List(options v1.ListOptions) (runtime.Object, error) {
return t.ListFunc(options)
}
func (t *testLW) Watch(options api.ListOptions) (watch.Interface, error) {
func (t *testLW) Watch(options v1.ListOptions) (watch.Interface, error) {
return t.WatchFunc(options)
}
func TestCloseWatchChannelOnError(t *testing.T) {
r := NewReflector(&testLW{}, &api.Pod{}, NewStore(MetaNamespaceKeyFunc), 0)
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}
r := NewReflector(&testLW{}, &v1.Pod{}, NewStore(MetaNamespaceKeyFunc), 0)
pod := &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "bar"}}
fw := watch.NewFake()
r.listerWatcher = &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return fw, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return &v1.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
},
}
go r.ListAndWatch(wait.NeverStop)
@ -73,20 +73,20 @@ func TestCloseWatchChannelOnError(t *testing.T) {
func TestRunUntil(t *testing.T) {
stopCh := make(chan struct{})
store := NewStore(MetaNamespaceKeyFunc)
r := NewReflector(&testLW{}, &api.Pod{}, store, 0)
r := NewReflector(&testLW{}, &v1.Pod{}, store, 0)
fw := watch.NewFake()
r.listerWatcher = &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return fw, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return &v1.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
},
}
r.RunUntil(stopCh)
// Synchronously add a dummy pod into the watch channel so we
// know the RunUntil go routine is in the watch handler.
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}})
fw.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "bar"}})
close(stopCh)
select {
case _, ok := <-fw.ResultChan():
@ -101,7 +101,7 @@ func TestRunUntil(t *testing.T) {
func TestReflectorResyncChan(t *testing.T) {
s := NewStore(MetaNamespaceKeyFunc)
g := NewReflector(&testLW{}, &api.Pod{}, s, time.Millisecond)
g := NewReflector(&testLW{}, &v1.Pod{}, s, time.Millisecond)
a, _ := g.resyncChan()
b := time.After(wait.ForeverTestTimeout)
select {
@ -114,7 +114,7 @@ func TestReflectorResyncChan(t *testing.T) {
func BenchmarkReflectorResyncChanMany(b *testing.B) {
s := NewStore(MetaNamespaceKeyFunc)
g := NewReflector(&testLW{}, &api.Pod{}, s, 25*time.Millisecond)
g := NewReflector(&testLW{}, &v1.Pod{}, s, 25*time.Millisecond)
// The improvement to this (calling the timer's Stop() method) makes
// this benchmark about 40% faster.
for i := 0; i < b.N; i++ {
@ -126,7 +126,7 @@ func BenchmarkReflectorResyncChanMany(b *testing.B) {
func TestReflectorWatchHandlerError(t *testing.T) {
s := NewStore(MetaNamespaceKeyFunc)
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
g := NewReflector(&testLW{}, &v1.Pod{}, s, 0)
fw := watch.NewFake()
go func() {
fw.Stop()
@ -140,15 +140,15 @@ func TestReflectorWatchHandlerError(t *testing.T) {
func TestReflectorWatchHandler(t *testing.T) {
s := NewStore(MetaNamespaceKeyFunc)
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
g := NewReflector(&testLW{}, &v1.Pod{}, s, 0)
fw := watch.NewFake()
s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}})
s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}})
s.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}})
s.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "bar"}})
go func() {
fw.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "rejected"}})
fw.Delete(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}})
fw.Modify(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "55"}})
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "32"}})
fw.Add(&v1.Service{ObjectMeta: v1.ObjectMeta{Name: "rejected"}})
fw.Delete(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}})
fw.Modify(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "bar", ResourceVersion: "55"}})
fw.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "baz", ResourceVersion: "32"}})
fw.Stop()
}()
var resumeRV string
@ -157,12 +157,12 @@ func TestReflectorWatchHandler(t *testing.T) {
t.Errorf("unexpected error %v", err)
}
mkPod := func(id string, rv string) *api.Pod {
return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}}
mkPod := func(id string, rv string) *v1.Pod {
return &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: id, ResourceVersion: rv}}
}
table := []struct {
Pod *api.Pod
Pod *v1.Pod
exists bool
}{
{mkPod("foo", ""), false},
@ -178,7 +178,7 @@ func TestReflectorWatchHandler(t *testing.T) {
if !exists {
continue
}
if e, a := item.Pod.ResourceVersion, obj.(*api.Pod).ResourceVersion; e != a {
if e, a := item.Pod.ResourceVersion, obj.(*v1.Pod).ResourceVersion; e != a {
t.Errorf("%v: expected %v, got %v", item.Pod, e, a)
}
}
@ -196,7 +196,7 @@ func TestReflectorWatchHandler(t *testing.T) {
func TestReflectorStopWatch(t *testing.T) {
s := NewStore(MetaNamespaceKeyFunc)
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
g := NewReflector(&testLW{}, &v1.Pod{}, s, 0)
fw := watch.NewFake()
var resumeRV string
stopWatch := make(chan struct{}, 1)
@ -215,7 +215,7 @@ func TestReflectorListAndWatch(t *testing.T) {
// inject an error.
expectedRVs := []string{"1", "3"}
lw := &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
rv := options.ResourceVersion
fw := watch.NewFake()
if e, a := expectedRVs[0], rv; e != a {
@ -227,12 +227,12 @@ func TestReflectorListAndWatch(t *testing.T) {
go func() { createdFakes <- fw }()
return fw, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return &v1.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
},
}
s := NewFIFO(MetaNamespaceKeyFunc)
r := NewReflector(lw, &api.Pod{}, s, 0)
r := NewReflector(lw, &v1.Pod{}, s, 0)
go r.ListAndWatch(wait.NeverStop)
ids := []string{"foo", "bar", "baz", "qux", "zoo"}
@ -242,7 +242,7 @@ func TestReflectorListAndWatch(t *testing.T) {
fw = <-createdFakes
}
sendingRV := strconv.FormatUint(uint64(i+2), 10)
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: sendingRV}})
fw.Add(&v1.Pod{ObjectMeta: v1.ObjectMeta{Name: id, ResourceVersion: sendingRV}})
if sendingRV == "3" {
// Inject a failure.
fw.Stop()
@ -252,7 +252,7 @@ func TestReflectorListAndWatch(t *testing.T) {
// Verify we received the right ids with the right resource versions.
for i, id := range ids {
pod := Pop(s).(*api.Pod)
pod := Pop(s).(*v1.Pod)
if e, a := id, pod.Name; e != a {
t.Errorf("%v: Expected %v, got %v", i, e, a)
}
@ -267,18 +267,18 @@ func TestReflectorListAndWatch(t *testing.T) {
}
func TestReflectorListAndWatchWithErrors(t *testing.T) {
mkPod := func(id string, rv string) *api.Pod {
return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}}
mkPod := func(id string, rv string) *v1.Pod {
return &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: id, ResourceVersion: rv}}
}
mkList := func(rv string, pods ...*api.Pod) *api.PodList {
list := &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: rv}}
mkList := func(rv string, pods ...*v1.Pod) *v1.PodList {
list := &v1.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: rv}}
for _, pod := range pods {
list.Items = append(list.Items, *pod)
}
return list
}
table := []struct {
list *api.PodList
list *v1.PodList
listErr error
events []watch.Event
watchErr error
@ -317,7 +317,7 @@ func TestReflectorListAndWatchWithErrors(t *testing.T) {
current := s.List()
checkMap := map[string]string{}
for _, item := range current {
pod := item.(*api.Pod)
pod := item.(*v1.Pod)
checkMap[pod.Name] = pod.ResourceVersion
}
for _, pod := range item.list.Items {
@ -331,7 +331,7 @@ func TestReflectorListAndWatchWithErrors(t *testing.T) {
}
watchRet, watchErr := item.events, item.watchErr
lw := &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if watchErr != nil {
return nil, watchErr
}
@ -345,11 +345,11 @@ func TestReflectorListAndWatchWithErrors(t *testing.T) {
}()
return fw, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return item.list, item.listErr
},
}
r := NewReflector(lw, &api.Pod{}, s, 0)
r := NewReflector(lw, &v1.Pod{}, s, 0)
r.ListAndWatch(wait.NeverStop)
}
}
@ -369,16 +369,16 @@ func TestReflectorResync(t *testing.T) {
}
lw := &testLW{
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
fw := watch.NewFake()
return fw, nil
},
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "0"}}, nil
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return &v1.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "0"}}, nil
},
}
resyncPeriod := 1 * time.Millisecond
r := NewReflector(lw, &api.Pod{}, s, resyncPeriod)
r := NewReflector(lw, &v1.Pod{}, s, resyncPeriod)
if err := r.ListAndWatch(stopCh); err != nil {
// error from Resync is not propaged up to here.
t.Errorf("expected error %v", err)

View File

@ -41,6 +41,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apimachinery/registered:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/fields:go_default_library",

View File

@ -20,6 +20,7 @@ import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/runtime"
)
@ -148,14 +149,47 @@ type EventSinkImpl struct {
Interface EventInterface
}
func (e *EventSinkImpl) Create(event *api.Event) (*api.Event, error) {
return e.Interface.CreateWithEventNamespace(event)
func (e *EventSinkImpl) Create(event *v1.Event) (*v1.Event, error) {
internalEvent := &api.Event{}
err := v1.Convert_v1_Event_To_api_Event(event, internalEvent, nil)
if err != nil {
return nil, err
}
_, err = e.Interface.CreateWithEventNamespace(internalEvent)
if err != nil {
return nil, err
}
return event, nil
}
func (e *EventSinkImpl) Update(event *api.Event) (*api.Event, error) {
return e.Interface.UpdateWithEventNamespace(event)
func (e *EventSinkImpl) Update(event *v1.Event) (*v1.Event, error) {
internalEvent := &api.Event{}
err := v1.Convert_v1_Event_To_api_Event(event, internalEvent, nil)
if err != nil {
return nil, err
}
_, err = e.Interface.UpdateWithEventNamespace(internalEvent)
if err != nil {
return nil, err
}
return event, nil
}
func (e *EventSinkImpl) Patch(event *api.Event, data []byte) (*api.Event, error) {
return e.Interface.PatchWithEventNamespace(event, data)
func (e *EventSinkImpl) Patch(event *v1.Event, data []byte) (*v1.Event, error) {
internalEvent := &api.Event{}
err := v1.Convert_v1_Event_To_api_Event(event, internalEvent, nil)
if err != nil {
return nil, err
}
internalEvent, err = e.Interface.PatchWithEventNamespace(internalEvent, data)
if err != nil {
return nil, err
}
externalEvent := &v1.Event{}
err = v1.Convert_api_Event_To_v1_Event(internalEvent, externalEvent, nil)
if err != nil {
// Patch succeeded, no need to report the failed conversion
return event, nil
}
return externalEvent, nil
}

View File

@ -0,0 +1,23 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["conditions.go"],
tags = ["automanaged"],
deps = [
"//pkg/api/errors:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/watch:go_default_library",
],
)

View File

@ -0,0 +1,164 @@
/*
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 conditions
import (
"fmt"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/watch"
)
// ErrPodCompleted is returned by PodRunning or PodContainerRunning to indicate that
// the pod has already reached completed state.
var ErrPodCompleted = fmt.Errorf("pod ran to completion")
// ErrContainerTerminated is returned by PodContainerRunning in the intermediate
// state where the pod indicates it's still running, but its container is already terminated
var ErrContainerTerminated = fmt.Errorf("container terminated")
// PodRunning returns true if the pod is running, false if the pod has not yet reached running state,
// returns ErrPodCompleted if the pod has run to completion, or an error in any other case.
func PodRunning(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodRunning:
return true, nil
case v1.PodFailed, v1.PodSucceeded:
return false, ErrPodCompleted
}
}
return false, nil
}
// PodCompleted returns true if the pod has run to completion, false if the pod has not yet
// reached running state, or an error in any other case.
func PodCompleted(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodFailed, v1.PodSucceeded:
return true, nil
}
}
return false, nil
}
// PodRunningAndReady returns true if the pod is running and ready, false if the pod has not
// yet reached those states, returns ErrPodCompleted if the pod has run to completion, or
// an error in any other case.
func PodRunningAndReady(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodFailed, v1.PodSucceeded:
return false, ErrPodCompleted
case v1.PodRunning:
return v1.IsPodReady(t), nil
}
}
return false, nil
}
// PodNotPending returns true if the pod has left the pending state, false if it has not,
// or an error in any other case (such as if the pod was deleted).
func PodNotPending(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodPending:
return false, nil
default:
return true, nil
}
}
return false, nil
}
// PodContainerRunning returns false until the named container has ContainerStatus running (at least once),
// and will return an error if the pod is deleted, runs to completion, or the container pod is not available.
func PodContainerRunning(containerName string) watch.ConditionFunc {
return func(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodRunning, v1.PodPending:
case v1.PodFailed, v1.PodSucceeded:
return false, ErrPodCompleted
default:
return false, nil
}
for _, s := range t.Status.ContainerStatuses {
if s.Name != containerName {
continue
}
if s.State.Terminated != nil {
return false, ErrContainerTerminated
}
return s.State.Running != nil, nil
}
for _, s := range t.Status.InitContainerStatuses {
if s.Name != containerName {
continue
}
if s.State.Terminated != nil {
return false, ErrContainerTerminated
}
return s.State.Running != nil, nil
}
return false, nil
}
return false, nil
}
}
// ServiceAccountHasSecrets returns true if the service account has at least one secret,
// false if it does not, or an error.
func ServiceAccountHasSecrets(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(unversioned.GroupResource{Resource: "serviceaccounts"}, "")
}
switch t := event.Object.(type) {
case *v1.ServiceAccount:
return len(t.Secrets) > 0, nil
}
return false, nil
}

View File

@ -32,10 +32,10 @@ go_test(
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/errors:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/release_1_5/fake:go_default_library",
"//pkg/client/leaderelection/resourcelock:go_default_library",
"//pkg/client/record:go_default_library",
"//pkg/client/testing/core:go_default_library",

View File

@ -26,10 +26,10 @@ import (
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
fakeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/api/v1"
fakeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/testing/core"
@ -67,7 +67,7 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "create",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(core.CreateAction).GetObject().(*api.Endpoints), nil
return true, action.(core.CreateAction).GetObject().(*v1.Endpoints), nil
},
},
},
@ -83,8 +83,8 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "get",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, &api.Endpoints{
ObjectMeta: api.ObjectMeta{
return true, &v1.Endpoints{
ObjectMeta: v1.ObjectMeta{
Namespace: action.GetNamespace(),
Name: action.(core.GetAction).GetName(),
},
@ -94,7 +94,7 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "update",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(core.CreateAction).GetObject().(*api.Endpoints), nil
return true, action.(core.CreateAction).GetObject().(*v1.Endpoints), nil
},
},
},
@ -112,8 +112,8 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "get",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, &api.Endpoints{
ObjectMeta: api.ObjectMeta{
return true, &v1.Endpoints{
ObjectMeta: v1.ObjectMeta{
Namespace: action.GetNamespace(),
Name: action.(core.GetAction).GetName(),
Annotations: map[string]string{
@ -126,7 +126,7 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "update",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(core.CreateAction).GetObject().(*api.Endpoints), nil
return true, action.(core.CreateAction).GetObject().(*v1.Endpoints), nil
},
},
},
@ -146,8 +146,8 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "get",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, &api.Endpoints{
ObjectMeta: api.ObjectMeta{
return true, &v1.Endpoints{
ObjectMeta: v1.ObjectMeta{
Namespace: action.GetNamespace(),
Name: action.(core.GetAction).GetName(),
Annotations: map[string]string{
@ -172,8 +172,8 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "get",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, &api.Endpoints{
ObjectMeta: api.ObjectMeta{
return true, &v1.Endpoints{
ObjectMeta: v1.ObjectMeta{
Namespace: action.GetNamespace(),
Name: action.(core.GetAction).GetName(),
Annotations: map[string]string{
@ -186,7 +186,7 @@ func TestTryAcquireOrRenew(t *testing.T) {
{
verb: "update",
reaction: func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, action.(core.CreateAction).GetObject().(*api.Endpoints), nil
return true, action.(core.CreateAction).GetObject().(*v1.Endpoints), nil
},
},
},
@ -205,7 +205,7 @@ func TestTryAcquireOrRenew(t *testing.T) {
var reportedLeader string
lock := rl.EndpointsLock{
EndpointsMeta: api.ObjectMeta{Namespace: "foo", Name: "bar"},
EndpointsMeta: v1.ObjectMeta{Namespace: "foo", Name: "bar"},
LockConfig: rl.ResourceLockConfig{
Identity: "baz",
EventRecorder: &record.FakeRecorder{},

View File

@ -18,9 +18,9 @@ go_library(
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/release_1_5:go_default_library",
"//pkg/client/record:go_default_library",
],
)

View File

@ -21,17 +21,17 @@ import (
"errors"
"fmt"
"k8s.io/kubernetes/pkg/api"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/api/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
)
type EndpointsLock struct {
// EndpointsMeta should contain a Name and a Namespace of an
// Endpoints object that the LeaderElector will attempt to lead.
EndpointsMeta api.ObjectMeta
EndpointsMeta v1.ObjectMeta
Client clientset.Interface
LockConfig ResourceLockConfig
e *api.Endpoints
e *v1.Endpoints
}
func (el *EndpointsLock) Get() (*LeaderElectionRecord, error) {
@ -58,8 +58,8 @@ func (el *EndpointsLock) Create(ler LeaderElectionRecord) error {
if err != nil {
return err
}
el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Create(&api.Endpoints{
ObjectMeta: api.ObjectMeta{
el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Create(&v1.Endpoints{
ObjectMeta: v1.ObjectMeta{
Name: el.EndpointsMeta.Name,
Namespace: el.EndpointsMeta.Namespace,
Annotations: map[string]string{
@ -87,7 +87,7 @@ func (el *EndpointsLock) Update(ler LeaderElectionRecord) error {
// RecordEvent in leader election while adding meta-data
func (el *EndpointsLock) RecordEvent(s string) {
events := fmt.Sprintf("%v %v", el.LockConfig.Identity, s)
el.LockConfig.EventRecorder.Eventf(&api.Endpoints{ObjectMeta: el.e.ObjectMeta}, api.EventTypeNormal, "LeaderElection", events)
el.LockConfig.EventRecorder.Eventf(&v1.Endpoints{ObjectMeta: el.e.ObjectMeta}, v1.EventTypeNormal, "LeaderElection", events)
}
// Describe is used to convert details on current resource lock

View File

@ -15,10 +15,13 @@ go_library(
srcs = [
"expansion_generated.go",
"job.go",
"job_expansion.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api/errors:go_default_library",
"//pkg/api/unversioned:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/batch/v1:go_default_library",
"//pkg/client/cache:go_default_library",

Some files were not shown because too many files have changed in this diff Show More