Skip to content

Commit

Permalink
Merge branch 'main' into merge-gateways-e2e-test
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnh2 authored Mar 8, 2024
2 parents 8df3a0d + 07d3ec9 commit ef9baee
Show file tree
Hide file tree
Showing 411 changed files with 15,147 additions and 5,903 deletions.
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ updates:
k8s.io:
patterns:
- "k8s.io/*"
go.opentelemetry.io:
patterns:
- "go.opentelemetry.io/*"
- package-ecosystem: pip
directory: /tools/src/codespell
schedule:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build_and_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
- uses: ./tools/github-actions/setup-deps

- name: Download EG Binaries
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: envoy-gateway
path: bin/
Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
- uses: ./tools/github-actions/setup-deps

- name: Download EG Binaries
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: envoy-gateway
path: bin/
Expand All @@ -139,7 +139,7 @@ jobs:
- uses: ./tools/github-actions/setup-deps

- name: Download EG Binaries
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: envoy-gateway
path: bin/
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/cherrypick.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ permissions:
contents: read

jobs:
cherry_pick_release_v0_6:
cherry_pick_release_v1_0:
runs-on: ubuntu-22.04
name: Cherry pick into release-v0.6
if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v0.6') && github.event.pull_request.merged == true }}
name: Cherry pick into release-v1.0
if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v1.0') && github.event.pull_request.merged == true }}
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
- name: Cherry pick into release/v0.6
- name: Cherry pick into release/v1.0
uses: carloscastrojumo/github-cherry-pick-action@a145da1b8142e752d3cbc11aaaa46a535690f0c5 # v1.0.9
with:
branch: release/v0.6
title: "[release/v0.6] {old_title}"
body: "Cherry picking #{old_pull_request_id} onto release/v0.6"
branch: release/v1.0
title: "[release/v1.0] {old_title}"
body: "Cherry picking #{old_pull_request_id} onto release/v1.0"
labels: |
cherrypick/release-v0.6
cherrypick/release-v1.0
# put release manager here
reviewers: |
arkodg
Xunzhuo
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ jobs:
- uses: ./tools/github-actions/setup-deps

- name: Initialize CodeQL
uses: github/codeql-action/init@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
uses: github/codeql-action/init@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
with:
languages: ${{ matrix.language }}

- name: Autobuild
uses: github/codeql-action/autobuild@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
uses: github/codeql-action/autobuild@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
uses: github/codeql-action/analyze@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
with:
category: "/language:${{matrix.language}}"
6 changes: 6 additions & 0 deletions .github/workflows/latest_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ on:
paths-ignore:
- "**/*.png"

# Limit workflow run or job concurrency,
# avoid workflow failed when merge more than one PR in short time.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
latest-release:
runs-on: ubuntu-22.04
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ jobs:
retention-days: 5

- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
uses: github/codeql-action/upload-sarif@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
with:
sarif_file: results.sarif
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ vendor/

# values.yaml file is generated from its template counterpart.
charts/gateway-helm/values.yaml

# VIM
.*.swp
2 changes: 1 addition & 1 deletion OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ maintainers:
- zirain
- qicz
- zhaohuabing
- guydc

reviewers:

