Skip to content

Host wildcard policy for supporting wildcard routes #11550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 2, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/swagger-spec/oapi-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -27540,6 +27540,10 @@
"$ref": "v1.RouteIngressCondition"
},
"description": "Conditions is the state of the route, may be empty."
},
"wildcardPolicy": {
"type": "string",
"description": "Wildcard policy is the wildcard policy that was allowed where this route is exposed."
}
}
},
Expand Down
4 changes: 4 additions & 0 deletions api/swagger-spec/openshift-openapi-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -51251,6 +51251,10 @@
"routerName": {
"description": "Name is a name chosen by the router to identify itself; this value is required",
"type": "string"
},
"wildcardPolicy": {
"description": "Wildcard policy is the wildcard policy that was allowed where this route is exposed.",
"type": "string"
}
}
},
Expand Down
14 changes: 9 additions & 5 deletions pkg/cmd/infra/router/f5.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,21 @@ func (o *F5RouterOptions) Validate() error {
// F5RouteAdmitterFunc returns a func that checks if a route is a
// wildcard route and currently denies it.
func (o *F5RouterOptions) F5RouteAdmitterFunc() controller.RouteAdmissionFunc {
return func(route *routeapi.Route) (error, bool) {
return func(route *routeapi.Route) error {
if err := o.AdmissionCheck(route); err != nil {
return err, false
return err
}

if len(route.Spec.WildcardPolicy) > 0 && route.Spec.WildcardPolicy != routeapi.WildcardPolicyNone {
switch route.Spec.WildcardPolicy {
case routeapi.WildcardPolicyNone:
return nil

case routeapi.WildcardPolicySubdomain:
// TODO: F5 wildcard route support.
return fmt.Errorf("Wildcard routes are currently not supported by the F5 router"), true
return fmt.Errorf("Wildcard routes are currently not supported by the F5 router")
}

return nil, false
return fmt.Errorf("unknown wildcard policy %v", route.Spec.WildcardPolicy)
}
}

Expand Down
17 changes: 12 additions & 5 deletions pkg/cmd/infra/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,23 @@ func (o *RouterSelection) AdmissionCheck(route *routeapi.Route) error {
// based on blacklist & whitelist checks and wildcard routes policy setting.
// Note: The blacklist settings trumps the whitelist ones.
func (o *RouterSelection) RouteAdmissionFunc() controller.RouteAdmissionFunc {
return func(route *routeapi.Route) (error, bool) {
return func(route *routeapi.Route) error {
if err := o.AdmissionCheck(route); err != nil {
return err, false
return err
}

if len(route.Spec.WildcardPolicy) > 0 && route.Spec.WildcardPolicy != routeapi.WildcardPolicyNone && !o.AllowWildcardRoutes {
return fmt.Errorf("wildcard routes are not allowed"), true
switch route.Spec.WildcardPolicy {
case routeapi.WildcardPolicyNone:
return nil

case routeapi.WildcardPolicySubdomain:
if o.AllowWildcardRoutes {
return nil
}
return fmt.Errorf("wildcard routes are not allowed")
}

return nil, true
return fmt.Errorf("unknown wildcard policy %v", route.Spec.WildcardPolicy)
}
}

Expand Down
12 changes: 3 additions & 9 deletions pkg/route/api/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,11 @@ func RouteLessThan(route1, route2 *Route) bool {
return true
}
Copy link
Contributor

@liggitt liggitt Oct 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simpler:

if route1.CreationTimestamp.Before(route2.CreationTimestamp) {
  return true
}
if route2.CreationTimestamp.Before(route1.CreationTimestamp) {
  return false
}
return route1.UID < route2.UID


if route1.CreationTimestamp == route2.CreationTimestamp {
if route1.UID < route2.UID {
return true
}
if route1.Namespace < route2.Namespace {
return true
}
return route1.Name < route2.Name
if route2.CreationTimestamp.Before(route1.CreationTimestamp) {
return false
}

return false
return route1.UID < route2.UID
}

// GetDomainForHost returns the domain for the specified host.
Expand Down
114 changes: 52 additions & 62 deletions pkg/route/api/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,85 +6,75 @@ import (

kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/types"
)

func TestRouteLessThan(t *testing.T) {
current := unversioned.Now()
older := unversioned.Time{Time: current.Add(-1 * time.Minute)}

r := Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: current.Rfc3339Copy(),
UID: "alpha",
Namespace: "alpha",
Name: "alpha",
},
olderTimestamp := unversioned.Now().Rfc3339Copy()
newerTimestamp := unversioned.Time{
Time: olderTimestamp.Add(1 * time.Minute),
}

tcs := []struct {
r Route
expected bool
testName string
timestamp1 unversioned.Time
timestamp2 unversioned.Time
uid1 types.UID
uid2 types.UID
expected bool
}{
{Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: unversioned.Time{
Time: r.CreationTimestamp.Add(time.Minute),
},
},
}, true},
{Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: r.CreationTimestamp,
UID: "beta",
},
}, true},
{Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: r.CreationTimestamp,
UID: r.UID,
Namespace: "beta",
},
}, true},
{Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: r.CreationTimestamp,
UID: r.UID,
Namespace: r.Namespace,
Name: "beta",
},
}, true},
{Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: older,
UID: r.UID,
Namespace: r.Namespace,
Name: "beta",
},
}, false},
{Route{
{
testName: "Older route less than newer route",
timestamp1: olderTimestamp,
timestamp2: newerTimestamp,
expected: true,
},
{
testName: "Newer route not less than older route",
timestamp1: newerTimestamp,
timestamp2: olderTimestamp,
expected: false,
},
{
testName: "Same age route less with smaller uid",
timestamp1: newerTimestamp,
timestamp2: newerTimestamp,
uid1: "alpha",
uid2: "beta",
expected: true,
},
{
testName: "Same age route not less with greater uid",
timestamp1: newerTimestamp,
timestamp2: newerTimestamp,
uid1: "beta",
uid2: "alpha",
expected: false,
},
}

for _, tc := range tcs {
r1 := &Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: older,
UID: r.UID,
Name: "gamma",
CreationTimestamp: tc.timestamp1,
UID: tc.uid1,
},
}, false},
{Route{
}
r2 := &Route{
ObjectMeta: kapi.ObjectMeta{
CreationTimestamp: older,
Name: "delta",
CreationTimestamp: tc.timestamp2,
UID: tc.uid2,
},
}, false},
{r, false},
}
}

