callouts/go/extproc/pkg/utils/callout_tools.go (85 lines of code) (raw):

// Copyright 2024 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package utils import ( "fmt" base "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" extproc "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" httpstatus "github.com/envoyproxy/go-control-plane/envoy/type/v3" structpb "google.golang.org/protobuf/types/known/structpb" "github.com/golang/protobuf/proto" ) const DYNAMIC_FORWARDING_METADATA_NAMESPACE string = "com.google.envoy.dynamic_forwarding.selected_endpoints" // HeaderImmediateResponse creates an ImmediateResponse with the given status code, headers to add, and headers to remove. // The headers can be appended if appendAction is provided. func HeaderImmediateResponse(code httpstatus.StatusCode, addHeaders []struct{ Key, Value string }, removeHeaders []string, appendAction *base.HeaderValueOption_HeaderAppendAction) *extproc.ImmediateResponse { headerMutation := AddHeaderMutation(addHeaders, removeHeaders, false, appendAction) return &extproc.ImmediateResponse{ Status: &httpstatus.HttpStatus{ Code: code, }, Headers: proto.Clone(headerMutation.Response.HeaderMutation).(*extproc.HeaderMutation), } } // AddHeaderMutation creates a HeadersResponse with the given headers to add and remove. // It also allows clearing the route cache and setting an append action for the headers. func AddHeaderMutation(add []struct{ Key, Value string }, remove []string, clearRouteCache bool, appendAction *base.HeaderValueOption_HeaderAppendAction) *extproc.HeadersResponse { headerMutation := &extproc.HeaderMutation{} if add != nil { for _, kv := range add { headerValueOption := &base.HeaderValueOption{ Header: &base.HeaderValue{ Key: kv.Key, RawValue: []byte(kv.Value), }, } if appendAction != nil { headerValueOption.AppendAction = *appendAction } headerMutation.SetHeaders = append(headerMutation.SetHeaders, headerValueOption) } } if remove != nil { headerMutation.RemoveHeaders = append(headerMutation.RemoveHeaders, remove...) } headersResponse := &extproc.HeadersResponse{ Response: &extproc.CommonResponse{ HeaderMutation: headerMutation, ClearRouteCache: clearRouteCache, }, } if clearRouteCache { headersResponse.Response.ClearRouteCache = true } return headersResponse } // AddBodyStringMutation creates a BodyResponse with the given body content. // It allows clearing the route cache. func AddBodyStringMutation(body string, clearRouteCache bool) *extproc.BodyResponse { bodyMutation := &extproc.BodyMutation{ Mutation: &extproc.BodyMutation_Body{ Body: []byte(body), }, } bodyResponse := &extproc.BodyResponse{ Response: &extproc.CommonResponse{ BodyMutation: bodyMutation, ClearRouteCache: clearRouteCache, }, } return bodyResponse } // AddBodyClearMutation creates a BodyResponse that clears the body. // It allows clearing the route cache. func AddBodyClearMutation(clearRouteCache bool) *extproc.BodyResponse { bodyMutation := &extproc.BodyMutation{ Mutation: &extproc.BodyMutation_ClearBody{ ClearBody: true, }, } bodyResponse := &extproc.BodyResponse{ Response: &extproc.CommonResponse{ BodyMutation: bodyMutation, ClearRouteCache: clearRouteCache, }, } return bodyResponse } // AddDynamicForwardingMetadata creates a Struct with expected Dynamic Forwarding // key and format with provided ip and port. func AddDynamicForwardingMetadata(ipAddress string, portNumber int) (*structpb.Struct, error) { formatedEndpoint := fmt.Sprintf("%s:%d", ipAddress, portNumber) return structpb.NewStruct(map[string]any{ DYNAMIC_FORWARDING_METADATA_NAMESPACE: map[string]any{ "primary": formatedEndpoint, }, }) }