Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion api/v1alpha1/authenticationfilter_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const (
KindAuthenticationFilter = "AuthenticationFilter"
)

//+kubebuilder:object:root=true
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

type AuthenticationFilter struct {
metav1.TypeMeta `json:",inline"`
Expand Down
31 changes: 31 additions & 0 deletions api/v1alpha1/envoypatchpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const (
)

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
Comment thread
arkodg marked this conversation as resolved.
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Programmed")].reason`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// EnvoyPatchPolicy allows the user to modify the generated Envoy xDS
// resources by Envoy Gateway using this patch API
Expand Down Expand Up @@ -122,6 +125,34 @@ type EnvoyPatchPolicyStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

const (
// PolicyConditionProgrammed indicates whether the policy has been translated
// and ready to be programmed into the data plane.
//
// Possible reasons for this condition to be True are:
//
// * "Programmed"
//
// Possible reasons for this condition to be False are:
//
// * "Invalid"
// * "ResourceNotFound"
//
PolicyConditionProgrammed gwapiv1a2.PolicyConditionType = "Programmed"

// PolicyReasonProgrammed is used with the "Programmed" condition when the policy
// is ready to be programmed into the data plane.
PolicyReasonProgrammed gwapiv1a2.PolicyConditionReason = "Programmed"

// PolicyReasonInvalid is used with the "Programmed" condition when the patch
// is syntactically or semantically invalid.
PolicyReasonInvalid gwapiv1a2.PolicyConditionReason = "Invalid"

// PolicyReasonTargetNotFound is used with the "Programmed" condition when the
// policy cannot find the resource type to patch to.
PolicyReasonResourceNotFound gwapiv1a2.PolicyConditionReason = "ResourceNotFound"
)

//+kubebuilder:object:root=true

// EnvoyPatchPolicyList contains a list of EnvoyPatchPolicy resources.
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/ratelimitfilter_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
)

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// RateLimitFilter allows the user to limit the number of incoming requests
// to a predefined value based on attributes within the traffic flow.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ spec:
singular: authenticationfilter
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
properties:
Expand Down Expand Up @@ -125,3 +129,4 @@ spec:
type: object
served: true
storage: true
subresources: {}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ spec:
singular: envoypatchpolicy
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .status.conditions[?(@.type=="Programmed")].reason
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: EnvoyPatchPolicy allows the user to modify the generated Envoy
Expand Down Expand Up @@ -221,3 +228,5 @@ spec:
type: object
served: true
storage: true
subresources:
status: {}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ spec:
singular: ratelimitfilter
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: RateLimitFilter allows the user to limit the number of incoming
Expand Down Expand Up @@ -177,3 +181,4 @@ spec:
type: object
served: true
storage: true
subresources: {}
7 changes: 7 additions & 0 deletions charts/gateway-helm/templates/generated/rbac/roles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ rules:
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- gateway.envoyproxy.io
resources:
- envoypatchpolicies/status
verbs:
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand Down
19 changes: 13 additions & 6 deletions internal/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,16 @@ func setupRunners(cfg *config.Server) error {
}

