Skip to content

Commit 8f4414b

Browse files
remove apiserver dependency in resourceinterpreter
Signed-off-by: changzhen <[email protected]>
1 parent c9ca6ac commit 8f4414b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+217
-9287
lines changed

Diff for: pkg/resourceinterpreter/customized/webhook/customized.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
webhookutil "k8s.io/apiserver/pkg/util/webhook"
3232
corev1 "k8s.io/client-go/listers/core/v1"
3333
"k8s.io/klog/v2"
34-
"k8s.io/kube-aggregator/pkg/apiserver"
3534
utiltrace "k8s.io/utils/trace"
3635

3736
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
@@ -70,7 +69,7 @@ func NewCustomizedInterpreter(informer genericmanager.SingleClusterInformerManag
7069
}
7170

7271
cm.SetAuthenticationInfoResolver(authInfoResolver)
73-
cm.SetServiceResolver(apiserver.NewClusterIPServiceResolver(serviceLister))
72+
cm.SetServiceResolver(NewServiceResolver(serviceLister))
7473

7574
return &CustomizedInterpreter{
7675
hookManager: configmanager.NewExploreConfigManager(informer),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package webhook
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"net/url"
7+
8+
corev1 "k8s.io/api/core/v1"
9+
apierrors "k8s.io/apimachinery/pkg/api/errors"
10+
webhookutil "k8s.io/apiserver/pkg/util/webhook"
11+
corev1lister "k8s.io/client-go/listers/core/v1"
12+
)
13+
14+
// ServiceResolver knows how to convert a service reference into an actual location.
15+
type ServiceResolver interface {
16+
ResolveEndpoint(namespace, name string, port int32) (*url.URL, error)
17+
}
18+
19+
// NewServiceResolver returns a ServiceResolver that parses service first,
20+
// if service not exist, constructs a service URL from a given namespace and name.
21+
func NewServiceResolver(services corev1lister.ServiceLister) ServiceResolver {
22+
return &serviceResolver{
23+
services: services,
24+
defaultResolver: webhookutil.NewDefaultServiceResolver(),
25+
}
26+
}
27+
28+
type serviceResolver struct {
29+
services corev1lister.ServiceLister
30+
defaultResolver ServiceResolver
31+
}
32+
33+
func (r *serviceResolver) ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) {
34+
svc, err := r.services.Services(namespace).Get(name)
35+
if err != nil {
36+
if apierrors.IsNotFound(err) {
37+
return r.defaultResolver.ResolveEndpoint(namespace, name, port)
38+
}
39+
return nil, err
40+
}
41+
return resolveCluster(svc, port)
42+
}
43+
44+
// resolveCluster parses Service resource to url.
45+
func resolveCluster(svc *corev1.Service, port int32) (*url.URL, error) {
46+
switch {
47+
case svc.Spec.Type == corev1.ServiceTypeClusterIP && svc.Spec.ClusterIP == corev1.ClusterIPNone:
48+
return nil, fmt.Errorf(`cannot route to service with ClusterIP "None"`)
49+
// use IP from a clusterIP for these service types
50+
case svc.Spec.Type == corev1.ServiceTypeClusterIP, svc.Spec.Type == corev1.ServiceTypeLoadBalancer, svc.Spec.Type == corev1.ServiceTypeNodePort:
51+
svcPort, err := findServicePort(svc, port)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return &url.URL{
56+
Scheme: "https",
57+
Host: net.JoinHostPort(svc.Spec.ClusterIP, fmt.Sprintf("%d", svcPort.Port)),
58+
}, nil
59+
case svc.Spec.Type == corev1.ServiceTypeExternalName:
60+
return &url.URL{
61+
Scheme: "https",
62+
Host: net.JoinHostPort(svc.Spec.ExternalName, fmt.Sprintf("%d", port)),
63+
}, nil
64+
default:
65+
return nil, fmt.Errorf("unsupported service type %q", svc.Spec.Type)
66+
}
67+
}
68+
69+
// findServicePort finds the service port by name or numerically.
70+
func findServicePort(svc *corev1.Service, port int32) (*corev1.ServicePort, error) {
71+
for _, svcPort := range svc.Spec.Ports {
72+
if svcPort.Port == port {
73+
return &svcPort, nil
74+
}
75+
}
76+
return nil, apierrors.NewServiceUnavailable(fmt.Sprintf("no service port %d found for service %q", port, svc.Name))
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package webhook
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
corev1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/util/intstr"
11+
)
12+
13+
func Test_resolveCluster(t *testing.T) {
14+
type args struct {
15+
svc *corev1.Service
16+
port int32
17+
}
18+
tests := []struct {
19+
name string
20+
args args
21+
want string
22+
wantErr assert.ErrorAssertionFunc
23+
}{
24+
{
25+
name: "cluster ip without 443 port",
26+
args: args{
27+
svc: &corev1.Service{
28+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
29+
Spec: corev1.ServiceSpec{
30+
Type: corev1.ServiceTypeClusterIP,
31+
ClusterIP: "hit",
32+
Ports: []corev1.ServicePort{
33+
{Port: 1234, TargetPort: intstr.FromInt32(1234)},
34+
}}},
35+
port: 443,
36+
},
37+
wantErr: assert.Error,
38+
},
39+
{
40+
name: "cluster ip",
41+
args: args{
42+
svc: &corev1.Service{
43+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
44+
Spec: corev1.ServiceSpec{
45+
Type: corev1.ServiceTypeClusterIP,
46+
ClusterIP: "hit",
47+
Ports: []corev1.ServicePort{
48+
{Name: "https", Port: 443, TargetPort: intstr.FromInt32(1443)},
49+
{Port: 1234, TargetPort: intstr.FromInt32(1234)},
50+
}}},
51+
port: 443,
52+
},
53+
want: "https://hit:443",
54+
wantErr: assert.NoError,
55+
},
56+
{
57+
name: "none cluster ip",
58+
args: args{
59+
svc: &corev1.Service{
60+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
61+
Spec: corev1.ServiceSpec{
62+
Type: corev1.ServiceTypeClusterIP,
63+
ClusterIP: corev1.ClusterIPNone,
64+
}},
65+
port: 443,
66+
},
67+
wantErr: assert.Error,
68+
},
69+
{
70+
name: "loadbalancer",
71+
args: args{
72+
svc: &corev1.Service{
73+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
74+
Spec: corev1.ServiceSpec{
75+
Type: corev1.ServiceTypeLoadBalancer,
76+
ClusterIP: "lb",
77+
Ports: []corev1.ServicePort{
78+
{Name: "https", Port: 443, TargetPort: intstr.FromInt32(1443)},
79+
{Port: 1234, TargetPort: intstr.FromInt32(1234)},
80+
}}},
81+
port: 443,
82+
},
83+
want: "https://lb:443",
84+
wantErr: assert.NoError,
85+
},
86+
{
87+
name: "node port",
88+
args: args{
89+
svc: &corev1.Service{
90+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
91+
Spec: corev1.ServiceSpec{
92+
Type: corev1.ServiceTypeLoadBalancer,
93+
ClusterIP: "np",
94+
Ports: []corev1.ServicePort{
95+
{Name: "https", Port: 443, TargetPort: intstr.FromInt32(1443)},
96+
{Port: 1234, TargetPort: intstr.FromInt32(1234)},
97+
}}},
98+
port: 443,
99+
},
100+
want: "https://np:443",
101+
wantErr: assert.NoError,
102+
},
103+
{
104+
name: "external name",
105+
args: args{
106+
svc: &corev1.Service{
107+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
108+
Spec: corev1.ServiceSpec{
109+
Type: corev1.ServiceTypeExternalName,
110+
ExternalName: "foo.bar.com",
111+
}},
112+
port: 443,
113+
},
114+
want: "https://foo.bar.com:443",
115+
wantErr: assert.NoError,
116+
},
117+
{
118+
name: "unsupported service",
119+
args: args{
120+
svc: &corev1.Service{
121+
ObjectMeta: metav1.ObjectMeta{Namespace: "one", Name: "alfa"},
122+
Spec: corev1.ServiceSpec{
123+
Type: "unsupported service",
124+
}},
125+
port: 443,
126+
},
127+
wantErr: assert.Error,
128+
},
129+
}
130+
for _, tt := range tests {
131+
t.Run(tt.name, func(t *testing.T) {
132+
got, err := resolveCluster(tt.args.svc, tt.args.port)
133+
if !tt.wantErr(t, err, fmt.Sprintf("resolveCluster(%v, %v)", tt.args.svc, tt.args.port)) {
134+
return
135+
}
136+
assert.Equalf(t, tt.want, got.String(), "resolveCluster(%v, %v)", tt.args.svc, tt.args.port)
137+
})
138+
}
139+
}

Diff for: vendor/k8s.io/apimachinery/pkg/api/meta/table/table.go

-70
This file was deleted.

0 commit comments

Comments
 (0)