Skip to content

Commit

Permalink
internal: Allow status on HTTPRoutes to be set
Browse files Browse the repository at this point in the history
- Update the status package to process GatewayAPI HTTPRoutes.
- Update the dag.GatewayAPIProcessor to set status.

Fixes #3436

Signed-off-by: Steve Sloka <[email protected]>
  • Loading branch information
stevesloka committed Mar 8, 2021
1 parent af3ec8e commit 3c46077
Show file tree
Hide file tree
Showing 12 changed files with 769 additions and 76 deletions.
5 changes: 5 additions & 0 deletions internal/contour/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

func TestHTTPProxyMetrics(t *testing.T) {
Expand All @@ -43,6 +44,10 @@ func TestHTTPProxyMetrics(t *testing.T) {
Source: dag.KubernetesCache{
RootNamespaces: tc.rootNamespaces,
FieldLogger: fixture.NewTestLogger(t),
Gateway: types.NamespacedName{
Name: "contour",
Namespace: "projectcontour",
},
},
Processors: []dag.Processor{
&dag.IngressProcessor{
Expand Down
2 changes: 1 addition & 1 deletion internal/dag/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type Builder struct {
// configured DAG processors, in order.
func (b *Builder) Build() *DAG {
dag := DAG{
StatusCache: status.NewCache(),
StatusCache: status.NewCache(b.Source.Gateway),
}

for _, p := range b.Processors {
Expand Down
42 changes: 28 additions & 14 deletions internal/dag/gatewayapi_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
package dag

import (
"fmt"

"github.com/projectcontour/contour/internal/status"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -101,10 +104,12 @@ func selectorMatches(selector metav1.LabelSelector, objLabels map[string]string)
}

func (p *GatewayAPIProcessor) computeHTTPRoute(route *gatewayapi_v1alpha1.HTTPRoute) {
routeAccessor, commit := p.dag.StatusCache.HTTPRouteAccessor(route)
defer commit()

// Validate TLS Configuration
if route.Spec.TLS != nil {
p.Error("NOT IMPLEMENTED: The 'RouteTLSConfig' is not yet implemented.")
routeAccessor.ConditionFor(status.NotImplemented, "NotImplemented", "HTTPRoute.Spec.TLS: Not yet implemented.")
}

// Determine the hosts on the route, if no hosts
Expand All @@ -128,44 +133,44 @@ func (p *GatewayAPIProcessor) computeHTTPRoute(route *gatewayapi_v1alpha1.HTTPRo
case gatewayapi_v1alpha1.PathMatchPrefix:
pathPrefixes = append(pathPrefixes, stringOrDefault(match.Path.Value, "/"))
default:
p.Error("NOT IMPLEMENTED: Only PathMatchPrefix is currently implemented.")
routeAccessor.ConditionFor(status.Invalid, "PathMatchType", "HTTPRoute.Spec.Rules.PathMatch: Only Prefix match type is supported.")
}
}

if len(rule.ForwardTo) == 0 {
// TODO: Raise `ResolvedRefs` condition on Gateway with `DegradedRoutes` reason (#3455).
routeAccessor.ConditionFor(status.Invalid, "ForwardTo", "At least one Spec.Rules.ForwardTo must be specified.")
continue
}

// Validate the ForwardTos.
var forwardTos []gatewayapi_v1alpha1.HTTPRouteForwardTo
for _, forward := range rule.ForwardTo {
// Verify the service is valid
if forward.ServiceName == nil {
p.Error("ServiceName must be specified and is currently only type implemented!")
routeAccessor.ConditionFor(status.Invalid, "ForwardTo", "Spec.Rules.ForwardTo.ServiceName must be specified.")
continue
}

// TODO: Do not require port to be present (#3352).
if forward.Port == nil {
p.Error("ServicePort must be specified.")
routeAccessor.ConditionFor(status.Invalid, "ForwardTo", "Spec.Rules.ForwardTo.ServicePort must be specified.")
continue
}
forwardTos = append(forwardTos, forward)
}

// Process any valid forwardTo.
for _, forward := range forwardTos {

meta := types.NamespacedName{Name: *forward.ServiceName, Namespace: route.Namespace}

// TODO: Refactor EnsureService to take an int32 so conversion to intstr is not needed.
service, err := p.dag.EnsureService(meta, intstr.FromInt(int(*forward.Port)), p.source)
if err != nil {
// TODO: Raise `ResolvedRefs` condition on Gateway with `DegradedRoutes` reason.
p.Errorf("Service %q does not exist in namespace %q", meta.Name, meta.Namespace)
return
// TODO: Raise `ResolvedRefs` condition on Gateway with `DegradedRoutes` reason (#3455).
routeAccessor.ConditionFor(status.Invalid, "ForwardTo", fmt.Sprintf("Service %q does not exist in namespace %q", meta.Name, meta.Namespace))
continue
}
services = append(services, service)
}

if len(services) == 0 {
p.Errorf("Route %q rule invalid due to invalid forwardTo configuration.", route.Name)
routeAccessor.ConditionFor(status.Invalid, "ForwardTo", "All Spec.Rules.ForwardTos are invalid.")
continue
}

Expand All @@ -177,6 +182,15 @@ func (p *GatewayAPIProcessor) computeHTTPRoute(route *gatewayapi_v1alpha1.HTTPRo
}
}
}

// Determine if any errors exist in conditions and set the "Admitted"
// condition accordingly.
switch len(routeAccessor.Conditions) {
case 0:
routeAccessor.ConditionFor(status.AdmittedConditionValid, "Valid", "Valid HTTPRoute")
default:
routeAccessor.ConditionFor(status.AdmittedConditionInvalid, "ErrorsExist", "Errors Found, check other Conditions for details.")
}
}

// routes builds a []*dag.Route for the supplied set of pathPrefixes & services.
Expand Down
Loading

0 comments on commit 3c46077

Please sign in to comment.