Skip to content

Commit

Permalink
Adds Wildcard Admission Policy
Browse files Browse the repository at this point in the history
  • Loading branch information
danehans committed Apr 2, 2020
1 parent 963eb01 commit e6fcaba
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 2 deletions.
20 changes: 18 additions & 2 deletions pkg/operator/controller/ingress/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import (
configv1 "github.com/openshift/api/config/v1"
)

const (
WildcardRouteAdmissionPolicy = "ROUTER_ALLOW_WILDCARD_ROUTES"
)

// ensureRouterDeployment ensures the router deployment exists for a given
// ingresscontroller.
func (r *reconciler) ensureRouterDeployment(ci *operatorv1.IngressController, infraConfig *configv1.Infrastructure, ingressConfig *configv1.Ingress, apiConfig *configv1.APIServer, networkConfig *configv1.Network) (*appsv1.Deployment, error) {
Expand Down Expand Up @@ -435,16 +439,28 @@ func desiredRouterDeployment(ci *operatorv1.IngressController, ingressController

routeAdmission := operatorv1.RouteAdmissionPolicy{
NamespaceOwnership: operatorv1.StrictNamespaceOwnershipCheck,
WildcardPolicy: operatorv1.WildcardPolicyDisallowed,
}
if admission := ci.Spec.RouteAdmission; admission != nil && len(admission.NamespaceOwnership) > 0 {
routeAdmission.NamespaceOwnership = ci.Spec.RouteAdmission.NamespaceOwnership
if admission := ci.Spec.RouteAdmission; admission != nil {
if len(admission.NamespaceOwnership) > 0 {
routeAdmission.NamespaceOwnership = admission.NamespaceOwnership
}
if len(admission.WildcardPolicy) > 0 {
routeAdmission.WildcardPolicy = admission.WildcardPolicy
}
}
switch routeAdmission.NamespaceOwnership {
case operatorv1.StrictNamespaceOwnershipCheck:
env = append(env, corev1.EnvVar{Name: "ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK", Value: "false"})
case operatorv1.InterNamespaceAllowedOwnershipCheck:
env = append(env, corev1.EnvVar{Name: "ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK", Value: "true"})
}
switch routeAdmission.WildcardPolicy {
case operatorv1.WildcardPolicyAllowed:
env = append(env, corev1.EnvVar{Name: WildcardRouteAdmissionPolicy, Value: "true"})
default:
env = append(env, corev1.EnvVar{Name: WildcardRouteAdmissionPolicy, Value: "false"})
}

deployment.Spec.Template.Spec.Volumes = volumes
deployment.Spec.Template.Spec.Containers[0].VolumeMounts = routerVolumeMounts
Expand Down
31 changes: 31 additions & 0 deletions pkg/operator/controller/ingress/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,20 @@ func TestDesiredRouterDeployment(t *testing.T) {
t.Errorf("router Deployment has wrong hash; expected: %s, got: %s", expectedHash, actualHash)
}

var wildcardPolicy string
for _, envVar := range deployment.Spec.Template.Spec.Containers[0].Env {
if envVar.Name == WildcardRouteAdmissionPolicy {
wildcardPolicy = envVar.Value
break
}
}
if wildcardPolicy == "" {
t.Error("router Deployment has no wildcard admission policy environment variable")
} else if wildcardPolicy != "false" {
t.Errorf("router Deployment has unexpected wildcard admission policy value: %v",
wildcardPolicy)
}

namespaceSelector := ""
for _, envVar := range deployment.Spec.Template.Spec.Containers[0].Env {
if envVar.Name == "NAMESPACE_LABELS" {
Expand Down Expand Up @@ -685,6 +699,19 @@ func TestDeploymentConfigChanged(t *testing.T) {
},
expect: true,
},
{
description: "if ROUTER_ALLOW_WILDCARD_ROUTES changes",
mutate: func(deployment *appsv1.Deployment) {
envs := deployment.Spec.Template.Spec.Containers[0].Env
for i, env := range envs {
if env.Name == WildcardRouteAdmissionPolicy {
envs[i].Value = "true"
}
}
deployment.Spec.Template.Spec.Containers[0].Env = envs
},
expect: true,
},
{
description: "if NAMESPACE_LABELS is added",
mutate: func(deployment *appsv1.Deployment) {
Expand Down Expand Up @@ -827,6 +854,10 @@ func TestDeploymentConfigChanged(t *testing.T) {
Name: "ROUTER_USE_PROXY_PROTOCOL",
Value: "false",
},
{
Name: "ROUTER_ALLOW_WILDCARD_ROUTES",
Value: "false",
},
{
Name: "ROUTE_LABELS",
Value: "foo=bar",
Expand Down
56 changes: 56 additions & 0 deletions test/e2e/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,62 @@ func TestRouteAdmissionPolicy(t *testing.T) {
if err := waitForRouteIngressConditions(kclient, route2Name, ic.Name, admittedCondition); err != nil {
t.Fatalf("failed to observe expected conditions: %v", err)
}

// Test the ingress controller wildcard admission policy. An ingress controller with
// a nil wildcard policy defaults to WildcardsDisallowed and the default wildcard
// policy of a route is None. Therefore, the tests above cover defaulting behavior.
// Create a route that explicitly sets the wildcard policy to None.
route3Name := types.NamespacedName{Namespace: ns2.Name, Name: "route3"}
route3 := makeRoute(route3Name, "route3.test.example.com", "/bar")
route3.Spec.WildcardPolicy = routev1.WildcardPolicyNone

// The route should be admitted because the default ingresscontroller wildcard
// policy is WildcardsDisallowed.
if err := kclient.Create(context.TODO(), route3); err != nil {
t.Fatalf("failed to create route: %v", err)
}
if err := waitForRouteIngressConditions(kclient, route3Name, ic.Name, admittedCondition); err != nil {
t.Fatalf("failed to observe expected conditions: %v, status: %v", err, route3)
}

// Create a route with a wildcard policy of Subdomain.
route4Name := types.NamespacedName{Namespace: ns2.Name, Name: "route4"}
route4 := makeRoute(route4Name, "route4.test.example.com", "/bar")
route4.Spec.WildcardPolicy = routev1.WildcardPolicySubdomain

// The route should not be admitted because the ingresscontroller wildcard policy
// is WildcardsDisallowed by default.
if err := kclient.Create(context.TODO(), route4); err != nil {
t.Fatalf("failed to create route: %v", err)
}
if err := waitForRouteIngressConditions(kclient, route4Name, ic.Name, rejectedCondition); err != nil {
t.Fatalf("failed to observe expected conditions: %v", err)
}

// Update the ingresscontroller wildcard policy to WildcardsAllowed.
if err := kclient.Get(context.TODO(), icName, ic); err != nil {
t.Fatalf("failed to get ingresscontroller: %v", ic)
}
ic.Spec.RouteAdmission.WildcardPolicy = operatorv1.WildcardPolicyAllowed
if err := kclient.Update(context.TODO(), ic); err != nil {
t.Fatalf("failed to update ingresscontroller: %v", err)
}

// Recreate the route since the failed route will not automatically get
// readmitted and a route wildcard policy is immutable.
if err := kclient.Delete(context.TODO(), route4); err != nil {
t.Fatalf("failed to delete route: %v", err)
}
route4 = makeRoute(route4Name, "route4.test.example.com", "/bar")
if err := kclient.Create(context.TODO(), route4); err != nil {
t.Fatalf("failed to create route: %v", err)
}
route4.Spec.WildcardPolicy = routev1.WildcardPolicySubdomain

// The route should now be admitted.
if err := waitForRouteIngressConditions(kclient, route4Name, ic.Name, admittedCondition); err != nil {
t.Fatalf("failed to observe expected conditions: %v", err)
}
}

func newLoadBalancerController(name types.NamespacedName, domain string) *operatorv1.IngressController {
Expand Down

0 comments on commit e6fcaba

Please sign in to comment.