for _, tc := range tcs {
if RouteLessThan(&r, &tc.r) != tc.expected {
if RouteLessThan(r1, r2) != tc.expected {
var msg string
if tc.expected {
msg = "Expected %v to be less than %v"
} else {
msg = "Expected %v to not be less than %v"
}
t.Errorf(msg, r, tc.r)
t.Errorf(msg, r1, r2)
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/route/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ type RouteIngress struct {
RouterName string
// Conditions is the state of the route, may be empty.
Conditions []RouteIngressCondition
// Wildcard policy is the wildcard policy that was allowed where this route is exposed.
WildcardPolicy WildcardPolicyType
}

// RouteIngressConditionType is a valid value for RouteCondition
Expand Down
9 changes: 9 additions & 0 deletions pkg/route/api/v1/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ func TestDefaults(t *testing.T) {
To: v1.RouteTargetReference{Name: "other"},
TLS: &v1.TLSConfig{},
},
Status: v1.RouteStatus{
Ingress: []v1.RouteIngress{{}},
},
}
out := &api.Route{}
if err := kapi.Scheme.Convert(obj, out, nil); err != nil {
Expand All @@ -54,7 +57,13 @@ func TestDefaults(t *testing.T) {
if out.Spec.TLS.Termination != api.TLSTerminationEdge {
t.Errorf("did not default termination: %#v", out)
}
if out.Spec.WildcardPolicy != api.WildcardPolicyNone {
t.Errorf("did not default wildcard policy: %#v", out)
}
if out.Spec.To.Kind != "Service" {
t.Errorf("did not default object reference kind: %#v", out)
}
if out.Status.Ingress[0].WildcardPolicy != api.WildcardPolicyNone {
t.Errorf("did not default status ingress wildcard policy: %#v", out)
}
}
13 changes: 7 additions & 6 deletions pkg/route/api/v1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import "k8s.io/kubernetes/pkg/runtime"

func SetDefaults_RouteSpec(obj *RouteSpec) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same defaulting of the wildcardpolicy in RouteIngress if we add the field there

if len(obj.WildcardPolicy) == 0 {
obj.WildcardPolicy = "None"
}
switch obj.WildcardPolicy {
case WildcardPolicyType("None"):
obj.WildcardPolicy = WildcardPolicyNone
case WildcardPolicyType("Subdomain"):
obj.WildcardPolicy = WildcardPolicySubdomain
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to do something on the case where something else is encountered? Log an error and default to None? Log and ignore the route (with appropriate status)? Or is that definitely impossible by some other mechanism I haven't spotted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know too much about this part - AFAICT, it was just setting defaults if no values were set on fields in an object. And there's no errors thrown back/logging here in similar defaults code. @liggitt may be able to tell more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not in conversion/defaulting, only in validation


Expand Down Expand Up @@ -38,10 +32,17 @@ func SetDefaults_TLSConfig(obj *TLSConfig) {
}
}

func SetDefaults_RouteIngress(obj *RouteIngress) {
if len(obj.WildcardPolicy) == 0 {
obj.WildcardPolicy = WildcardPolicyNone
}
}

func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs(
SetDefaults_RouteSpec,
SetDefaults_RouteTargetReference,
SetDefaults_TLSConfig,
SetDefaults_RouteIngress,
)
}
Loading