remove portsforobject from factory

This commit is contained in:
David Eads 2018-05-21 16:01:08 -04:00
parent e85b81bbee
commit 043f66b86e
10 changed files with 177 additions and 88 deletions

View File

@ -24,7 +24,6 @@ import (
autoscalingv1 "k8s.io/api/autoscaling/v1" autoscalingv1 "k8s.io/api/autoscaling/v1"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1" autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
@ -33,6 +32,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -73,7 +73,7 @@ type AutoscaleOptions struct {
namespace string namespace string
dryRun bool dryRun bool
builder *resource.Builder builder *resource.Builder
canBeAutoscaled func(kind schema.GroupKind) error canBeAutoscaled polymorphichelpers.CanBeAutoscaledFunc
generatorFunc func(string, *meta.RESTMapping) (kubectl.StructuredGenerator, error) generatorFunc func(string, *meta.RESTMapping) (kubectl.StructuredGenerator, error)
HPAClient autoscalingv1client.HorizontalPodAutoscalersGetter HPAClient autoscalingv1client.HorizontalPodAutoscalersGetter
@ -132,7 +132,7 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run") o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run")
o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag) o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.builder = f.NewBuilder() o.builder = f.NewBuilder()
o.canBeAutoscaled = f.CanBeAutoscaled o.canBeAutoscaled = polymorphichelpers.CanBeAutoscaledFn
o.args = args o.args = args
o.RecordFlags.Complete(f.Command(cmd, false)) o.RecordFlags.Complete(f.Command(cmd, false))

View File

