remove portsforobject from factory

pull/8/head
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"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl"
@ -33,6 +32,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -73,7 +73,7 @@ type AutoscaleOptions struct {
namespace string
dryRun bool
builder *resource.Builder
canBeAutoscaled func(kind schema.GroupKind) error
canBeAutoscaled polymorphichelpers.CanBeAutoscaledFunc
generatorFunc func(string, *meta.RESTMapping) (kubectl.StructuredGenerator, error)
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.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.builder = f.NewBuilder()
o.canBeAutoscaled = f.CanBeAutoscaled
o.canBeAutoscaled = polymorphichelpers.CanBeAutoscaledFn
o.args = args
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/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -94,7 +95,7 @@ type ExposeServiceOptions struct {
CanBeExposed func(kind schema.GroupKind) error
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
MapBasedSelectorForObject func(runtime.Object) (string, error)
PortsForObject func(runtime.Object) ([]string, error)
PortsForObject polymorphichelpers.PortsForObjectFunc
ProtocolsForObject func(runtime.Object) (map[string]string, error)
Namespace string
@ -193,7 +194,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
o.CanBeExposed = f.CanBeExposed
o.ClientForMapping = f.ClientForMapping
o.MapBasedSelectorForObject = f.MapBasedSelectorForObject
o.PortsForObject = f.PortsForObject
o.PortsForObject = polymorphichelpers.PortsForObjectFn
o.ProtocolsForObject = f.ProtocolsForObject
o.Mapper, err = f.ToRESTMapper()
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
// map-based selector
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(object runtime.Object) (map[string]string, error)
@ -111,8 +109,6 @@ type ClientAccessFactory interface {
Generators(cmdName string) map[string]kubectl.Generator
// Check whether the kind of resources could be exposed
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.
@ -178,16 +174,6 @@ func makePortsString(ports []api.ServicePort, useNodePort bool) string {
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 {
result := make(map[string]string)
for _, container := range spec.Containers {
@ -198,15 +184,6 @@ func getProtocols(spec api.PodSpec) map[string]string {
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.
func getServiceProtocols(spec api.ServiceSpec) 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) {
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
switch t := object.(type) {
@ -488,17 +470,6 @@ func (f *ring0Factory) CanBeExposed(kind schema.GroupKind) error {
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.
func InternalVersionDecoder() runtime.Decoder {
return legacyscheme.Codecs.UniversalDecoder()

View File

@ -28,37 +28,6 @@ import (
"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) {
f := NewFactory(genericclioptions.NewTestConfigFlags())

View File

@ -4,10 +4,12 @@ go_library(
name = "go_default_library",
srcs = [
"attachablepodforobject.go",
"canbeautoscaled.go",
"helpers.go",
"historyviewer.go",
"interface.go",
"logsforobject.go",
"portsforobject.go",
"statusviewer.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/labels: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/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
@ -47,6 +50,7 @@ go_test(
srcs = [
"helpers_test.go",
"logsforobject_test.go",
"portsforobject_test.go",
],
embed = [":go_default_library"],
deps = [
@ -63,6 +67,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/runtime: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/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch: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/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/rest"
api "k8s.io/kubernetes/pkg/apis/core"
"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
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)
}
}