Remove service annotation for namedPorts

This commit is contained in:
Manuel de Brito Fontes 2017-05-22 22:55:39 -04:00
parent c5e30973e5
commit d98a052972
5 changed files with 3 additions and 398 deletions

View file

@ -45,7 +45,6 @@ import (
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/annotations/proxy"
"k8s.io/ingress/core/pkg/ingress/annotations/service"
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/resolver"
"k8s.io/ingress/core/pkg/ingress/status"
@ -1046,31 +1045,7 @@ func (ic *GenericController) getEndpoints(
// ExternalName services
if s.Spec.Type == api.ServiceTypeExternalName {
var targetPort int
switch servicePort.Type {
case intstr.Int:
targetPort = servicePort.IntValue()
case intstr.String:
port, err := service.GetPortMapping(servicePort.StrVal, s)
if err == nil {
targetPort = int(port)
break
}
glog.Warningf("error mapping service port: %v", err)
err = ic.checkSvcForUpdate(s)
if err != nil {
glog.Warningf("error mapping service ports: %v", err)
return upsServers
}
port, err = service.GetPortMapping(servicePort.StrVal, s)
if err == nil {
targetPort = int(port)
}
}
targetPort := servicePort.IntValue()
// check for invalid port value
if targetPort <= 0 {
return upsServers
@ -1106,22 +1081,8 @@ func (ic *GenericController) getEndpoints(
targetPort = epPort.Port
}
case intstr.String:
port, err := service.GetPortMapping(servicePort.StrVal, s)
if err == nil {
targetPort = port
break
}
glog.Warningf("error mapping service port: %v", err)
err = ic.checkSvcForUpdate(s)
if err != nil {
glog.Warningf("error mapping service ports: %v", err)
continue
}
port, err = service.GetPortMapping(servicePort.StrVal, s)
if err == nil {
targetPort = port
if epPort.Name == servicePort.StrVal {
targetPort = epPort.Port
}
}

View file

@ -17,94 +17,12 @@ limitations under the License.
package controller
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"github.com/golang/glog"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/annotations/service"
)
// checkSvcForUpdate verifies if one of the running pods for a service contains
// named port. If the annotation in the service does not exist or is not equals
// to the port mapping obtained from the pod the service must be updated to reflect
// the current state
func (ic *GenericController) checkSvcForUpdate(svc *api_v1.Service) error {
// get the pods associated with the service
// TODO: switch this to a watch
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(meta_v1.ListOptions{
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector().String(),
})
if err != nil {
return fmt.Errorf("error searching service pods %v/%v: %v", svc.Namespace, svc.Name, err)
}
if len(pods.Items) == 0 {
return nil
}
namedPorts := map[string]string{}
// we need to check only one pod searching for named ports
pod := &pods.Items[0]
glog.V(4).Infof("checking pod %v/%v for named port information", pod.Namespace, pod.Name)
for i := range svc.Spec.Ports {
servicePort := &svc.Spec.Ports[i]
_, err := strconv.Atoi(servicePort.TargetPort.StrVal)
if err != nil {
portNum, err := findPort(pod, servicePort)
if err != nil {
glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err)
continue
}
if servicePort.TargetPort.StrVal == "" {
continue
}
namedPorts[servicePort.TargetPort.StrVal] = fmt.Sprintf("%v", portNum)
}
}
if svc.ObjectMeta.Annotations == nil {
svc.ObjectMeta.Annotations = map[string]string{}
}
curNamedPort := svc.ObjectMeta.Annotations[service.NamedPortAnnotation]
if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) {
data, _ := json.Marshal(namedPorts)
newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name, meta_v1.GetOptions{})
if err != nil {
return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err)
}
if newSvc.ObjectMeta.Annotations == nil {
newSvc.ObjectMeta.Annotations = map[string]string{}
}
newSvc.ObjectMeta.Annotations[service.NamedPortAnnotation] = string(data)
glog.Infof("updating service %v with new named port mappings", svc.Name)
_, err = ic.cfg.Client.Core().Services(svc.Namespace).Update(newSvc)
if err != nil {
return fmt.Errorf("error syncing service %v/%v: %v", svc.Namespace, svc.Name, err)
}
return nil
}
return nil
}
// 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

View file

@ -17,15 +17,10 @@ limitations under the License.
package controller
import (
"reflect"
"testing"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/annotations/service"
)
func buildSimpleClientSet() *fake.Clientset {
@ -96,99 +91,3 @@ func buildService() *api_v1.Service {
},
}
}
func TestCheckSvcForUpdate(t *testing.T) {
foos := []struct {
n string
ns string
sps []api_v1.ServicePort
sl map[string]string
er string
}{
{
"pods_have_not_been_found_in_this_namespace",
api.NamespaceSystem,
[]api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"ports_have_not_been_found_in_this_pod",
api.NamespaceDefault,
[]api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")},
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"ports_fixed",
api.NamespaceDefault,
[]api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(80)},
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"nil_selector",
api.NamespaceDefault,
[]api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
},
nil,
"{\"foo1_named_port_c1\":\"80\"}",
},
{
"normal_update",
api.NamespaceDefault,
[]api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"{\"foo1_named_port_c1\":\"80\"}",
},
}
for _, foo := range foos {
t.Run(foo.n, func(t *testing.T) {
gc := buildGenericController()
s := buildService()
s.SetNamespace(foo.ns)
s.Spec.Ports = foo.sps
s.Spec.Selector = foo.sl
err := gc.checkSvcForUpdate(s)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service", meta_v1.GetOptions{})
rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation]
if !reflect.DeepEqual(rr, foo.er) {
t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n)
}
})
}
}