pResources := new(message.ProviderResources)
ePatchPolicyStatuses := new(message.EnvoyPatchPolicyStatuses)
// Start the Provider Service
// It fetches the resources from the configured provider type
// and publishes it
// It also subscribes to status resources and once it receives
// a status resource back, it writes it out.
providerRunner := providerrunner.New(&providerrunner.Config{
Server: *cfg,
ProviderResources: pResources,
Server: *cfg,
ProviderResources: pResources,
EnvoyPatchPolicyStatuses: ePatchPolicyStatuses,
})
if err := providerRunner.Start(ctx); err != nil {
return err
Expand All @@ -154,11 +158,13 @@ func setupRunners(cfg *config.Server) error {
xds := new(message.Xds)
// Start the Xds Translator Service
// It subscribes to the xdsIR, translates it into xds Resources and publishes it.
// It also computes the EnvoyPatchPolicy statuses and publishes it.
xdsTranslatorRunner := xdstranslatorrunner.New(&xdstranslatorrunner.Config{
Server: *cfg,
XdsIR: xdsIR,
Xds: xds,
ExtensionManager: extMgr,
Server: *cfg,
XdsIR: xdsIR,
Xds: xds,
ExtensionManager: extMgr,
EnvoyPatchPolicyStatuses: ePatchPolicyStatuses,
})
if err := xdsTranslatorRunner.Start(ctx); err != nil {
return err
Expand Down Expand Up @@ -206,6 +212,7 @@ func setupRunners(cfg *config.Server) error {
<-ctx.Done()
// Close messages
pResources.Close()
ePatchPolicyStatuses.Close()
xdsIR.Close()
infraIR.Close()
xds.Close()
Expand Down
82 changes: 72 additions & 10 deletions internal/gatewayapi/envoypatchpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
package gatewayapi

import (
"fmt"
"sort"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/status"
)

func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR XdsIRMap) {
Expand All @@ -21,16 +25,19 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
})

for _, policy := range envoyPatchPolicies {
// Ensure policy can only target a Gateway
if policy.Spec.TargetRef.Group != gwv1b1.GroupName || policy.Spec.TargetRef.Kind != KindGateway {
// TODO: Update Status
continue
}

// Ensure Policy and target Gateway are in the same namespace
targetNs := policy.Spec.TargetRef.Namespace
if targetNs == nil || policy.Namespace != string(*targetNs) {
// TODO: Update Status
if targetNs == nil {
// This status condition will not get updated in the resource because
// we dont have access to the IR yet, but it has been kept here in case we publish
// the status from this layer instead of the xds layer.

status.SetEnvoyPatchPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionFalse,
gwv1a2.PolicyReasonInvalid,
"TargetRef.Namespace must be set",
)
continue
}

Expand All @@ -39,7 +46,54 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
irKey := irStringKey(string(*targetNs), string(policy.Spec.TargetRef.Name))
gwXdsIR, ok := xdsIR[irKey]
if !ok {
// TODO: Update Status
// This status condition will not get updated in the resource because
// the IR is missing, but it has been kept here in case we publish
// the status from this layer instead of the xds layer.
message := fmt.Sprintf("Gateway:%s not found.", policy.Spec.TargetRef.Name)

status.SetEnvoyPatchPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionFalse,
gwv1a2.PolicyReasonTargetNotFound,
message,
)
continue
}

// Create the IR with the context need to publish the status later
policyIR := ir.EnvoyPatchPolicy{}
policyIR.Name = policy.Name
policyIR.Namespace = policy.Namespace
policyIR.Status = &policy.Status

// Append the IR
gwXdsIR.EnvoyPatchPolicies = append(gwXdsIR.EnvoyPatchPolicies, &policyIR)

// Ensure policy can only target a Gateway
if policy.Spec.TargetRef.Group != gwv1b1.GroupName || policy.Spec.TargetRef.Kind != KindGateway {
Comment thread
Alice-Lilith marked this conversation as resolved.
message := fmt.Sprintf("TargetRef.Group:%s TargetRef.Kind:%s, only TargetRef.Group:%s and TargetRef.Kind:%s is supported.",
policy.Spec.TargetRef.Group, policy.Spec.TargetRef.Kind, gwv1b1.GroupName, KindGateway)

status.SetEnvoyPatchPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionFalse,
gwv1a2.PolicyReasonInvalid,
message,
)
continue
}

// Ensure Policy and target Gateway are in the same namespace
if policy.Namespace != string(*targetNs) {
Comment thread
Alice-Lilith marked this conversation as resolved.
message := fmt.Sprintf("Namespace:%s TargetRef.Namespace:%s, EnvoyPatchPolicy can only target a Gateway in the same namespace.",
policy.Namespace, *targetNs)

status.SetEnvoyPatchPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionFalse,
gwv1a2.PolicyReasonInvalid,
message,
)
continue
}

Expand All @@ -52,7 +106,15 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
irPatch.Operation.Path = patch.Operation.Path
irPatch.Operation.Value = patch.Operation.Value

gwXdsIR.JSONPatches = append(gwXdsIR.JSONPatches, &irPatch)
policyIR.JSONPatches = append(policyIR.JSONPatches, &irPatch)
}

// Set Accepted=True
status.SetEnvoyPatchPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionTrue,
gwv1a2.PolicyReasonAccepted,
"EnvoyPatchPolicy has been accepted.",
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
envoyPatchPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
namespace: envoy-gateway-2
name: edit-conn-buffer-bytes
spec:
type: "JSONPatch"
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
name: "envoy-gateway-gateway-1-http"
operation:
op: replace
path: "/per_connection_buffer_limit_bytes"
value: "1024"
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
Loading