Skip to content

Commit bf7e23e

Browse files
committed
UPSTREAM: <carry>: Apply shared defaulters to CRD-based routes.
1 parent 2f0a6b4 commit bf7e23e

File tree

7 files changed

+211
-0
lines changed

7 files changed

+211
-0
lines changed

openshift-kube-apiserver/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var AllCustomResourceValidators = []string{
4141
network.PluginName,
4242
apirequestcount.PluginName,
4343
node.PluginName,
44+
route.DefaultingPluginName,
4445
route.PluginName,
4546

4647
// the kubecontrollermanager operator resource has to exist in order to run deployments to deploy admission webhooks.
@@ -84,4 +85,5 @@ func RegisterCustomResourceValidation(plugins *admission.Plugins) {
8485
// served via CRD. Most OpenShift flavors (including vanilla) will continue to do validation
8586
// and defaulting inside openshift-apiserver.
8687
route.Register(plugins)
88+
route.RegisterDefaulting(plugins)
8789
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package route
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
8+
"k8s.io/apimachinery/pkg/runtime"
9+
"k8s.io/apimachinery/pkg/runtime/schema"
10+
"k8s.io/apiserver/pkg/admission"
11+
12+
v1 "github.com/openshift/api/route/v1"
13+
)
14+
15+
const (
16+
DefaultingPluginName = "route.openshift.io/DefaultRoute"
17+
)
18+
19+
func RegisterDefaulting(plugins *admission.Plugins) {
20+
plugins.Register(DefaultingPluginName, func(_ io.Reader) (admission.Interface, error) {
21+
return &defaultRoute{
22+
Handler: admission.NewHandler(admission.Create, admission.Update),
23+
}, nil
24+
})
25+
}
26+
27+
type defaultRoute struct {
28+
*admission.Handler
29+
}
30+
31+
var _ admission.MutationInterface = &defaultRoute{}
32+
33+
func (a *defaultRoute) Admit(ctx context.Context, attributes admission.Attributes, _ admission.ObjectInterfaces) error {
34+
if attributes.GetResource().GroupResource() != (schema.GroupResource{Group: "route.openshift.io", Resource: "routes"}) {
35+
return nil
36+
}
37+
38+
if len(attributes.GetSubresource()) > 0 {
39+
return nil
40+
}
41+
42+
u, ok := attributes.GetObject().(runtime.Unstructured)
43+
if !ok {
44+
// If a request to the resource routes.route.openshift.io is subject to
45+
// kube-apiserver admission, that should imply that the route API is being served as
46+
// CRs and the request body should have been unmarshaled into an unstructured
47+
// object.
48+
return fmt.Errorf("object being admitted is of type %T and does not implement runtime.Unstructured", attributes.GetObject())
49+
}
50+
51+
var external v1.Route
52+
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &external); err != nil {
53+
return err
54+
}
55+
56+
SetObjectDefaults_Route(&external)
57+
58+
content, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&external)
59+
if err != nil {
60+
return err
61+
}
62+
u.SetUnstructuredContent(content)
63+
64+
return nil
65+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package route
2+
3+
import (
4+
routev1 "github.com/openshift/api/route/v1"
5+
"github.com/openshift/library-go/pkg/route/defaulting"
6+
)
7+
8+
// Defaulters defined in github.com/openshift/library-go/pkg/route/defaulting are not recongized by
9+
// codegen (make update). This file MUST contain duplicates of each defaulter function defined in
10+
// library-go, with the body of each function defined here delegating to its library-go
11+
// counterpart. Missing or extra defaulters here will introduce differences between Route as a CRD
12+
// (MicroShift) and Route as an aggregated API of openshift-apiserver.
13+
14+
func SetDefaults_RouteSpec(obj *routev1.RouteSpec) {
15+
defaulting.SetDefaults_RouteSpec(obj)
16+
}
17+
18+
func SetDefaults_RouteTargetReference(obj *routev1.RouteTargetReference) {
19+
defaulting.SetDefaults_RouteTargetReference(obj)
20+
}
21+
22+
func SetDefaults_TLSConfig(obj *routev1.TLSConfig) {
23+
defaulting.SetDefaults_TLSConfig(obj)
24+
}
25+
26+
func SetDefaults_RouteIngress(obj *routev1.RouteIngress) {
27+
defaulting.SetDefaults_RouteIngress(obj)
28+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package route
2+
3+
import (
4+
"fmt"
5+
"go/ast"
6+
"go/parser"
7+
"go/token"
8+
"io/fs"
9+
"strings"
10+
"testing"
11+
12+
"k8s.io/apimachinery/pkg/util/sets"
13+
)
14+
15+
func TestDuplicatedDefaulters(t *testing.T) {
16+
expected, err := findDefaultersInPackage("../../../../vendor/github.com/openshift/library-go/pkg/route/defaulting")
17+
if err != nil {
18+
t.Fatalf("error finding expected manual defaulters: %v", err)
19+
}
20+
21+
actual, err := findDefaultersInPackage(".")
22+
if err != nil {
23+
t.Fatalf("error finding actual manual defaulters: %v", err)
24+
}
25+
26+
for _, missing := range expected.Difference(actual).List() {
27+
t.Errorf("missing local duplicate of library-go defaulter %q", missing)
28+
}
29+
30+
for _, extra := range actual.Difference(expected).List() {
31+
t.Errorf("found local defaulter %q without library-go counterpart", extra)
32+
}
33+
}
34+
35+
// findDefaultersInPackage parses the source of the Go package at the given path and returns the
36+
// names of all manual defaulter functions it declares. Package function declarations can't be
37+
// enumerated using reflection.
38+
func findDefaultersInPackage(path string) (sets.String, error) {
39+
pkgs, err := parser.ParseDir(token.NewFileSet(), path, func(fi fs.FileInfo) bool {
40+
return !strings.HasSuffix(fi.Name(), "_test.go")
41+
}, 0)
42+
if err != nil {
43+
return nil, fmt.Errorf("failed to parse source of package at %q: %v", path, err)
44+
}
45+
if len(pkgs) != 1 {
46+
return nil, fmt.Errorf("expected exactly 1 package for all sources in %q, got %d", path, len(pkgs))
47+
}
48+
49+
defaulters := sets.NewString()
50+
for _, pkg := range pkgs {
51+
ast.Inspect(pkg, func(node ast.Node) bool {
52+
switch typed := node.(type) {
53+
case *ast.Package, *ast.File:
54+
return true
55+
case *ast.FuncDecl:
56+
if typed.Recv == nil && strings.HasPrefix(typed.Name.Name, "SetDefaults_") {
57+
defaulters.Insert(typed.Name.Name)
58+
}
59+
return false
60+
default:
61+
return false
62+
}
63+
})
64+
}
65+
return defaulters, nil
66+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// +k8s:defaulter-gen=TypeMeta
2+
// +k8s:defaulter-gen-input=github.com/openshift/api/route/v1
3+
4+
package route

vendor/github.com/openshift/library-go/pkg/route/defaulting/defaults.go

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ github.com/openshift/library-go/pkg/network
917917
github.com/openshift/library-go/pkg/oauth/oauthdiscovery
918918
github.com/openshift/library-go/pkg/quota/clusterquotamapping
919919
github.com/openshift/library-go/pkg/quota/quotautil
920+
github.com/openshift/library-go/pkg/route/defaulting
920921
github.com/openshift/library-go/pkg/route/hostassignment
921922
github.com/openshift/library-go/pkg/route/validation
922923
github.com/openshift/library-go/pkg/security/ldaputil

0 commit comments

Comments
 (0)