@ -37,6 +37,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -94,7 +95,7 @@ type ExposeServiceOptions struct {
CanBeExposed func(kind schema.GroupKind) error CanBeExposed func(kind schema.GroupKind) error
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error) ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
MapBasedSelectorForObject func(runtime.Object) (string, error) MapBasedSelectorForObject func(runtime.Object) (string, error)
PortsForObject func(runtime.Object) ([]string, error) PortsForObject polymorphichelpers.PortsForObjectFunc
ProtocolsForObject func(runtime.Object) (map[string]string, error) ProtocolsForObject func(runtime.Object) (map[string]string, error)
Namespace string Namespace string
@ -193,7 +194,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
o.CanBeExposed = f.CanBeExposed o.CanBeExposed = f.CanBeExposed
o.ClientForMapping = f.ClientForMapping o.ClientForMapping = f.ClientForMapping
o.MapBasedSelectorForObject = f.MapBasedSelectorForObject o.MapBasedSelectorForObject = f.MapBasedSelectorForObject
o.PortsForObject = f.PortsForObject o.PortsForObject = polymorphichelpers.PortsForObjectFn
o.ProtocolsForObject = f.ProtocolsForObject o.ProtocolsForObject = f.ProtocolsForObject
o.Mapper, err = f.ToRESTMapper() o.Mapper, err = f.ToRESTMapper()
if err != nil { if err != nil {

View File

@ -82,8 +82,6 @@ type ClientAccessFactory interface {
// new set-based selector is provided, an error is returned if the selector cannot be converted to a // new set-based selector is provided, an error is returned if the selector cannot be converted to a
// map-based selector // map-based selector
MapBasedSelectorForObject(object runtime.Object) (string, error) MapBasedSelectorForObject(object runtime.Object) (string, error)
// PortsForObject returns the ports associated with the provided object
PortsForObject(object runtime.Object) ([]string, error)
// ProtocolsForObject returns the <port, protocol> mapping associated with the provided object // ProtocolsForObject returns the <port, protocol> mapping associated with the provided object
ProtocolsForObject(object runtime.Object) (map[string]string, error) ProtocolsForObject(object runtime.Object) (map[string]string, error)
@ -111,8 +109,6 @@ type ClientAccessFactory interface {
Generators(cmdName string) map[string]kubectl.Generator Generators(cmdName string) map[string]kubectl.Generator
// Check whether the kind of resources could be exposed // Check whether the kind of resources could be exposed
CanBeExposed(kind schema.GroupKind) error CanBeExposed(kind schema.GroupKind) error
// Check whether the kind of resources could be autoscaled
CanBeAutoscaled(kind schema.GroupKind) error
} }
// ObjectMappingFactory holds the second level of factory methods. These functions depend upon ClientAccessFactory methods. // ObjectMappingFactory holds the second level of factory methods. These functions depend upon ClientAccessFactory methods.
@ -178,16 +174,6 @@ func makePortsString(ports []api.ServicePort, useNodePort bool) string {
return strings.Join(pieces, ",") return strings.Join(pieces, ",")
} }
func getPorts(spec api.PodSpec) []string {
result := []string{}
for _, container := range spec.Containers {
for _, port := range container.Ports {
result = append(result, strconv.Itoa(int(port.ContainerPort)))
}
}
return result
}
func getProtocols(spec api.PodSpec) map[string]string { func getProtocols(spec api.PodSpec) map[string]string {
result := make(map[string]string) result := make(map[string]string)
for _, container := range spec.Containers { for _, container := range spec.Containers {
@ -198,15 +184,6 @@ func getProtocols(spec api.PodSpec) map[string]string {
return result return result
} }
// Extracts the ports exposed by a service from the given service spec.
func getServicePorts(spec api.ServiceSpec) []string {
result := []string{}
for _, servicePort := range spec.Ports {
result = append(result, strconv.Itoa(int(servicePort.Port)))
}
return result
}
// Extracts the protocols exposed by a service from the given service spec. // Extracts the protocols exposed by a service from the given service spec.
func getServiceProtocols(spec api.ServiceSpec) map[string]string { func getServiceProtocols(spec api.ServiceSpec) map[string]string {
result := make(map[string]string) result := make(map[string]string)

View File

@ -160,24 +160,6 @@ func (f *ring0Factory) MapBasedSelectorForObject(object runtime.Object) (string,
} }
} }
func (f *ring0Factory) PortsForObject(object runtime.Object) ([]string, error) {
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
switch t := object.(type) {
case *api.ReplicationController:
return getPorts(t.Spec.Template.Spec), nil
case *api.Pod:
return getPorts(t.Spec), nil
case *api.Service:
return getServicePorts(t.Spec), nil
case *extensions.Deployment:
return getPorts(t.Spec.Template.Spec), nil
case *extensions.ReplicaSet:
return getPorts(t.Spec.Template.Spec), nil
default:
return nil, fmt.Errorf("cannot extract ports from %T", object)
}
}
func (f *ring0Factory) ProtocolsForObject(object runtime.Object) (map[string]string, error) { func (f *ring0Factory) ProtocolsForObject(object runtime.Object) (map[string]string, error) {
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
switch t := object.(type) { switch t := object.(type) {
@ -488,17 +470,6 @@ func (f *ring0Factory) CanBeExposed(kind schema.GroupKind) error {
return nil return nil
} }
func (f *ring0Factory) CanBeAutoscaled(kind schema.GroupKind) error {
switch kind {
case api.Kind("ReplicationController"), extensions.Kind("ReplicaSet"),
extensions.Kind("Deployment"), apps.Kind("Deployment"), apps.Kind("ReplicaSet"):
// nothing to do here
default:
return fmt.Errorf("cannot autoscale a %v", kind)
}
return nil
}
// this method exists to help us find the points still relying on internal types. // this method exists to help us find the points still relying on internal types.
func InternalVersionDecoder() runtime.Decoder { func InternalVersionDecoder() runtime.Decoder {
return legacyscheme.Codecs.UniversalDecoder() return legacyscheme.Codecs.UniversalDecoder()

View File

@ -28,37 +28,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestPortsForObject(t *testing.T) {
f := NewFactory(genericclioptions.NewTestConfigFlags())
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: api.PodSpec{
Containers: []api.Container{
{
Ports: []api.ContainerPort{
{
ContainerPort: 101,
},
},
},
},
},
}
expected := sets.NewString("101")
ports, err := f.PortsForObject(pod)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
got := sets.NewString(ports...)
if !expected.Equal(got) {
t.Fatalf("Ports mismatch! Expected %v, got %v", expected, got)
}
}
func TestProtocolsForObject(t *testing.T) { func TestProtocolsForObject(t *testing.T) {
f := NewFactory(genericclioptions.NewTestConfigFlags()) f := NewFactory(genericclioptions.NewTestConfigFlags())

View File

@ -4,10 +4,12 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"attachablepodforobject.go", "attachablepodforobject.go",
"canbeautoscaled.go",
"helpers.go", "helpers.go",
"historyviewer.go", "historyviewer.go",
"interface.go", "interface.go",
"logsforobject.go", "logsforobject.go",
"portsforobject.go",
"statusviewer.go", "statusviewer.go",
"updatepodspec.go", "updatepodspec.go",
], ],
@ -36,6 +38,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library",
@ -47,6 +50,7 @@ go_test(
srcs = [ srcs = [
"helpers_test.go", "helpers_test.go",
"logsforobject_test.go", "logsforobject_test.go",
"portsforobject_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
@ -63,6 +67,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/testing:go_default_library", "//vendor/k8s.io/client-go/testing:go_default_library",
], ],

View File

@ -0,0 +1,37 @@
/*
Copyright 2018 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 polymorphichelpers
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/apis/apps"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/extensions"
)
func canBeAutoscaled(kind schema.GroupKind) error {
switch kind {
case api.Kind("ReplicationController"), extensions.Kind("ReplicaSet"),
extensions.Kind("Deployment"), apps.Kind("Deployment"), apps.Kind("ReplicaSet"):
// nothing to do here
default:
return fmt.Errorf("cannot autoscale a %v", kind)
}
return nil
}

View File

@ -22,6 +22,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
@ -58,3 +59,15 @@ type UpdatePodSpecForObjectFunc func(obj runtime.Object, fn func(*v1.PodSpec) er
// UpdatePodSpecForObjectFn gives a way to easily override the function for unit testing if needed // UpdatePodSpecForObjectFn gives a way to easily override the function for unit testing if needed
var UpdatePodSpecForObjectFn UpdatePodSpecForObjectFunc = updatePodSpecForObject var UpdatePodSpecForObjectFn UpdatePodSpecForObjectFunc = updatePodSpecForObject
// PortsForObjectFunc returns the ports associated with the provided object
type PortsForObjectFunc func(object runtime.Object) ([]string, error)
// PortsForObjectFn gives a way to easily override the function for unit testing if needed
var PortsForObjectFn PortsForObjectFunc = portsForObject
// CanBeAutoscaledFunc checks whether the kind of resources could be autoscaled
type CanBeAutoscaledFunc func(kind schema.GroupKind) error
// CanBeAutoscaledFn gives a way to easily override the function for unit testing if needed
var CanBeAutoscaledFn CanBeAutoscaledFunc = canBeAutoscaled

View File

@ -0,0 +1,62 @@
/*
Copyright 2018 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 polymorphichelpers
import (
"fmt"
"strconv"
"k8s.io/apimachinery/pkg/runtime"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/extensions"
)
func portsForObject(object runtime.Object) ([]string, error) {
switch t := object.(type) {
case *api.ReplicationController:
return getPorts(t.Spec.Template.Spec), nil
case *api.Pod:
return getPorts(t.Spec), nil
case *api.Service:
return getServicePorts(t.Spec), nil
case *extensions.Deployment:
return getPorts(t.Spec.Template.Spec), nil
case *extensions.ReplicaSet:
return getPorts(t.Spec.Template.Spec), nil
default:
return nil, fmt.Errorf("cannot extract ports from %T", object)
}
}
func getPorts(spec api.PodSpec) []string {
result := []string{}
for _, container := range spec.Containers {
for _, port := range container.Ports {
result = append(result, strconv.Itoa(int(port.ContainerPort)))
}
}
return result
}
// Extracts the ports exposed by a service from the given service spec.
func getServicePorts(spec api.ServiceSpec) []string {
result := []string{}
for _, servicePort := range spec.Ports {
result = append(result, strconv.Itoa(int(servicePort.Port)))
}
return result
}

View File

@ -0,0 +1,54 @@
/*
Copyright 2018 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 polymorphichelpers
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
api "k8s.io/kubernetes/pkg/apis/core"
)
func TestPortsForObject(t *testing.T) {
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: api.PodSpec{
Containers: []api.Container{
{
Ports: []api.ContainerPort{
{
ContainerPort: 101,
},
},
},
},
},
}
expected := sets.NewString("101")
ports, err := portsForObject(pod)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
got := sets.NewString(ports...)
if !expected.Equal(got) {
t.Fatalf("Ports mismatch! Expected %v, got %v", expected, got)
}
}