Expand All @@ -25,5 +26,4 @@ reviewers:
- tanujd11
- cnvergence
- shawnh2
- guydc
- liorokman
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.6.0
v1.0.0-rc.1
8 changes: 8 additions & 0 deletions api/v1alpha1/circuitbreaker_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ type CircuitBreaker struct {
// +optional
MaxParallelRequests *int64 `json:"maxParallelRequests,omitempty"`

// The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule.
//
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=4294967295
// +kubebuilder:default=1024
// +optional
MaxParallelRetries *int64 `json:"maxParallelRetries,omitempty"`

// The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
// Default: unlimited.
//
Expand Down
19 changes: 19 additions & 0 deletions api/v1alpha1/envoygateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,25 @@ type RateLimit struct {
// otherwise, don't let the traffic pass and return 500.
// If not set, FailClosed is False.
FailClosed bool `json:"failClosed"`

// Telemetry defines telemetry configuration for RateLimit.
// +optional
Telemetry *RateLimitTelemetry `json:"telemetry,omitempty"`
}

type RateLimitTelemetry struct {
// Metrics defines metrics configuration for RateLimit.
Metrics *RateLimitMetrics `json:"metrics,omitempty"`
}

type RateLimitMetrics struct {
// Prometheus defines the configuration for prometheus endpoint.
Prometheus *RateLimitMetricsPrometheusProvider `json:"prometheus,omitempty"`
}

type RateLimitMetricsPrometheusProvider struct {
// Disable the Prometheus endpoint.
Disable bool `json:"disable,omitempty"`
}

// RateLimitDatabaseBackend defines the configuration associated with
Expand Down
36 changes: 36 additions & 0 deletions api/v1alpha1/kubernetes_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,39 @@ func (deployment *KubernetesDeploymentSpec) ApplyMergePatch(old *appv1.Deploymen

return &patchedDeployment, nil
}

// ApplyMergePatch applies a merge patch to a service based on the merge type
func (service *KubernetesServiceSpec) ApplyMergePatch(old *corev1.Service) (*corev1.Service, error) {
if service.Patch == nil {
return old, nil
}

var patchedJSON []byte
var err error

// Serialize the current deployment to JSON
originalJSON, err := json.Marshal(old)
if err != nil {
return nil, fmt.Errorf("error marshaling original deployment: %w", err)
}

switch {
case service.Patch.Type == nil || *service.Patch.Type == StrategicMerge:
patchedJSON, err = strategicpatch.StrategicMergePatch(originalJSON, service.Patch.Value.Raw, corev1.Service{})
case *service.Patch.Type == JSONMerge:
patchedJSON, err = jsonpatch.MergePatch(originalJSON, service.Patch.Value.Raw)
default:
return nil, fmt.Errorf("unsupported merge type: %s", *service.Patch.Type)
}
if err != nil {
return nil, fmt.Errorf("error applying merge patch: %w", err)
}

// Deserialize the patched JSON into a new service object
var patchedService corev1.Service
if err := json.Unmarshal(patchedJSON, &patchedService); err != nil {
return nil, fmt.Errorf("error unmarshaling patched service: %w", err)
}

return &patchedService, nil
}
4 changes: 2 additions & 2 deletions api/v1alpha1/retry_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type RetryOn struct {
}

// TriggerEnum specifies the conditions that trigger retries.
// +kubebuilder:validation:Enum={"5xx","gateway-error","disconnect-reset","connect-failure","retriable-4xx","refused-stream","retriable-status-codes","cancelled","deadline-exceeded","internal","resource-exhausted","unavailable"}
// +kubebuilder:validation:Enum={"5xx","gateway-error","reset","connect-failure","retriable-4xx","refused-stream","retriable-status-codes","cancelled","deadline-exceeded","internal","resource-exhausted","unavailable"}
type TriggerEnum string

const (
Expand All @@ -57,7 +57,7 @@ const (
// The response is a gateway error (502,503 or 504).
GatewayError TriggerEnum = "gateway-error"
// The upstream server does not respond at all (disconnect/reset/read timeout.)
DisconnectRest TriggerEnum = "disconnect-reset"
Reset TriggerEnum = "reset"
// Connection failure to the upstream server (connect timeout, etc.). (Included in *5xx*)
ConnectFailure TriggerEnum = "connect-failure"
// The upstream server responds with a retriable 4xx response code.
Expand Down
9 changes: 5 additions & 4 deletions api/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ type KubernetesPodSpec struct {
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty"`

// HostNetwork, If this is set to true, the pod will use host's network namespace.
// +optional
HostNetwork bool `json:"hostNetwork,omitempty"`

// ImagePullSecrets is an optional list of references to secrets
// in the same namespace to use for pulling any of the images used by this PodSpec.
// If specified, these secrets will be passed to individual puller implementations for them to use.
Expand Down Expand Up @@ -268,6 +264,11 @@ type KubernetesServiceSpec struct {
// +kubebuilder:default:="Local"
// +optional
ExternalTrafficPolicy *ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty"`

// Patch defines how to perform the patch operation to the service
//
// +optional
Patch *KubernetesPatchSpec `json:"patch,omitempty"`
// TODO: Expose config as use cases are better understood, e.g. labels.
}

Expand Down
47 changes: 22 additions & 25 deletions api/v1alpha1/validation/envoyproxy_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import (
"errors"
"fmt"
"net/netip"
"reflect"

bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/testing/protocmp"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/yaml"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/utils/proto"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
_ "github.com/envoyproxy/gateway/internal/xds/extensions" // register the generated types to support protojson unmarshalling
)
Expand Down Expand Up @@ -126,47 +124,47 @@ func validateService(spec *egv1a1.EnvoyProxySpec) []error {
errs = append(errs, fmt.Errorf("loadBalancerIP:%s is an invalid IPv4 address", *serviceLoadBalancerIP))
}
}
if patch := spec.Provider.Kubernetes.EnvoyService.Patch; patch != nil {
if patch.Value.Raw == nil {
errs = append(errs, fmt.Errorf("envoy service patch object cannot be empty"))
}
if patch.Type != nil && *patch.Type != egv1a1.JSONMerge && *patch.Type != egv1a1.StrategicMerge {
errs = append(errs, fmt.Errorf("unsupported envoy service patch type %s", *patch.Type))
}
}

}
return errs
}

func validateBootstrap(boostrapConfig *egv1a1.ProxyBootstrap) error {
// Validate user bootstrap config
defaultBootstrap := &bootstrapv3.Bootstrap{}
// TODO: need validate when enable prometheus?
defaultBootstrapStr, err := bootstrap.GetRenderedBootstrapConfig(nil)
if err != nil {
return err
}
if err := proto.FromYAML([]byte(defaultBootstrapStr), defaultBootstrap); err != nil {
return fmt.Errorf("unable to unmarshal default bootstrap: %w", err)
}
if err := defaultBootstrap.Validate(); err != nil {
return fmt.Errorf("default bootstrap validation failed: %w", err)
}

// Validate user bootstrap config
userBootstrapStr, err := bootstrap.ApplyBootstrapConfig(boostrapConfig, defaultBootstrapStr)
if err != nil {
return err
}

jsonData, err := yaml.YAMLToJSON([]byte(userBootstrapStr))
if err != nil {
return fmt.Errorf("unable to convert user bootstrap to json: %w", err)
}

userBootstrap := &bootstrapv3.Bootstrap{}
if err := protojson.Unmarshal(jsonData, userBootstrap); err != nil {
return fmt.Errorf("unable to unmarshal user bootstrap: %w", err)
if err := proto.FromYAML([]byte(userBootstrapStr), userBootstrap); err != nil {
return fmt.Errorf("failed to parse default bootstrap config: %w", err)
}

// Call Validate method
if err := userBootstrap.Validate(); err != nil {
return fmt.Errorf("validation failed for user bootstrap: %w", err)
}

jsonData, err = yaml.YAMLToJSON([]byte(defaultBootstrapStr))
if err != nil {
return fmt.Errorf("unable to convert default bootstrap to json: %w", err)
}

if err := protojson.Unmarshal(jsonData, defaultBootstrap); err != nil {
return fmt.Errorf("unable to unmarshal default bootstrap: %w", err)
}

// Ensure dynamic resources config is same
if userBootstrap.DynamicResources == nil ||
cmp.Diff(userBootstrap.DynamicResources, defaultBootstrap.DynamicResources, protocmp.Transform()) != "" {
Expand All @@ -187,9 +185,8 @@ func validateBootstrap(boostrapConfig *egv1a1.ProxyBootstrap) error {
break
}
}

// nolint // Circumvents this error "Error: copylocks: call of reflect.DeepEqual copies lock value:"
if userXdsCluster == nil || !reflect.DeepEqual(*userXdsCluster.LoadAssignment, *defaultXdsCluster.LoadAssignment) {
if userXdsCluster == nil ||
cmp.Diff(userXdsCluster.LoadAssignment, defaultXdsCluster.LoadAssignment, protocmp.Transform()) != "" {
return fmt.Errorf("xds_cluster's loadAssigntment cannot be modified")
}

Expand Down
25 changes: 24 additions & 1 deletion api/v1alpha1/validation/envoyproxy_validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,30 @@ func TestValidateEnvoyProxy(t *testing.T) {
},
expected: true,
}, {
name: "should invalid when patch type is empty",
name: "should be invalid when service patch type is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyService: &egv1a1.KubernetesServiceSpec{
Patch: &egv1a1.KubernetesPatchSpec{
Value: v1.JSON{
Raw: []byte{},
},
},
},
},
},
},
},
expected: true,
}, {
name: "should be invalid when deployment patch type is empty",
proxy: &egv1a1.EnvoyProxy{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Expand Down
Loading

0 comments on commit ef9baee

Please sign in to comment.